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