ENPICOM Logo API Docs Python SDK Docs Events

enpi_api.l2.client.api.sequence_annotation_api

  1from uuid import UUID
  2
  3from loguru import logger
  4
  5from enpi_api.l1 import openapi_client
  6from enpi_api.l2.client.api.collection_api import CollectionApi
  7from enpi_api.l2.events.workflow_execution_task_waitable import WorkflowExecutionTaskWaitable
  8from enpi_api.l2.types.api_error import ApiError, ApiErrorContext
  9from enpi_api.l2.types.collection import CollectionId, CollectionMetadata
 10from enpi_api.l2.types.execution import Execution
 11from enpi_api.l2.types.file import FileId
 12from enpi_api.l2.types.log import LogLevel
 13from enpi_api.l2.types.reference_database import ReferenceDatabaseRevision
 14from enpi_api.l2.types.sequence_annotation import (
 15    CloneIdentifierExtractionConfig,
 16    CorrectionSettings,
 17    LiabilityType,
 18    MutationAssaySettings,
 19    QualityControlTemplate,
 20    SequenceTemplate,
 21    SequenceTemplateConfig,
 22)
 23from enpi_api.l2.types.tag import TagId
 24from enpi_api.l2.types.task import TaskState
 25from enpi_api.l2.types.workflow import WorkflowExecutionId, WorkflowExecutionTaskId, WorkflowTaskTemplateName
 26
 27
 28class MultipleSequenceTemplatesWithName(Exception):
 29    """Indicates that multiple sequence templates with the given name can be found."""
 30
 31    def __init__(self, name: str) -> None:
 32        """@private"""
 33        super().__init__(
 34            f"Multiple sequence templates with name '{name}' found, ensure the names are unique, or use the "
 35            f"`get_sequence_templates` method to filter them yourself"
 36        )
 37
 38
 39class NoQualityControlTemplateWithName(Exception):
 40    """Indicates that no quality control template with the given name can be found."""
 41
 42    def __init__(self, name: str) -> None:
 43        """@private"""
 44        super().__init__(f"No quality control template with name '{name}' found")
 45
 46
 47class MultipleQualityControlTemplatesWithName(Exception):
 48    """Indicates that multiple quality control templates with the given name can be found."""
 49
 50    def __init__(self, name: str) -> None:
 51        """@private"""
 52        super().__init__(
 53            f"Multiple quality control templates with name '{name}' found, ensure the names are unique, or use the "
 54            f"`get_quality_control_templates` method to filter them yourself"
 55        )
 56
 57
 58class NoSequenceTemplateWithName(Exception):
 59    """Indicates that no sequence template with the given name can be found."""
 60
 61    def __init__(self, name: str) -> None:
 62        """@private"""
 63        super().__init__(f"No sequence template with name '{name}' found")
 64
 65
 66class SequenceAnnotationApi:
 67    _inner_api_client: openapi_client.ApiClient
 68    _log_level: LogLevel
 69
 70    def __init__(self, inner_api_client: openapi_client.ApiClient, log_level: LogLevel):
 71        """@private"""
 72        self._inner_api_client = inner_api_client
 73        self._log_level = log_level
 74
 75    def get_quality_control_templates(self) -> list[QualityControlTemplate]:
 76        """Get a list of all quality control templates owned by you or shared with you.
 77
 78        Returns:
 79            list[enpi_api.l2.types.sequence_annotation.QualityControlTemplate]: A list of quality control templates.
 80
 81        Raises:
 82            enpi_api.l2.types.api_error.ApiError: If API request fails.
 83
 84        Example:
 85            ```python
 86            quality_control_templates = self.get_quality_control_templates()
 87            ```
 88        """
 89
 90        sequence_annotation_api_instance = openapi_client.SequenceAnnotationApi(self._inner_api_client)
 91
 92        try:
 93            return [QualityControlTemplate.from_raw(i) for i in sequence_annotation_api_instance.quality_control_templates()]
 94        except openapi_client.ApiException as e:
 95            raise ApiError(e)
 96
 97    def get_quality_control_template_by_name(self, name: str) -> QualityControlTemplate:
 98        """Get a quality control template by its name.
 99
100        It will raise an error if not exactly one quality control template with the given name is found.
101
102        Args:
103            name (str): The name of the quality control template to get.
104
105        Returns:
106            enpi_api.l2.types.sequence_annotation.QualityControlTemplate: The quality control template.
107
108        Raises:
109            enpi_api.l2.client.api.sequence_annotation_api.NoQualityControlTemplateWithName: If no quality control template with the given name can be found.
110            enpi_api.l2.client.api.sequence_annotation_api.MultipleQualityControlTemplatesWithName: If multiple quality control templates with the given name can be found.
111            enpi_api.l2.types.api_error.ApiError: If API request fails.
112
113        Example:
114            ```python
115            name = "Quality control template 1"
116            quality_control_template = self.get_quality_control_template_by_name(name)
117            ```
118        """
119
120        quality_control_templates = self.get_quality_control_templates()
121
122        matching_templates = [qct for qct in quality_control_templates if qct.name == name]
123
124        if len(matching_templates) == 0:
125            raise NoQualityControlTemplateWithName(name)
126        elif len(matching_templates) > 1:
127            raise MultipleQualityControlTemplatesWithName(name)
128
129        return matching_templates[0]
130
131    def get_sequence_templates(self) -> list[SequenceTemplate]:
132        """Get a list of all sequence templates owned by you or shared with you.
133
134        Returns:
135            list[enpi_api.l2.types.sequence_annotation.SequenceTemplate]: A list of sequence templates
136
137        Raises:
138            enpi_api.l2.types.api_error.ApiError: If API request fails.
139
140        Example:
141            ```python
142            sequence_templates = self.get_sequence_templates()
143            ```
144        """
145
146        sequence_annotation_api_instance = openapi_client.SequenceAnnotationApi(self._inner_api_client)
147
148        try:
149            return [SequenceTemplate.from_raw(i) for i in sequence_annotation_api_instance.sequence_templates()]
150        except openapi_client.ApiException as e:
151            raise ApiError(e)
152
153    def get_sequence_template_by_name(self, name: str) -> SequenceTemplate:
154        """Get a sequence template by its name.
155
156        It will raise an error if not exactly one sequence template with the given name is found.
157
158        Args:
159            name (str): The name of the sequence template to get.
160
161        Raises:
162            enpi_api.l2.client.api.sequence_annotation_api.NoSequenceTemplateWithName: If no sequence template with the given name can be found.
163            enpi_api.l2.client.api.sequence_annotation_api.MultipleSequenceTemplatesWithName: If multiple sequence templates with the given name can be found.
164            enpi_api.l2.types.api_error.ApiError: If API request fails.
165
166        Returns:
167            enpi_api.l2.types.sequence_annotation.SequenceTemplate: The sequence template.
168
169        Example:
170            ```python
171            name = "Sequence template 1"
172            sequence_template = self.get_sequence_template_by_name(name)
173            ```
174        """
175
176        sequence_templates = self.get_sequence_templates()
177
178        matching_templates = [st for st in sequence_templates if st.name == name]
179
180        if len(matching_templates) == 0:
181            raise NoSequenceTemplateWithName(name)
182        elif len(matching_templates) > 1:
183            raise MultipleSequenceTemplatesWithName(name)
184
185        return matching_templates[0]
186
187    def start(
188        self,
189        name: str,
190        file_ids: list[FileId],
191        sequence_templates: list[SequenceTemplateConfig],
192        reference_database_revision: ReferenceDatabaseRevision,
193        quality_control_template: QualityControlTemplate,
194        archive_inputs: bool = False,
195        clone_id_extraction: CloneIdentifierExtractionConfig | None = None,
196        correction_settings: CorrectionSettings | None = None,
197        mutation_assay_settings: MutationAssaySettings | None = None,
198        chain_fraction_tag_id: TagId | None = None,
199        liability_check: list[LiabilityType | str] = [],
200        restrict_deduplication_within_file: bool = False,
201        should_deduplicate_on_amino_acids: bool = False,
202        filename_tag_id: TagId | None = None,
203        extend_alignment_to_cover_full_vdj: bool = False,
204    ) -> Execution[CollectionMetadata]:
205        """Start Sequence Annotation on raw sequencing data.
206
207        A sequence template (available here: enpi_api.l2.client.api.sequence_annotation_api.SequenceAnnotationApi.get_sequence_template_by_name) and a quality control template
208        (enpi_api.l2.client.api.sequence_annotation_api.SequenceAnnotationApi.get_quality_control_template_by_name) are required in order to run a Sequence Annotation task.
209        **<u>Templates can be created and configured only via the [web interface of ENPICOM-Platform](https://igx.bio/)</u>**, it can not
210        be done through SDK or API. Additionally, getting familiar with Sequence Annotation in the web interface can help
211        in understanding it and setting up a desired task configuration due to it being more informative than the
212        minimal documentation provided for this function.
213
214        Args:
215            name (str): The name of the resulting collection.
216            file_ids (list[enpi_api.l2.types.file.FileId]): List of the IDs of raw sequencing data files.
217            sequence_templates (list[enpi_api.l2.types.sequence_annotation.SequenceTemplateConfig]): A list of configuration objects to specify the sequence
218              templates to be used. For more information, see the `enpi_api.l2.types.sequence_annotation.SequenceTemplateConfig` class.
219            reference_database_revision (enpi_api.l2.types.reference_database.ReferenceDatabaseRevision | None): The reference database revision to use.
220              The reference database specifies which organism it is linked to.
221            archive_inputs (bool): Whether to archive the input files after the Sequence Annotation run is finished.
222            quality_control_template (enpi_api.l2.types.sequence_annotation.QualityControlTemplate): The Quality Control Template to use.
223            clone_id_extraction (enpi_api.l2.types.sequence_annotation.CloneIdentifierExtractionConfig | None): The configuration for extracting clone IDs. This is only
224              needed if your sequence template has the option "Manually Specify Clone Identifier" enabled. In other
225              cases, this parameter can be omitted.
226
227              For more information, see the `enpi_api.l2.types.sequence_annotation.CloneIdentifierExtractionConfig` class.
228            correction_settings (enpi_api.l2.types.sequence_annotation.CorrectionSettings | None): The settings to correct regions to the germline reference,
229            or complete the sequence to full VDJ using germline reference nucleotides.
230            This is useful to reduce artificial diversity in libraries with e.g. fixed framework regions.
231            mutation_assay_settings (enpi_api.l2.types.sequence_annotation.MutationAssaySettings | None): The settings to run Sequence Annotation for a mutation assay.
232            chain_fraction_tag_id (enpi_api.l2.types.tag.TagId | None): The sequence-level tag identifier of the tag that is used to store
233              the fraction of each chain within a clone.
234            liability_check (list[enpi_api.l2.types.sequence_annotation.LiabilityType | str]): A list of liability checks to perform.
235              Summed counts are stored as clone level tags.
236            extend_alignment_to_cover_full_vdj (bool): Aligner extracts as much VDJ as read coverage allows, tolerates mismatches, and always extends by full codons.
237              Recommended for full-VDJ sequencing; not for amplicons partially covering VDJ.
238
239        Raises:
240            enpi_api.l2.types.api_error.ApiError: If API request fails.
241
242        Returns:
243            enpi_api.l2.types.execution.Execution[enpi_api.l2.types.collection.CollectionMetadata]: An object that allows you to wait for the
244              execution to finish and get the resulting collection metadata.
245
246        Example:
247
248            Part of `start_sequence_annotation_run.py` example script.
249
250            ```python
251            # Templates need to be present in the ENPICOM-Platform already
252            sequence_template_name = "sequence template 1"
253            quality_control_template_name = "quality control template 1"
254
255            sequence_templates = [st for st in client.sequence_annotation_api.get_sequence_templates() if st.name == sequence_template_name]
256            quality_control_templates = [qct for qct in client.sequence_annotation_api.get_quality_control_templates() if qct.name == quality_control_template_name]
257
258            quality_control_template = QualityControlTemplate(quality_control_templates[0])
259            sequence_template_id = SequenceTemplateId(sequence_templates[0].id)
260
261            # Upload the input file
262            file_path = "data.fq"
263            file: File = client.file_api.upload_file(file_path=file_path, tags=[]).wait()
264            file_ids = [file.id]
265
266            # Get the reference database revision
267            reference_database_revision = client.reference_database_api.get_revision_by_name(name=REFERENCE_NAME, species=ORGANISM)
268
269            collection_name = "New collection from Sequence Annotation"
270
271            # We will now start Sequence Annotation, which will process raw sequencing data into annotated clone collections
272            clone_collection = client.sequence_annotation_api.start(
273                name=collection_name,
274                file_ids=file_ids,
275                # To assign a sequence template to each input file
276                sequence_templates=[
277                    SequenceTemplateConfig(
278                        # We select it using a selector, in this case by matching the file_id, but we could also match on file name or tags
279                        selector=SequenceTemplateSelector(value=f),
280                        # And then assign it using a sequence template id
281                        id=sequence_template_id,
282                    )
283                    for f in file_ids
284                ],
285                reference_database_revision=reference_database_revision,
286                # Archives the raw sequencing data after they have been processed
287                archive_inputs=True,
288                quality_control_template=quality_control_template,
289            ).wait()
290            ```
291        """
292
293        if filename_tag_id is not None:
294            if not restrict_deduplication_within_file:
295                raise ValueError("filename_tag_id can only be set if restrict_deduplication_within_file is set to True")
296
297        sequence_annotation_api_instance = openapi_client.SequenceAnnotationApi(self._inner_api_client)
298
299        try:
300            inner_sequence_templates: list[openapi_client.SequenceAnnotationWorkSequenceTemplatesInner] = []
301            for st in sequence_templates:
302                match st.selector.type:
303                    case "file_id":
304                        inner_sequence_templates.append(
305                            openapi_client.SequenceAnnotationWorkSequenceTemplatesInner(
306                                template_id=st.id,
307                                template_version=st.version,
308                                selector=openapi_client.SequenceTemplateSelector(
309                                    openapi_client.MatchAFileByItsID(type=st.selector.type, value=st.selector.value)
310                                ),
311                            )
312                        )
313                    case _:
314                        assert False, f"Selector type {st.selector.type} should be matched"
315
316            sequence_annotation_work = openapi_client.SequenceAnnotationWork(
317                name=name,
318                file_ids=[UUID(fid) for fid in file_ids],
319                sequence_templates=inner_sequence_templates,
320                reference_database=openapi_client.ReferenceDatabaseIdVersion(
321                    id=str(reference_database_revision.reference_database_id),
322                    version=int(reference_database_revision.reference_database_version),
323                ),
324                quality_control_template=openapi_client.QualityControlTemplateIdOptionalVersion(
325                    id=str(quality_control_template.id), version=int(quality_control_template.version)
326                ),
327                archive_inputs=archive_inputs,
328                clone_id_to_tag_spec=clone_id_extraction.to_api_payload() if clone_id_extraction else None,
329                correction_settings=correction_settings.to_api_payload() if correction_settings else None,
330                mutation_assay_settings=mutation_assay_settings.to_api_payload() if mutation_assay_settings else None,
331                chain_fraction_tag_id=int(chain_fraction_tag_id) if chain_fraction_tag_id is not None else None,
332                liability_check=liability_check,
333                restrict_deduplication_within_file=restrict_deduplication_within_file,
334                should_deduplicate_on_amino_acids=should_deduplicate_on_amino_acids,
335                filename_tag_id=int(filename_tag_id) if filename_tag_id is not None else None,
336                extend_alignment_to_cover_full_vdj=extend_alignment_to_cover_full_vdj,
337            )
338
339            with ApiErrorContext():
340                sequence_annotation_job = sequence_annotation_api_instance.start_sequence_annotation(sequence_annotation_work=sequence_annotation_work)
341                assert sequence_annotation_job.workflow_execution_id is not None
342
343                workflow_execution_id = WorkflowExecutionId(int(sequence_annotation_job.workflow_execution_id))
344
345                def on_complete(task_id: WorkflowExecutionTaskId, task_state: TaskState) -> CollectionMetadata:
346                    assert task_state == TaskState.SUCCEEDED, f"Task {task_id} did not reach {TaskState.SUCCEEDED} state, got {task_state} state instead"
347
348                    get_collection_id_response = sequence_annotation_api_instance.get_sequence_annotation_collection_id_by_workflow_execution_task_id(task_id)
349                    collection_id = get_collection_id_response.collection_id
350                    assert collection_id is not None
351
352                    logger.success(f"Collection with ID `{collection_id}` was successfully obtained by running Sequence Annotation")
353
354                    collection_api = CollectionApi(self._inner_api_client, self._log_level)
355                    return collection_api.get_collection_metadata_by_id(CollectionId(collection_id))
356
357                waitable = WorkflowExecutionTaskWaitable[CollectionMetadata](
358                    workflow_execution_id=workflow_execution_id,
359                    task_template_name=WorkflowTaskTemplateName.ENPI_APP_SEQUENCE_ANNOTATION,
360                    on_complete=on_complete,
361                )
362
363                return Execution(wait=waitable.wait_and_return_result, check_execution_state=waitable.check_execution_state)
364
365        except openapi_client.ApiException as e:
366            raise ApiError(e)
class MultipleSequenceTemplatesWithName(builtins.Exception):
29class MultipleSequenceTemplatesWithName(Exception):
30    """Indicates that multiple sequence templates with the given name can be found."""
31
32    def __init__(self, name: str) -> None:
33        """@private"""
34        super().__init__(
35            f"Multiple sequence templates with name '{name}' found, ensure the names are unique, or use the "
36            f"`get_sequence_templates` method to filter them yourself"
37        )

Indicates that multiple sequence templates with the given name can be found.

class NoQualityControlTemplateWithName(builtins.Exception):
40class NoQualityControlTemplateWithName(Exception):
41    """Indicates that no quality control template with the given name can be found."""
42
43    def __init__(self, name: str) -> None:
44        """@private"""
45        super().__init__(f"No quality control template with name '{name}' found")

Indicates that no quality control template with the given name can be found.

class MultipleQualityControlTemplatesWithName(builtins.Exception):
48class MultipleQualityControlTemplatesWithName(Exception):
49    """Indicates that multiple quality control templates with the given name can be found."""
50
51    def __init__(self, name: str) -> None:
52        """@private"""
53        super().__init__(
54            f"Multiple quality control templates with name '{name}' found, ensure the names are unique, or use the "
55            f"`get_quality_control_templates` method to filter them yourself"
56        )

Indicates that multiple quality control templates with the given name can be found.

class NoSequenceTemplateWithName(builtins.Exception):
59class NoSequenceTemplateWithName(Exception):
60    """Indicates that no sequence template with the given name can be found."""
61
62    def __init__(self, name: str) -> None:
63        """@private"""
64        super().__init__(f"No sequence template with name '{name}' found")

Indicates that no sequence template with the given name can be found.

class SequenceAnnotationApi:
 67class SequenceAnnotationApi:
 68    _inner_api_client: openapi_client.ApiClient
 69    _log_level: LogLevel
 70
 71    def __init__(self, inner_api_client: openapi_client.ApiClient, log_level: LogLevel):
 72        """@private"""
 73        self._inner_api_client = inner_api_client
 74        self._log_level = log_level
 75
 76    def get_quality_control_templates(self) -> list[QualityControlTemplate]:
 77        """Get a list of all quality control templates owned by you or shared with you.
 78
 79        Returns:
 80            list[enpi_api.l2.types.sequence_annotation.QualityControlTemplate]: A list of quality control templates.
 81
 82        Raises:
 83            enpi_api.l2.types.api_error.ApiError: If API request fails.
 84
 85        Example:
 86            ```python
 87            quality_control_templates = self.get_quality_control_templates()
 88            ```
 89        """
 90
 91        sequence_annotation_api_instance = openapi_client.SequenceAnnotationApi(self._inner_api_client)
 92
 93        try:
 94            return [QualityControlTemplate.from_raw(i) for i in sequence_annotation_api_instance.quality_control_templates()]
 95        except openapi_client.ApiException as e:
 96            raise ApiError(e)
 97
 98    def get_quality_control_template_by_name(self, name: str) -> QualityControlTemplate:
 99        """Get a quality control template by its name.
100
101        It will raise an error if not exactly one quality control template with the given name is found.
102
103        Args:
104            name (str): The name of the quality control template to get.
105
106        Returns:
107            enpi_api.l2.types.sequence_annotation.QualityControlTemplate: The quality control template.
108
109        Raises:
110            enpi_api.l2.client.api.sequence_annotation_api.NoQualityControlTemplateWithName: If no quality control template with the given name can be found.
111            enpi_api.l2.client.api.sequence_annotation_api.MultipleQualityControlTemplatesWithName: If multiple quality control templates with the given name can be found.
112            enpi_api.l2.types.api_error.ApiError: If API request fails.
113
114        Example:
115            ```python
116            name = "Quality control template 1"
117            quality_control_template = self.get_quality_control_template_by_name(name)
118            ```
119        """
120
121        quality_control_templates = self.get_quality_control_templates()
122
123        matching_templates = [qct for qct in quality_control_templates if qct.name == name]
124
125        if len(matching_templates) == 0:
126            raise NoQualityControlTemplateWithName(name)
127        elif len(matching_templates) > 1:
128            raise MultipleQualityControlTemplatesWithName(name)
129
130        return matching_templates[0]
131
132    def get_sequence_templates(self) -> list[SequenceTemplate]:
133        """Get a list of all sequence templates owned by you or shared with you.
134
135        Returns:
136            list[enpi_api.l2.types.sequence_annotation.SequenceTemplate]: A list of sequence templates
137
138        Raises:
139            enpi_api.l2.types.api_error.ApiError: If API request fails.
140
141        Example:
142            ```python
143            sequence_templates = self.get_sequence_templates()
144            ```
145        """
146
147        sequence_annotation_api_instance = openapi_client.SequenceAnnotationApi(self._inner_api_client)
148
149        try:
150            return [SequenceTemplate.from_raw(i) for i in sequence_annotation_api_instance.sequence_templates()]
151        except openapi_client.ApiException as e:
152            raise ApiError(e)
153
154    def get_sequence_template_by_name(self, name: str) -> SequenceTemplate:
155        """Get a sequence template by its name.
156
157        It will raise an error if not exactly one sequence template with the given name is found.
158
159        Args:
160            name (str): The name of the sequence template to get.
161
162        Raises:
163            enpi_api.l2.client.api.sequence_annotation_api.NoSequenceTemplateWithName: If no sequence template with the given name can be found.
164            enpi_api.l2.client.api.sequence_annotation_api.MultipleSequenceTemplatesWithName: If multiple sequence templates with the given name can be found.
165            enpi_api.l2.types.api_error.ApiError: If API request fails.
166
167        Returns:
168            enpi_api.l2.types.sequence_annotation.SequenceTemplate: The sequence template.
169
170        Example:
171            ```python
172            name = "Sequence template 1"
173            sequence_template = self.get_sequence_template_by_name(name)
174            ```
175        """
176
177        sequence_templates = self.get_sequence_templates()
178
179        matching_templates = [st for st in sequence_templates if st.name == name]
180
181        if len(matching_templates) == 0:
182            raise NoSequenceTemplateWithName(name)
183        elif len(matching_templates) > 1:
184            raise MultipleSequenceTemplatesWithName(name)
185
186        return matching_templates[0]
187
188    def start(
189        self,
190        name: str,
191        file_ids: list[FileId],
192        sequence_templates: list[SequenceTemplateConfig],
193        reference_database_revision: ReferenceDatabaseRevision,
194        quality_control_template: QualityControlTemplate,
195        archive_inputs: bool = False,
196        clone_id_extraction: CloneIdentifierExtractionConfig | None = None,
197        correction_settings: CorrectionSettings | None = None,
198        mutation_assay_settings: MutationAssaySettings | None = None,
199        chain_fraction_tag_id: TagId | None = None,
200        liability_check: list[LiabilityType | str] = [],
201        restrict_deduplication_within_file: bool = False,
202        should_deduplicate_on_amino_acids: bool = False,
203        filename_tag_id: TagId | None = None,
204        extend_alignment_to_cover_full_vdj: bool = False,
205    ) -> Execution[CollectionMetadata]:
206        """Start Sequence Annotation on raw sequencing data.
207
208        A sequence template (available here: enpi_api.l2.client.api.sequence_annotation_api.SequenceAnnotationApi.get_sequence_template_by_name) and a quality control template
209        (enpi_api.l2.client.api.sequence_annotation_api.SequenceAnnotationApi.get_quality_control_template_by_name) are required in order to run a Sequence Annotation task.
210        **<u>Templates can be created and configured only via the [web interface of ENPICOM-Platform](https://igx.bio/)</u>**, it can not
211        be done through SDK or API. Additionally, getting familiar with Sequence Annotation in the web interface can help
212        in understanding it and setting up a desired task configuration due to it being more informative than the
213        minimal documentation provided for this function.
214
215        Args:
216            name (str): The name of the resulting collection.
217            file_ids (list[enpi_api.l2.types.file.FileId]): List of the IDs of raw sequencing data files.
218            sequence_templates (list[enpi_api.l2.types.sequence_annotation.SequenceTemplateConfig]): A list of configuration objects to specify the sequence
219              templates to be used. For more information, see the `enpi_api.l2.types.sequence_annotation.SequenceTemplateConfig` class.
220            reference_database_revision (enpi_api.l2.types.reference_database.ReferenceDatabaseRevision | None): The reference database revision to use.
221              The reference database specifies which organism it is linked to.
222            archive_inputs (bool): Whether to archive the input files after the Sequence Annotation run is finished.
223            quality_control_template (enpi_api.l2.types.sequence_annotation.QualityControlTemplate): The Quality Control Template to use.
224            clone_id_extraction (enpi_api.l2.types.sequence_annotation.CloneIdentifierExtractionConfig | None): The configuration for extracting clone IDs. This is only
225              needed if your sequence template has the option "Manually Specify Clone Identifier" enabled. In other
226              cases, this parameter can be omitted.
227
228              For more information, see the `enpi_api.l2.types.sequence_annotation.CloneIdentifierExtractionConfig` class.
229            correction_settings (enpi_api.l2.types.sequence_annotation.CorrectionSettings | None): The settings to correct regions to the germline reference,
230            or complete the sequence to full VDJ using germline reference nucleotides.
231            This is useful to reduce artificial diversity in libraries with e.g. fixed framework regions.
232            mutation_assay_settings (enpi_api.l2.types.sequence_annotation.MutationAssaySettings | None): The settings to run Sequence Annotation for a mutation assay.
233            chain_fraction_tag_id (enpi_api.l2.types.tag.TagId | None): The sequence-level tag identifier of the tag that is used to store
234              the fraction of each chain within a clone.
235            liability_check (list[enpi_api.l2.types.sequence_annotation.LiabilityType | str]): A list of liability checks to perform.
236              Summed counts are stored as clone level tags.
237            extend_alignment_to_cover_full_vdj (bool): Aligner extracts as much VDJ as read coverage allows, tolerates mismatches, and always extends by full codons.
238              Recommended for full-VDJ sequencing; not for amplicons partially covering VDJ.
239
240        Raises:
241            enpi_api.l2.types.api_error.ApiError: If API request fails.
242
243        Returns:
244            enpi_api.l2.types.execution.Execution[enpi_api.l2.types.collection.CollectionMetadata]: An object that allows you to wait for the
245              execution to finish and get the resulting collection metadata.
246
247        Example:
248
249            Part of `start_sequence_annotation_run.py` example script.
250
251            ```python
252            # Templates need to be present in the ENPICOM-Platform already
253            sequence_template_name = "sequence template 1"
254            quality_control_template_name = "quality control template 1"
255
256            sequence_templates = [st for st in client.sequence_annotation_api.get_sequence_templates() if st.name == sequence_template_name]
257            quality_control_templates = [qct for qct in client.sequence_annotation_api.get_quality_control_templates() if qct.name == quality_control_template_name]
258
259            quality_control_template = QualityControlTemplate(quality_control_templates[0])
260            sequence_template_id = SequenceTemplateId(sequence_templates[0].id)
261
262            # Upload the input file
263            file_path = "data.fq"
264            file: File = client.file_api.upload_file(file_path=file_path, tags=[]).wait()
265            file_ids = [file.id]
266
267            # Get the reference database revision
268            reference_database_revision = client.reference_database_api.get_revision_by_name(name=REFERENCE_NAME, species=ORGANISM)
269
270            collection_name = "New collection from Sequence Annotation"
271
272            # We will now start Sequence Annotation, which will process raw sequencing data into annotated clone collections
273            clone_collection = client.sequence_annotation_api.start(
274                name=collection_name,
275                file_ids=file_ids,
276                # To assign a sequence template to each input file
277                sequence_templates=[
278                    SequenceTemplateConfig(
279                        # We select it using a selector, in this case by matching the file_id, but we could also match on file name or tags
280                        selector=SequenceTemplateSelector(value=f),
281                        # And then assign it using a sequence template id
282                        id=sequence_template_id,
283                    )
284                    for f in file_ids
285                ],
286                reference_database_revision=reference_database_revision,
287                # Archives the raw sequencing data after they have been processed
288                archive_inputs=True,
289                quality_control_template=quality_control_template,
290            ).wait()
291            ```
292        """
293
294        if filename_tag_id is not None:
295            if not restrict_deduplication_within_file:
296                raise ValueError("filename_tag_id can only be set if restrict_deduplication_within_file is set to True")
297
298        sequence_annotation_api_instance = openapi_client.SequenceAnnotationApi(self._inner_api_client)
299
300        try:
301            inner_sequence_templates: list[openapi_client.SequenceAnnotationWorkSequenceTemplatesInner] = []
302            for st in sequence_templates:
303                match st.selector.type:
304                    case "file_id":
305                        inner_sequence_templates.append(
306                            openapi_client.SequenceAnnotationWorkSequenceTemplatesInner(
307                                template_id=st.id,
308                                template_version=st.version,
309                                selector=openapi_client.SequenceTemplateSelector(
310                                    openapi_client.MatchAFileByItsID(type=st.selector.type, value=st.selector.value)
311                                ),
312                            )
313                        )
314                    case _:
315                        assert False, f"Selector type {st.selector.type} should be matched"
316
317            sequence_annotation_work = openapi_client.SequenceAnnotationWork(
318                name=name,
319                file_ids=[UUID(fid) for fid in file_ids],
320                sequence_templates=inner_sequence_templates,
321                reference_database=openapi_client.ReferenceDatabaseIdVersion(
322                    id=str(reference_database_revision.reference_database_id),
323                    version=int(reference_database_revision.reference_database_version),
324                ),
325                quality_control_template=openapi_client.QualityControlTemplateIdOptionalVersion(
326                    id=str(quality_control_template.id), version=int(quality_control_template.version)
327                ),
328                archive_inputs=archive_inputs,
329                clone_id_to_tag_spec=clone_id_extraction.to_api_payload() if clone_id_extraction else None,
330                correction_settings=correction_settings.to_api_payload() if correction_settings else None,
331                mutation_assay_settings=mutation_assay_settings.to_api_payload() if mutation_assay_settings else None,
332                chain_fraction_tag_id=int(chain_fraction_tag_id) if chain_fraction_tag_id is not None else None,
333                liability_check=liability_check,
334                restrict_deduplication_within_file=restrict_deduplication_within_file,
335                should_deduplicate_on_amino_acids=should_deduplicate_on_amino_acids,
336                filename_tag_id=int(filename_tag_id) if filename_tag_id is not None else None,
337                extend_alignment_to_cover_full_vdj=extend_alignment_to_cover_full_vdj,
338            )
339
340            with ApiErrorContext():
341                sequence_annotation_job = sequence_annotation_api_instance.start_sequence_annotation(sequence_annotation_work=sequence_annotation_work)
342                assert sequence_annotation_job.workflow_execution_id is not None
343
344                workflow_execution_id = WorkflowExecutionId(int(sequence_annotation_job.workflow_execution_id))
345
346                def on_complete(task_id: WorkflowExecutionTaskId, task_state: TaskState) -> CollectionMetadata:
347                    assert task_state == TaskState.SUCCEEDED, f"Task {task_id} did not reach {TaskState.SUCCEEDED} state, got {task_state} state instead"
348
349                    get_collection_id_response = sequence_annotation_api_instance.get_sequence_annotation_collection_id_by_workflow_execution_task_id(task_id)
350                    collection_id = get_collection_id_response.collection_id
351                    assert collection_id is not None
352
353                    logger.success(f"Collection with ID `{collection_id}` was successfully obtained by running Sequence Annotation")
354
355                    collection_api = CollectionApi(self._inner_api_client, self._log_level)
356                    return collection_api.get_collection_metadata_by_id(CollectionId(collection_id))
357
358                waitable = WorkflowExecutionTaskWaitable[CollectionMetadata](
359                    workflow_execution_id=workflow_execution_id,
360                    task_template_name=WorkflowTaskTemplateName.ENPI_APP_SEQUENCE_ANNOTATION,
361                    on_complete=on_complete,
362                )
363
364                return Execution(wait=waitable.wait_and_return_result, check_execution_state=waitable.check_execution_state)
365
366        except openapi_client.ApiException as e:
367            raise ApiError(e)
def get_quality_control_templates( self) -> list[enpi_api.l2.types.sequence_annotation.QualityControlTemplate]:
76    def get_quality_control_templates(self) -> list[QualityControlTemplate]:
77        """Get a list of all quality control templates owned by you or shared with you.
78
79        Returns:
80            list[enpi_api.l2.types.sequence_annotation.QualityControlTemplate]: A list of quality control templates.
81
82        Raises:
83            enpi_api.l2.types.api_error.ApiError: If API request fails.
84
85        Example:
86            ```python
87            quality_control_templates = self.get_quality_control_templates()
88            ```
89        """
90
91        sequence_annotation_api_instance = openapi_client.SequenceAnnotationApi(self._inner_api_client)
92
93        try:
94            return [QualityControlTemplate.from_raw(i) for i in sequence_annotation_api_instance.quality_control_templates()]
95        except openapi_client.ApiException as e:
96            raise ApiError(e)

Get a list of all quality control templates owned by you or shared with you.

Returns:

list[enpi_api.l2.types.sequence_annotation.QualityControlTemplate]: A list of quality control templates.

Raises:
Example:
quality_control_templates = self.get_quality_control_templates()
def get_quality_control_template_by_name( self, name: str) -> enpi_api.l2.types.sequence_annotation.QualityControlTemplate:
 98    def get_quality_control_template_by_name(self, name: str) -> QualityControlTemplate:
 99        """Get a quality control template by its name.
100
101        It will raise an error if not exactly one quality control template with the given name is found.
102
103        Args:
104            name (str): The name of the quality control template to get.
105
106        Returns:
107            enpi_api.l2.types.sequence_annotation.QualityControlTemplate: The quality control template.
108
109        Raises:
110            enpi_api.l2.client.api.sequence_annotation_api.NoQualityControlTemplateWithName: If no quality control template with the given name can be found.
111            enpi_api.l2.client.api.sequence_annotation_api.MultipleQualityControlTemplatesWithName: If multiple quality control templates with the given name can be found.
112            enpi_api.l2.types.api_error.ApiError: If API request fails.
113
114        Example:
115            ```python
116            name = "Quality control template 1"
117            quality_control_template = self.get_quality_control_template_by_name(name)
118            ```
119        """
120
121        quality_control_templates = self.get_quality_control_templates()
122
123        matching_templates = [qct for qct in quality_control_templates if qct.name == name]
124
125        if len(matching_templates) == 0:
126            raise NoQualityControlTemplateWithName(name)
127        elif len(matching_templates) > 1:
128            raise MultipleQualityControlTemplatesWithName(name)
129
130        return matching_templates[0]

Get a quality control template by its name.

It will raise an error if not exactly one quality control template with the given name is found.

Arguments:
  • name (str): The name of the quality control template to get.
Returns:

enpi_api.l2.types.sequence_annotation.QualityControlTemplate: The quality control template.

Raises:
Example:
name = "Quality control template 1"
quality_control_template = self.get_quality_control_template_by_name(name)
def get_sequence_templates(self) -> list[enpi_api.l2.types.sequence_annotation.SequenceTemplate]:
132    def get_sequence_templates(self) -> list[SequenceTemplate]:
133        """Get a list of all sequence templates owned by you or shared with you.
134
135        Returns:
136            list[enpi_api.l2.types.sequence_annotation.SequenceTemplate]: A list of sequence templates
137
138        Raises:
139            enpi_api.l2.types.api_error.ApiError: If API request fails.
140
141        Example:
142            ```python
143            sequence_templates = self.get_sequence_templates()
144            ```
145        """
146
147        sequence_annotation_api_instance = openapi_client.SequenceAnnotationApi(self._inner_api_client)
148
149        try:
150            return [SequenceTemplate.from_raw(i) for i in sequence_annotation_api_instance.sequence_templates()]
151        except openapi_client.ApiException as e:
152            raise ApiError(e)

Get a list of all sequence templates owned by you or shared with you.

Returns:

list[enpi_api.l2.types.sequence_annotation.SequenceTemplate]: A list of sequence templates

Raises:
Example:
sequence_templates = self.get_sequence_templates()
def get_sequence_template_by_name( self, name: str) -> enpi_api.l2.types.sequence_annotation.SequenceTemplate:
154    def get_sequence_template_by_name(self, name: str) -> SequenceTemplate:
155        """Get a sequence template by its name.
156
157        It will raise an error if not exactly one sequence template with the given name is found.
158
159        Args:
160            name (str): The name of the sequence template to get.
161
162        Raises:
163            enpi_api.l2.client.api.sequence_annotation_api.NoSequenceTemplateWithName: If no sequence template with the given name can be found.
164            enpi_api.l2.client.api.sequence_annotation_api.MultipleSequenceTemplatesWithName: If multiple sequence templates with the given name can be found.
165            enpi_api.l2.types.api_error.ApiError: If API request fails.
166
167        Returns:
168            enpi_api.l2.types.sequence_annotation.SequenceTemplate: The sequence template.
169
170        Example:
171            ```python
172            name = "Sequence template 1"
173            sequence_template = self.get_sequence_template_by_name(name)
174            ```
175        """
176
177        sequence_templates = self.get_sequence_templates()
178
179        matching_templates = [st for st in sequence_templates if st.name == name]
180
181        if len(matching_templates) == 0:
182            raise NoSequenceTemplateWithName(name)
183        elif len(matching_templates) > 1:
184            raise MultipleSequenceTemplatesWithName(name)
185
186        return matching_templates[0]

Get a sequence template by its name.

It will raise an error if not exactly one sequence template with the given name is found.

Arguments:
  • name (str): The name of the sequence template to get.
Raises:
Returns:

enpi_api.l2.types.sequence_annotation.SequenceTemplate: The sequence template.

Example:
name = "Sequence template 1"
sequence_template = self.get_sequence_template_by_name(name)
def start( self, name: str, file_ids: list[enpi_api.l2.types.file.FileId], sequence_templates: list[enpi_api.l2.types.sequence_annotation.SequenceTemplateConfig], reference_database_revision: enpi_api.l2.types.reference_database.ReferenceDatabaseRevision, quality_control_template: enpi_api.l2.types.sequence_annotation.QualityControlTemplate, archive_inputs: bool = False, clone_id_extraction: enpi_api.l2.types.sequence_annotation.CloneIdentifierExtractionConfig | None = None, correction_settings: enpi_api.l2.types.sequence_annotation.CorrectionSettings | None = None, mutation_assay_settings: enpi_api.l2.types.sequence_annotation.MutationAssaySettings | None = None, chain_fraction_tag_id: Optional[enpi_api.l2.types.tag.TagId] = None, liability_check: list[enpi_api.l2.types.sequence_annotation.LiabilityType | str] = [], restrict_deduplication_within_file: bool = False, should_deduplicate_on_amino_acids: bool = False, filename_tag_id: Optional[enpi_api.l2.types.tag.TagId] = None, extend_alignment_to_cover_full_vdj: bool = False) -> enpi_api.l2.types.execution.Execution[CollectionMetadata]:
188    def start(
189        self,
190        name: str,
191        file_ids: list[FileId],
192        sequence_templates: list[SequenceTemplateConfig],
193        reference_database_revision: ReferenceDatabaseRevision,
194        quality_control_template: QualityControlTemplate,
195        archive_inputs: bool = False,
196        clone_id_extraction: CloneIdentifierExtractionConfig | None = None,
197        correction_settings: CorrectionSettings | None = None,
198        mutation_assay_settings: MutationAssaySettings | None = None,
199        chain_fraction_tag_id: TagId | None = None,
200        liability_check: list[LiabilityType | str] = [],
201        restrict_deduplication_within_file: bool = False,
202        should_deduplicate_on_amino_acids: bool = False,
203        filename_tag_id: TagId | None = None,
204        extend_alignment_to_cover_full_vdj: bool = False,
205    ) -> Execution[CollectionMetadata]:
206        """Start Sequence Annotation on raw sequencing data.
207
208        A sequence template (available here: enpi_api.l2.client.api.sequence_annotation_api.SequenceAnnotationApi.get_sequence_template_by_name) and a quality control template
209        (enpi_api.l2.client.api.sequence_annotation_api.SequenceAnnotationApi.get_quality_control_template_by_name) are required in order to run a Sequence Annotation task.
210        **<u>Templates can be created and configured only via the [web interface of ENPICOM-Platform](https://igx.bio/)</u>**, it can not
211        be done through SDK or API. Additionally, getting familiar with Sequence Annotation in the web interface can help
212        in understanding it and setting up a desired task configuration due to it being more informative than the
213        minimal documentation provided for this function.
214
215        Args:
216            name (str): The name of the resulting collection.
217            file_ids (list[enpi_api.l2.types.file.FileId]): List of the IDs of raw sequencing data files.
218            sequence_templates (list[enpi_api.l2.types.sequence_annotation.SequenceTemplateConfig]): A list of configuration objects to specify the sequence
219              templates to be used. For more information, see the `enpi_api.l2.types.sequence_annotation.SequenceTemplateConfig` class.
220            reference_database_revision (enpi_api.l2.types.reference_database.ReferenceDatabaseRevision | None): The reference database revision to use.
221              The reference database specifies which organism it is linked to.
222            archive_inputs (bool): Whether to archive the input files after the Sequence Annotation run is finished.
223            quality_control_template (enpi_api.l2.types.sequence_annotation.QualityControlTemplate): The Quality Control Template to use.
224            clone_id_extraction (enpi_api.l2.types.sequence_annotation.CloneIdentifierExtractionConfig | None): The configuration for extracting clone IDs. This is only
225              needed if your sequence template has the option "Manually Specify Clone Identifier" enabled. In other
226              cases, this parameter can be omitted.
227
228              For more information, see the `enpi_api.l2.types.sequence_annotation.CloneIdentifierExtractionConfig` class.
229            correction_settings (enpi_api.l2.types.sequence_annotation.CorrectionSettings | None): The settings to correct regions to the germline reference,
230            or complete the sequence to full VDJ using germline reference nucleotides.
231            This is useful to reduce artificial diversity in libraries with e.g. fixed framework regions.
232            mutation_assay_settings (enpi_api.l2.types.sequence_annotation.MutationAssaySettings | None): The settings to run Sequence Annotation for a mutation assay.
233            chain_fraction_tag_id (enpi_api.l2.types.tag.TagId | None): The sequence-level tag identifier of the tag that is used to store
234              the fraction of each chain within a clone.
235            liability_check (list[enpi_api.l2.types.sequence_annotation.LiabilityType | str]): A list of liability checks to perform.
236              Summed counts are stored as clone level tags.
237            extend_alignment_to_cover_full_vdj (bool): Aligner extracts as much VDJ as read coverage allows, tolerates mismatches, and always extends by full codons.
238              Recommended for full-VDJ sequencing; not for amplicons partially covering VDJ.
239
240        Raises:
241            enpi_api.l2.types.api_error.ApiError: If API request fails.
242
243        Returns:
244            enpi_api.l2.types.execution.Execution[enpi_api.l2.types.collection.CollectionMetadata]: An object that allows you to wait for the
245              execution to finish and get the resulting collection metadata.
246
247        Example:
248
249            Part of `start_sequence_annotation_run.py` example script.
250
251            ```python
252            # Templates need to be present in the ENPICOM-Platform already
253            sequence_template_name = "sequence template 1"
254            quality_control_template_name = "quality control template 1"
255
256            sequence_templates = [st for st in client.sequence_annotation_api.get_sequence_templates() if st.name == sequence_template_name]
257            quality_control_templates = [qct for qct in client.sequence_annotation_api.get_quality_control_templates() if qct.name == quality_control_template_name]
258
259            quality_control_template = QualityControlTemplate(quality_control_templates[0])
260            sequence_template_id = SequenceTemplateId(sequence_templates[0].id)
261
262            # Upload the input file
263            file_path = "data.fq"
264            file: File = client.file_api.upload_file(file_path=file_path, tags=[]).wait()
265            file_ids = [file.id]
266
267            # Get the reference database revision
268            reference_database_revision = client.reference_database_api.get_revision_by_name(name=REFERENCE_NAME, species=ORGANISM)
269
270            collection_name = "New collection from Sequence Annotation"
271
272            # We will now start Sequence Annotation, which will process raw sequencing data into annotated clone collections
273            clone_collection = client.sequence_annotation_api.start(
274                name=collection_name,
275                file_ids=file_ids,
276                # To assign a sequence template to each input file
277                sequence_templates=[
278                    SequenceTemplateConfig(
279                        # We select it using a selector, in this case by matching the file_id, but we could also match on file name or tags
280                        selector=SequenceTemplateSelector(value=f),
281                        # And then assign it using a sequence template id
282                        id=sequence_template_id,
283                    )
284                    for f in file_ids
285                ],
286                reference_database_revision=reference_database_revision,
287                # Archives the raw sequencing data after they have been processed
288                archive_inputs=True,
289                quality_control_template=quality_control_template,
290            ).wait()
291            ```
292        """
293
294        if filename_tag_id is not None:
295            if not restrict_deduplication_within_file:
296                raise ValueError("filename_tag_id can only be set if restrict_deduplication_within_file is set to True")
297
298        sequence_annotation_api_instance = openapi_client.SequenceAnnotationApi(self._inner_api_client)
299
300        try:
301            inner_sequence_templates: list[openapi_client.SequenceAnnotationWorkSequenceTemplatesInner] = []
302            for st in sequence_templates:
303                match st.selector.type:
304                    case "file_id":
305                        inner_sequence_templates.append(
306                            openapi_client.SequenceAnnotationWorkSequenceTemplatesInner(
307                                template_id=st.id,
308                                template_version=st.version,
309                                selector=openapi_client.SequenceTemplateSelector(
310                                    openapi_client.MatchAFileByItsID(type=st.selector.type, value=st.selector.value)
311                                ),
312                            )
313                        )
314                    case _:
315                        assert False, f"Selector type {st.selector.type} should be matched"
316
317            sequence_annotation_work = openapi_client.SequenceAnnotationWork(
318                name=name,
319                file_ids=[UUID(fid) for fid in file_ids],
320                sequence_templates=inner_sequence_templates,
321                reference_database=openapi_client.ReferenceDatabaseIdVersion(
322                    id=str(reference_database_revision.reference_database_id),
323                    version=int(reference_database_revision.reference_database_version),
324                ),
325                quality_control_template=openapi_client.QualityControlTemplateIdOptionalVersion(
326                    id=str(quality_control_template.id), version=int(quality_control_template.version)
327                ),
328                archive_inputs=archive_inputs,
329                clone_id_to_tag_spec=clone_id_extraction.to_api_payload() if clone_id_extraction else None,
330                correction_settings=correction_settings.to_api_payload() if correction_settings else None,
331                mutation_assay_settings=mutation_assay_settings.to_api_payload() if mutation_assay_settings else None,
332                chain_fraction_tag_id=int(chain_fraction_tag_id) if chain_fraction_tag_id is not None else None,
333                liability_check=liability_check,
334                restrict_deduplication_within_file=restrict_deduplication_within_file,
335                should_deduplicate_on_amino_acids=should_deduplicate_on_amino_acids,
336                filename_tag_id=int(filename_tag_id) if filename_tag_id is not None else None,
337                extend_alignment_to_cover_full_vdj=extend_alignment_to_cover_full_vdj,
338            )
339
340            with ApiErrorContext():
341                sequence_annotation_job = sequence_annotation_api_instance.start_sequence_annotation(sequence_annotation_work=sequence_annotation_work)
342                assert sequence_annotation_job.workflow_execution_id is not None
343
344                workflow_execution_id = WorkflowExecutionId(int(sequence_annotation_job.workflow_execution_id))
345
346                def on_complete(task_id: WorkflowExecutionTaskId, task_state: TaskState) -> CollectionMetadata:
347                    assert task_state == TaskState.SUCCEEDED, f"Task {task_id} did not reach {TaskState.SUCCEEDED} state, got {task_state} state instead"
348
349                    get_collection_id_response = sequence_annotation_api_instance.get_sequence_annotation_collection_id_by_workflow_execution_task_id(task_id)
350                    collection_id = get_collection_id_response.collection_id
351                    assert collection_id is not None
352
353                    logger.success(f"Collection with ID `{collection_id}` was successfully obtained by running Sequence Annotation")
354
355                    collection_api = CollectionApi(self._inner_api_client, self._log_level)
356                    return collection_api.get_collection_metadata_by_id(CollectionId(collection_id))
357
358                waitable = WorkflowExecutionTaskWaitable[CollectionMetadata](
359                    workflow_execution_id=workflow_execution_id,
360                    task_template_name=WorkflowTaskTemplateName.ENPI_APP_SEQUENCE_ANNOTATION,
361                    on_complete=on_complete,
362                )
363
364                return Execution(wait=waitable.wait_and_return_result, check_execution_state=waitable.check_execution_state)
365
366        except openapi_client.ApiException as e:
367            raise ApiError(e)

Start Sequence Annotation on raw sequencing data.

A sequence template (available here: enpi_api.l2.client.api.sequence_annotation_api.SequenceAnnotationApi.get_sequence_template_by_name) and a quality control template (enpi_api.l2.client.api.sequence_annotation_api.SequenceAnnotationApi.get_quality_control_template_by_name) are required in order to run a Sequence Annotation task. Templates can be created and configured only via the web interface of ENPICOM-Platform, it can not be done through SDK or API. Additionally, getting familiar with Sequence Annotation in the web interface can help in understanding it and setting up a desired task configuration due to it being more informative than the minimal documentation provided for this function.

Arguments:
Raises:
Returns:

enpi_api.l2.types.execution.Execution[enpi_api.l2.types.collection.CollectionMetadata]: An object that allows you to wait for the execution to finish and get the resulting collection metadata.

Example:

Part of start_sequence_annotation_run.py example script.

# Templates need to be present in the ENPICOM-Platform already
sequence_template_name = "sequence template 1"
quality_control_template_name = "quality control template 1"

sequence_templates = [st for st in client.sequence_annotation_api.get_sequence_templates() if st.name == sequence_template_name]
quality_control_templates = [qct for qct in client.sequence_annotation_api.get_quality_control_templates() if qct.name == quality_control_template_name]

quality_control_template = QualityControlTemplate(quality_control_templates[0])
sequence_template_id = SequenceTemplateId(sequence_templates[0].id)

# Upload the input file
file_path = "data.fq"
file: File = client.file_api.upload_file(file_path=file_path, tags=[]).wait()
file_ids = [file.id]

# Get the reference database revision
reference_database_revision = client.reference_database_api.get_revision_by_name(name=REFERENCE_NAME, species=ORGANISM)

collection_name = "New collection from Sequence Annotation"

# We will now start Sequence Annotation, which will process raw sequencing data into annotated clone collections
clone_collection = client.sequence_annotation_api.start(
    name=collection_name,
    file_ids=file_ids,
    # To assign a sequence template to each input file
    sequence_templates=[
        SequenceTemplateConfig(
            # We select it using a selector, in this case by matching the file_id, but we could also match on file name or tags
            selector=SequenceTemplateSelector(value=f),
            # And then assign it using a sequence template id
            id=sequence_template_id,
        )
        for f in file_ids
    ],
    reference_database_revision=reference_database_revision,
    # Archives the raw sequencing data after they have been processed
    archive_inputs=True,
    quality_control_template=quality_control_template,
).wait()