From e05b1dcbc645e125226e9b683bda5465c6664acd Mon Sep 17 00:00:00 2001 From: Henrik Stranneheim Date: Tue, 6 Feb 2024 10:03:35 +0100 Subject: [PATCH] Refactor pipeline functions (#2894) (maajor) ### Changed - refactors `pipeline` into `workflow` for functions and CLI --- CONTRIBUTING.md | 6 +- cg/apps/gt.py | 2 +- cg/apps/hermes/hermes_api.py | 14 +- cg/apps/hermes/models.py | 6 +- cg/cli/clean.py | 16 +- cg/cli/delete/observations.py | 11 +- cg/cli/generate/report/base.py | 16 +- cg/cli/generate/report/options.py | 10 +- cg/cli/generate/report/utils.py | 26 ++-- cg/cli/upload/base.py | 10 +- cg/cli/upload/clinical_delivery.py | 2 +- cg/cli/upload/observations/observations.py | 10 +- cg/cli/upload/observations/utils.py | 4 +- cg/cli/upload/scout.py | 2 +- cg/cli/upload/utils.py | 4 +- cg/cli/workflow/balsamic/base.py | 4 +- cg/cli/workflow/balsamic/qc.py | 4 +- cg/cli/workflow/balsamic/umi.py | 4 +- cg/cli/workflow/commands.py | 16 +- cg/cli/workflow/fastq/base.py | 2 +- cg/cli/workflow/fastq/fastq_service.py | 2 +- cg/cli/workflow/fluffy/base.py | 4 +- cg/cli/workflow/microsalt/base.py | 6 +- cg/cli/workflow/mip/base.py | 2 +- cg/cli/workflow/mutant/base.py | 4 +- cg/cli/workflow/raredisease/base.py | 4 +- cg/cli/workflow/rnafusion/base.py | 8 +- cg/cli/workflow/rnafusion/options.py | 2 +- cg/cli/workflow/taxprofiler/base.py | 8 +- cg/cli/workflow/taxprofiler/options.py | 2 +- cg/constants/housekeeper_tags.py | 2 +- cg/constants/observations.py | 2 +- cg/constants/report.py | 8 +- cg/meta/clean/api.py | 27 ++-- cg/meta/report/balsamic.py | 2 +- cg/meta/report/report_api.py | 40 ++--- cg/meta/report/templates/balsamic_report.html | 12 +- cg/meta/report/templates/mip-dna_report.html | 10 +- .../report/templates/rnafusion_report.html | 10 +- cg/meta/rsync/rsync_api.py | 2 +- cg/meta/upload/gt.py | 14 +- cg/meta/upload/nipt/nipt.py | 2 +- cg/meta/upload/scout/uploadscoutapi.py | 14 +- cg/meta/upload/upload_api.py | 2 +- cg/meta/workflow/analysis.py | 36 ++--- cg/meta/workflow/balsamic.py | 12 +- cg/meta/workflow/balsamic_pon.py | 4 +- cg/meta/workflow/balsamic_qc.py | 4 +- cg/meta/workflow/balsamic_umi.py | 4 +- cg/meta/workflow/fastq.py | 2 +- cg/meta/workflow/fluffy.py | 9 +- cg/meta/workflow/microsalt/microsalt.py | 6 +- cg/meta/workflow/mip.py | 12 +- cg/meta/workflow/mip_dna.py | 8 +- cg/meta/workflow/mip_rna.py | 8 +- cg/meta/workflow/mutant.py | 8 +- cg/meta/workflow/nf_analysis.py | 29 ++-- cg/meta/workflow/nf_handlers.py | 4 +- cg/meta/workflow/prepare_fastq.py | 2 +- cg/meta/workflow/raredisease.py | 4 +- cg/meta/workflow/rnafusion.py | 16 +- cg/meta/workflow/taxprofiler.py | 14 +- cg/models/report/metadata.py | 2 +- cg/models/report/report.py | 30 ++-- cg/models/report/sample.py | 2 +- cg/models/report/validators.py | 2 +- cg/resources/rnafusion_bundle_filenames.csv | 2 +- cg/server/api.py | 8 +- cg/store/base.py | 8 +- cg/store/crud/create.py | 8 +- cg/store/crud/read.py | 143 ++++++++---------- cg/store/filters/status_analysis_filters.py | 28 ++-- .../status_application_limitations_filters.py | 14 +- cg/store/filters/status_case_filters.py | 48 +++--- cg/store/models.py | 8 +- tests/cli/clean/conftest.py | 8 +- tests/cli/clean/test_balsamic_clean.py | 4 +- tests/cli/clean/test_hk_bundle_files.py | 6 +- tests/cli/clean/test_hk_case_bundle_files.py | 10 +- tests/cli/clean/test_microbial_clean.py | 8 +- tests/cli/generate/report/conftest.py | 4 +- tests/cli/generate/report/test_utils.py | 12 +- tests/cli/upload/conftest.py | 2 +- tests/cli/upload/test_cli_scout.py | 4 +- tests/cli/upload/test_cli_upload.py | 2 +- tests/cli/upload/test_cli_upload_auto.py | 6 +- tests/cli/upload/test_cli_upload_nipt.py | 6 +- tests/cli/workflow/balsamic/conftest.py | 4 +- .../balsamic/test_compound_commands.py | 10 +- .../balsamic/test_store_housekeeper.py | 2 +- .../test_cli_rnafusion_store_housekeeper.py | 6 +- tests/conftest.py | 4 +- tests/meta/report/conftest.py | 8 +- tests/meta/report/test_report_api.py | 6 +- tests/meta/upload/conftest.py | 10 +- tests/meta/upload/scout/conftest.py | 12 +- .../upload/scout/test_generate_load_config.py | 10 +- .../scout/test_meta_upload_scoutapi_rna.py | 4 +- .../meta/upload/test_upload_genotypes_api.py | 2 +- tests/meta/workflow/test_nf_analysis.py | 2 +- tests/models/report/test_validators.py | 4 +- tests/store/api/conftest.py | 4 +- tests/store/conftest.py | 12 +- tests/store/crud/conftest.py | 12 +- tests/store/crud/read/test_read.py | 44 +++--- .../crud/read/test_read_analyses_to_clean.py | 26 ++-- .../test_read_analyses_to_delivery_report.py | 20 +-- tests/store/crud/read/test_read_analysis.py | 68 ++++----- tests/store/crud/read/test_read_case.py | 42 ++--- .../filters/test_status_analyses_filters.py | 34 ++--- ..._status_application_limitations_filters.py | 12 +- .../filters/test_status_cases_filters.py | 78 +++++----- tests/store_helpers.py | 25 ++- tests/utils/test_dispatcher.py | 16 +- 114 files changed, 670 insertions(+), 722 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 78c45a2aca..8fa4ec1a47 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -168,11 +168,11 @@ We convert all the info that we get from LIMS/`genologics` to dictionaries befor Interface to Trailblazer. -- Monitor analysis pipeline status +- Monitor analysis workflow status #### Genotype (gt) -Interface to Genotype. For uploading results from the pipeline about genotypes to compare and validate that we are clear of sample mix-ups. +Interface to Genotype. For uploading results from the workflow about genotypes to compare and validate that we are clear of sample mix-ups. #### Housekeeper (hk) @@ -188,7 +188,7 @@ Internal app for opening tickets in SupportSystems. We use this mainly to link a #### Scout (scoutapi) -Interface to Scout. For uploading analysis results to Scout. It's also used to access the generation of gene panels files used in the analysis pipeline. +Interface to Scout. For uploading analysis results to Scout. It's also used to access the generation of gene panels files used in the analysis workflow. #### Delivery report diff --git a/cg/apps/gt.py b/cg/apps/gt.py index 12c10308d2..1edd5035cb 100644 --- a/cg/apps/gt.py +++ b/cg/apps/gt.py @@ -39,7 +39,7 @@ def upload(self, bcf_path: str, samples_sex: dict, force: bool = False) -> None: # This is the sample sex specified by the customer sample_sex = samples_sex[sample_id]["pedigree"] self.update_sample_sex(sample_id, sample_sex) - # This is the predicted sex based on variant calls from the pipeline + # This is the predicted sex based on variant calls from the workflow analysis_predicted_sex = samples_sex[sample_id]["analysis"] self.update_analysis_sex(sample_id, sex=analysis_predicted_sex) diff --git a/cg/apps/hermes/hermes_api.py b/cg/apps/hermes/hermes_api.py index 395ebc57db..e8249e0bda 100644 --- a/cg/apps/hermes/hermes_api.py +++ b/cg/apps/hermes/hermes_api.py @@ -17,15 +17,15 @@ def __init__(self, config: dict): self.process = Process(binary=config["hermes"]["binary_path"]) def convert_deliverables( - self, deliverables_file: Path, pipeline: str, analysis_type: str | None = None + self, deliverables_file: Path, workflow: str, analysis_type: str | None = None ) -> CGDeliverables: - """Convert deliverables file in raw pipeline format to CG format with hermes""" - LOG.info("Converting pipeline deliverables to CG deliverables") + """Convert deliverables file in raw workflow format to CG format with hermes""" + LOG.info("Converting workflow deliverables to CG deliverables") convert_command = [ "convert", "deliverables", "--pipeline", - pipeline, + workflow, str(deliverables_file), ] if analysis_type: @@ -38,13 +38,13 @@ def create_housekeeper_bundle( self, bundle_name: str, deliverables: Path, - pipeline: str, + workflow: str, analysis_type: str | None, created: datetime | None, ) -> hk_models.InputBundle: - """Convert pipeline deliverables to housekeeper bundle ready to be inserted into hk""" + """Convert workflow deliverables to a Housekeeper bundle ready to be inserted into Housekeeper.""" cg_deliverables: CGDeliverables = self.convert_deliverables( - deliverables_file=deliverables, pipeline=pipeline, analysis_type=analysis_type + deliverables_file=deliverables, workflow=workflow, analysis_type=analysis_type ) return self.get_housekeeper_bundle( deliverables=cg_deliverables, created=created, bundle_name=bundle_name diff --git a/cg/apps/hermes/models.py b/cg/apps/hermes/models.py index d18b5961fb..17a3f5960f 100644 --- a/cg/apps/hermes/models.py +++ b/cg/apps/hermes/models.py @@ -19,9 +19,9 @@ class CGTag(BaseModel): class CGDeliverables(BaseModel): - """Class that specifies the output from hermes""" + """Class that specifies the output from Hermes.""" - pipeline: str + workflow: str bundle_id: str files: list[CGTag] @@ -29,7 +29,7 @@ class CGDeliverables(BaseModel): @classmethod def remove_missing_files(cls, files: list[CGTag]) -> list[CGTag]: """Validates that the files in a suggested CGDeliverables object are correct. - I.e. if a file doesn't exist an error is raised if the file was mandatory, + I.e., if a file doesn't exist, an error is raised if the file was mandatory, otherwise it is simply removed from the list of files.""" filtered_files: list[CGTag] = files.copy() for file in files: diff --git a/cg/cli/clean.py b/cg/cli/clean.py index cd3935b31a..900da98d6a 100644 --- a/cg/cli/clean.py +++ b/cg/cli/clean.py @@ -146,7 +146,7 @@ def scout_finished_cases( @DRY_RUN @click.pass_context def hk_case_bundle_files(context: CGConfig, days_old: int, dry_run: bool = False) -> None: - """Clean up all non-protected files for all pipelines.""" + """Clean up all non-protected files for all workflows.""" housekeeper_api: HousekeeperAPI = context.obj.housekeeper_api clean_api: CleanAPI = CleanAPI(status_db=context.obj.status_db, housekeeper_api=housekeeper_api) @@ -172,7 +172,7 @@ def hk_case_bundle_files(context: CGConfig, days_old: int, dry_run: bool = False @clean.command("hk-bundle-files") @click.option("-c", "--case-id", type=str, required=False) -@click.option("-p", "--pipeline", type=Workflow, required=False) +@click.option("-w", "--workflow", type=Workflow, required=False) @click.option("-t", "--tags", multiple=True, required=True) @click.option("-o", "--days-old", type=int, default=30) @DRY_RUN @@ -182,7 +182,7 @@ def hk_bundle_files( case_id: str | None, tags: list, days_old: int | None, - pipeline: Workflow | None, + workflow: Workflow | None, dry_run: bool, ): """Remove files found in Housekeeper bundles.""" @@ -195,13 +195,13 @@ def hk_bundle_files( function_dispatcher: Dispatcher = Dispatcher( functions=[ status_db.get_analyses_started_at_before, - status_db.get_analyses_for_case_and_pipeline_started_at_before, - status_db.get_analyses_for_pipeline_started_at_before, + status_db.get_analyses_for_case_and_workflow_started_at_before, + status_db.get_analyses_for_workflow_started_at_before, status_db.get_analyses_for_case_started_at_before, ], input_dict={ "case_internal_id": case_id, - "pipeline": pipeline, + "workflow": workflow, "started_at_before": date_threshold, }, ) @@ -218,7 +218,7 @@ def hk_bundle_files( LOG.warning( f"Version not found for " f"bundle:{bundle_name}; " - f"pipeline: {analysis.pipeline}; " + f"workflow: {analysis.pipeline}; " f"date {analysis.started_at}" ) continue @@ -226,7 +226,7 @@ def hk_bundle_files( LOG.info( f"Version found for " f"bundle:{bundle_name}; " - f"pipeline: {analysis.pipeline}; " + f"workflow: {analysis.pipeline}; " f"date {analysis.started_at}" ) version_files: list[File] = housekeeper_api.get_files( diff --git a/cg/cli/delete/observations.py b/cg/cli/delete/observations.py index a93b0d334c..ac9e3bc4ec 100644 --- a/cg/cli/delete/observations.py +++ b/cg/cli/delete/observations.py @@ -6,10 +6,7 @@ from sqlalchemy.orm import Query from cg.cli.upload.observations.utils import get_observations_api, get_observations_case -from cg.cli.workflow.commands import ( - ARGUMENT_CASE_ID, - OPTION_LOQUSDB_SUPPORTED_PIPELINES, -) +from cg.cli.workflow.commands import ARGUMENT_CASE_ID, OPTION_LOQUSDB_SUPPORTED_WORKFLOW from cg.constants.constants import DRY_RUN, SKIP_CONFIRMATION, Workflow from cg.exc import CaseNotFoundError, LoqusdbError from cg.meta.observations.balsamic_observations_api import BalsamicObservationsAPI @@ -44,17 +41,17 @@ def delete_observations(context: CGConfig, case_id: str, dry_run: bool, yes: boo @click.command("available-observations") -@OPTION_LOQUSDB_SUPPORTED_PIPELINES +@OPTION_LOQUSDB_SUPPORTED_WORKFLOW @SKIP_CONFIRMATION @DRY_RUN @click.pass_context def delete_available_observations( - context: click.Context, pipeline: Workflow | None, dry_run: bool, yes: bool + context: click.Context, workflow: Workflow | None, dry_run: bool, yes: bool ): """Delete available observation from Loqusdb.""" status_db: Store = context.obj.status_db - uploaded_observations: Query = status_db.observations_uploaded(pipeline) + uploaded_observations: Query = status_db.observations_uploaded(workflow) LOG.info( f"This would delete observations for the following cases: {[case.internal_id for case in uploaded_observations]}" diff --git a/cg/cli/generate/report/base.py b/cg/cli/generate/report/base.py index b09dcfe985..0d16ed38b6 100644 --- a/cg/cli/generate/report/base.py +++ b/cg/cli/generate/report/base.py @@ -12,13 +12,13 @@ ARGUMENT_CASE_ID, OPTION_DRY_RUN, OPTION_FORCE_REPORT, - OPTION_PIPELINE, OPTION_STARTED_AT, + OPTION_WORKFLOW, ) from cg.cli.generate.report.utils import ( get_report_analysis_started, get_report_api, - get_report_api_pipeline, + get_report_api_workflow, get_report_case, ) from cg.constants import EXIT_FAIL, EXIT_SUCCESS, Workflow @@ -85,23 +85,23 @@ def generate_delivery_report( @click.command("available-delivery-reports") -@OPTION_PIPELINE +@OPTION_WORKFLOW @OPTION_FORCE_REPORT @OPTION_DRY_RUN @click.pass_context def generate_available_delivery_reports( - context: click.Context, pipeline: Workflow, force_report: bool, dry_run: bool + context: click.Context, workflow: Workflow, force_report: bool, dry_run: bool ) -> None: - """Generates delivery reports for all cases that need one and stores them in housekeeper.""" + """Generates delivery reports for all cases that need one and stores them in Housekeeper.""" click.echo(click.style("--------------- AVAILABLE DELIVERY REPORTS ---------------")) exit_code = EXIT_SUCCESS - report_api: ReportAPI = get_report_api_pipeline(context, pipeline) - context.obj.meta_apis["report_api"] = report_api if pipeline else None + report_api: ReportAPI = get_report_api_workflow(context=context, workflow=workflow) + context.obj.meta_apis["report_api"] = report_api if workflow else None - cases_without_delivery_report = report_api.get_cases_without_delivery_report(pipeline) + cases_without_delivery_report = report_api.get_cases_without_delivery_report(workflow) if not cases_without_delivery_report: click.echo( click.style( diff --git a/cg/cli/generate/report/options.py b/cg/cli/generate/report/options.py index ea0b14988e..f7fe3bcf05 100644 --- a/cg/cli/generate/report/options.py +++ b/cg/cli/generate/report/options.py @@ -2,7 +2,7 @@ import click -from cg.constants import REPORT_SUPPORTED_PIPELINES +from cg.constants import REPORT_SUPPORTED_WORKFLOW ARGUMENT_CASE_ID = click.argument( "case_id", @@ -10,10 +10,10 @@ type=str, ) -OPTION_PIPELINE = click.option( - "--pipeline", - type=click.Choice(REPORT_SUPPORTED_PIPELINES), - help="Limit delivery report generation to a specific pipeline", +OPTION_WORKFLOW = click.option( + "--workflow", + type=click.Choice(REPORT_SUPPORTED_WORKFLOW), + help="Limit delivery report generation to a specific workflow", ) OPTION_STARTED_AT = click.option( diff --git a/cg/cli/generate/report/utils.py b/cg/cli/generate/report/utils.py index 6272183d17..e5a9d16c3f 100644 --- a/cg/cli/generate/report/utils.py +++ b/cg/cli/generate/report/utils.py @@ -7,7 +7,7 @@ from cg.constants import ( REPORT_SUPPORTED_DATA_DELIVERY, - REPORT_SUPPORTED_PIPELINES, + REPORT_SUPPORTED_WORKFLOW, Workflow, ) from cg.meta.report.balsamic import BalsamicReportAPI @@ -38,13 +38,13 @@ def get_report_case(context: click.Context, case_id: str) -> Case: # Missing or not valid internal case ID if not case_id or not case: LOG.warning("Invalid case ID. Retrieving available cases.") - pipeline: Workflow = ( - report_api.analysis_api.pipeline if context.obj.meta_apis.get("report_api") else None + workflow: Workflow = ( + report_api.analysis_api.workflow if context.obj.meta_apis.get("report_api") else None ) cases_without_delivery_report: list[Case] = ( - report_api.get_cases_without_delivery_report(pipeline=pipeline) + report_api.get_cases_without_delivery_report(workflow=workflow) if not context.obj.meta_apis.get("upload_api") - else report_api.get_cases_without_uploaded_delivery_report(pipeline=pipeline) + else report_api.get_cases_without_uploaded_delivery_report(workflow=workflow) ) if not cases_without_delivery_report: click.echo( @@ -57,9 +57,9 @@ def get_report_case(context: click.Context, case_id: str) -> Case: for case in cases_without_delivery_report: click.echo(f"{case.internal_id} ({case.data_analysis})") raise click.Abort - if case.data_analysis not in REPORT_SUPPORTED_PIPELINES: + if case.data_analysis not in REPORT_SUPPORTED_WORKFLOW: LOG.error( - f"The {case.data_analysis} pipeline does not support delivery reports (case: {case.internal_id})" + f"The {case.data_analysis} workflow does not support delivery reports (case: {case.internal_id})" ) raise click.Abort if case.data_delivery not in REPORT_SUPPORTED_DATA_DELIVERY: @@ -74,13 +74,13 @@ def get_report_api(context: click.Context, case: Case) -> ReportAPI: """Returns a report API to be used for the delivery report generation.""" if context.obj.meta_apis.get("report_api"): return context.obj.meta_apis.get("report_api") - return get_report_api_pipeline(context, case.data_analysis) + return get_report_api_workflow(context, case.data_analysis) -def get_report_api_pipeline(context: click.Context, pipeline: Workflow) -> ReportAPI: - """Resolves the report API given a specific pipeline.""" - # Default report API pipeline: MIP-DNA - pipeline: Workflow = pipeline if pipeline else Workflow.MIP_DNA +def get_report_api_workflow(context: click.Context, workflow: Workflow) -> ReportAPI: + """Return the report API given a specific workflow.""" + # Default report API workflow: MIP-DNA + workflow: Workflow = workflow if workflow else Workflow.MIP_DNA dispatch_report_api: dict[Workflow, ReportAPI] = { Workflow.BALSAMIC: BalsamicReportAPI( config=context.obj, analysis_api=BalsamicAnalysisAPI(config=context.obj) @@ -98,7 +98,7 @@ def get_report_api_pipeline(context: click.Context, pipeline: Workflow) -> Repor config=context.obj, analysis_api=RnafusionAnalysisAPI(config=context.obj) ), } - return dispatch_report_api.get(pipeline) + return dispatch_report_api.get(workflow) def get_report_analysis_started( diff --git a/cg/cli/upload/base.py b/cg/cli/upload/base.py index 69c7022bfa..99ec356174 100644 --- a/cg/cli/upload/base.py +++ b/cg/cli/upload/base.py @@ -92,21 +92,21 @@ def upload(context: click.Context, case_id: str | None, restart: bool): @upload.command("auto") -@click.option("--pipeline", type=EnumChoice(Workflow), help="Limit to specific pipeline") +@click.option("--workflow", type=EnumChoice(Workflow), help="Limit to specific workflow") @click.pass_context -def upload_all_completed_analyses(context: click.Context, pipeline: Workflow = None): - """Upload all completed analyses""" +def upload_all_completed_analyses(context: click.Context, workflow: Workflow = None): + """Upload all completed analyses.""" LOG.info("----------------- AUTO -----------------") status_db: Store = context.obj.status_db exit_code = 0 - for analysis_obj in status_db.get_analyses_to_upload(pipeline=pipeline): + for analysis_obj in status_db.get_analyses_to_upload(workflow=workflow): if analysis_obj.case.analyses[0].uploaded_at is not None: LOG.warning( f"Skipping upload for case {analysis_obj.case.internal_id}. " - f"It has been already uploaded at {analysis_obj.case.analyses[0].uploaded_at}." + f"Case has been already uploaded at {analysis_obj.case.analyses[0].uploaded_at}." ) continue diff --git a/cg/cli/upload/clinical_delivery.py b/cg/cli/upload/clinical_delivery.py index 2e9c108be0..6f4ba0e50e 100644 --- a/cg/cli/upload/clinical_delivery.py +++ b/cg/cli/upload/clinical_delivery.py @@ -89,7 +89,7 @@ def auto_fastq(context: click.Context, dry_run: bool): exit_code: int = EXIT_SUCCESS status_db: Store = context.obj.status_db trailblazer_api: TrailblazerAPI = context.obj.trailblazer_api - for analysis_obj in status_db.get_analyses_to_upload(pipeline=Workflow.FASTQ): + for analysis_obj in status_db.get_analyses_to_upload(workflow=Workflow.FASTQ): if analysis_obj.case.analyses[0].uploaded_at: LOG.debug( f"Newer analysis already uploaded for {analysis_obj.case.internal_id}, skipping" diff --git a/cg/cli/upload/observations/observations.py b/cg/cli/upload/observations/observations.py index 460de4f7ff..39d941698b 100644 --- a/cg/cli/upload/observations/observations.py +++ b/cg/cli/upload/observations/observations.py @@ -15,7 +15,7 @@ from cg.cli.workflow.commands import ( ARGUMENT_CASE_ID, OPTION_DRY, - OPTION_LOQUSDB_SUPPORTED_PIPELINES, + OPTION_LOQUSDB_SUPPORTED_WORKFLOW, ) from cg.constants.constants import Workflow from cg.exc import CaseNotFoundError, LoqusdbError @@ -51,21 +51,21 @@ def upload_observations_to_loqusdb(context: CGConfig, case_id: str | None, dry_r @click.command("available-observations") -@OPTION_LOQUSDB_SUPPORTED_PIPELINES +@OPTION_LOQUSDB_SUPPORTED_WORKFLOW @OPTION_DRY @click.pass_context def upload_available_observations_to_loqusdb( - context: click.Context, pipeline: Workflow | None, dry_run: bool + context: click.Context, workflow: Workflow | None, dry_run: bool ): """Uploads the available observations to Loqusdb.""" click.echo(click.style("----------------- AVAILABLE OBSERVATIONS -----------------")) status_db: Store = context.obj.status_db - cases_to_upload: Query = status_db.observations_to_upload(pipeline=pipeline) + cases_to_upload: Query = status_db.observations_to_upload(workflow=workflow) if not cases_to_upload: LOG.error( - f"There are no available cases to upload to Loqusdb for {pipeline} ({datetime.now()})" + f"There are no available cases to upload to Loqusdb for {workflow} ({datetime.now()})" ) return diff --git a/cg/cli/upload/observations/utils.py b/cg/cli/upload/observations/utils.py index 0540d1ef29..ec340e19de 100644 --- a/cg/cli/upload/observations/utils.py +++ b/cg/cli/upload/observations/utils.py @@ -5,7 +5,7 @@ from sqlalchemy.orm import Query from cg.constants.constants import Workflow -from cg.constants.observations import LOQUSDB_SUPPORTED_PIPELINES +from cg.constants.observations import LOQUSDB_SUPPORTED_WORKFLOWS from cg.constants.sequencing import SequencingMethod from cg.exc import CaseNotFoundError, LoqusdbUploadCaseError from cg.meta.observations.balsamic_observations_api import BalsamicObservationsAPI @@ -21,7 +21,7 @@ def get_observations_case(context: CGConfig, case_id: str, upload: bool) -> Case """Return a verified Loqusdb case.""" status_db: Store = context.status_db case: Case = status_db.get_case_by_internal_id(internal_id=case_id) - if not case or case.data_analysis not in LOQUSDB_SUPPORTED_PIPELINES: + if not case or case.data_analysis not in LOQUSDB_SUPPORTED_WORKFLOWS: LOG.error("Invalid case ID. Retrieving available cases for Loqusdb actions.") cases_to_process: Query = ( status_db.observations_to_upload() if upload else status_db.observations_uploaded() diff --git a/cg/cli/upload/scout.py b/cg/cli/upload/scout.py index 05d49f5dcc..eb4df18827 100644 --- a/cg/cli/upload/scout.py +++ b/cg/cli/upload/scout.py @@ -216,7 +216,7 @@ def upload_multiqc_to_scout(context: CGConfig, case_id: str, dry_run: bool) -> N status_db: Store = context.status_db case: Case = status_db.get_case_by_internal_id(internal_id=case_id) scout_report_type, multiqc_report = scout_upload_api.get_multiqc_html_report( - case_id=case_id, pipeline=case.data_analysis + case_id=case_id, workflow=case.data_analysis ) if scout_report_type == ScoutCustomCaseReportTags.MULTIQC_RNA: scout_upload_api.upload_rna_report_to_dna_case_in_scout( diff --git a/cg/cli/upload/utils.py b/cg/cli/upload/utils.py index 3af9502751..5276b47475 100644 --- a/cg/cli/upload/utils.py +++ b/cg/cli/upload/utils.py @@ -12,10 +12,10 @@ LOG = logging.getLogger(__name__) -def suggest_cases_to_upload(status_db: Store, pipeline: Workflow | None = None) -> None: +def suggest_cases_to_upload(status_db: Store, workflow: Workflow | None = None) -> None: """Print a list of suggested cases to upload.""" LOG.warning("Provide a case, suggestions:") - records: list[Analysis] = status_db.get_analyses_to_upload(pipeline=pipeline)[ + records: list[Analysis] = status_db.get_analyses_to_upload(workflow=workflow)[ :MAX_ITEMS_TO_RETRIEVE ] for case_obj in records: diff --git a/cg/cli/workflow/balsamic/base.py b/cg/cli/workflow/balsamic/base.py index 1cd6873519..88a131eb6a 100644 --- a/cg/cli/workflow/balsamic/base.py +++ b/cg/cli/workflow/balsamic/base.py @@ -34,9 +34,7 @@ def balsamic(context: click.Context): AnalysisAPI.get_help(context) config = context.obj - context.obj.meta_apis["analysis_api"] = BalsamicAnalysisAPI( - config=config, - ) + context.obj.meta_apis["analysis_api"] = BalsamicAnalysisAPI(config=config) balsamic.add_command(resolve_compression) diff --git a/cg/cli/workflow/balsamic/qc.py b/cg/cli/workflow/balsamic/qc.py index f76b608169..7710cc1c1c 100644 --- a/cg/cli/workflow/balsamic/qc.py +++ b/cg/cli/workflow/balsamic/qc.py @@ -28,9 +28,7 @@ def balsamic_qc(context: click.Context): click.echo(context.get_help()) return None config = context.obj - context.obj.meta_apis["analysis_api"] = BalsamicQCAnalysisAPI( - config=config, - ) + context.obj.meta_apis["analysis_api"] = BalsamicQCAnalysisAPI(config=config) balsamic_qc.add_command(resolve_compression) diff --git a/cg/cli/workflow/balsamic/umi.py b/cg/cli/workflow/balsamic/umi.py index fbaba8f8e1..f881d0b535 100644 --- a/cg/cli/workflow/balsamic/umi.py +++ b/cg/cli/workflow/balsamic/umi.py @@ -28,9 +28,7 @@ def balsamic_umi(context: click.Context): click.echo(context.get_help()) return None config = context.obj - context.obj.meta_apis["analysis_api"] = BalsamicUmiAnalysisAPI( - config=config, - ) + context.obj.meta_apis["analysis_api"] = BalsamicUmiAnalysisAPI(config=config) balsamic_umi.add_command(resolve_compression) diff --git a/cg/cli/workflow/commands.py b/cg/cli/workflow/commands.py index f216d3d8a9..7a8bc5f157 100644 --- a/cg/cli/workflow/commands.py +++ b/cg/cli/workflow/commands.py @@ -8,7 +8,7 @@ from cg.apps.housekeeper.hk import HousekeeperAPI from cg.constants import EXIT_FAIL, EXIT_SUCCESS -from cg.constants.observations import LOQUSDB_SUPPORTED_PIPELINES +from cg.constants.observations import LOQUSDB_SUPPORTED_WORKFLOWS from cg.exc import FlowCellsNeededError from cg.meta.rsync import RsyncAPI from cg.meta.workflow.analysis import AnalysisAPI @@ -34,10 +34,10 @@ OPTION_ANALYSIS_PARAMETERS_CONFIG = click.option( "--config-artic", type=str, help="Config with computational and lab related settings" ) -OPTION_LOQUSDB_SUPPORTED_PIPELINES = click.option( - "--pipeline", - type=click.Choice(LOQUSDB_SUPPORTED_PIPELINES), - help="Limit observations upload to a specific pipeline", +OPTION_LOQUSDB_SUPPORTED_WORKFLOW = click.option( + "--workflow", + type=click.Choice(LOQUSDB_SUPPORTED_WORKFLOWS), + help="Limit observations upload to a specific workflow", ) LOG = logging.getLogger(__name__) @@ -47,7 +47,7 @@ @ARGUMENT_CASE_ID @click.pass_obj def ensure_flow_cells_on_disk(context: CGConfig, case_id: str): - """Check if flow cells are on disk for given case. If not, request flow cells and raise FlowcellsNeededError.""" + """Check if flow cells are on disk for a given case. If not, request flow cells and raise FlowcellsNeededError.""" analysis_api: AnalysisAPI = context.meta_apis["analysis_api"] status_db: Store = context.status_db analysis_api.status_db.verify_case_exists(case_internal_id=case_id) @@ -199,7 +199,7 @@ def past_run_dirs( for analysis in possible_cleanups: case_id = analysis.case.internal_id try: - LOG.info(f"Cleaning {analysis_api.pipeline} output for {case_id}") + LOG.info(f"Cleaning {analysis_api.workflow} output for {case_id}") context.invoke(clean_run_dir, yes=yes, case_id=case_id, dry_run=dry_run) except FileNotFoundError: continue @@ -209,7 +209,7 @@ def past_run_dirs( if exit_code: raise click.Abort - LOG.info(f"Done cleaning {analysis_api.pipeline} output") + LOG.info(f"Done cleaning {analysis_api.workflow} output") @click.command("balsamic-past-run-dirs") diff --git a/cg/cli/workflow/fastq/base.py b/cg/cli/workflow/fastq/base.py index 45972d5762..254ef9e7b5 100644 --- a/cg/cli/workflow/fastq/base.py +++ b/cg/cli/workflow/fastq/base.py @@ -41,5 +41,5 @@ def store_fastq_analysis(context: click.Context, case_id: str, dry_run: bool = F def store_available_fastq_analysis(context: click.Context, dry_run: bool = False): """Creates an analysis object in status-db for all fastq cases to be delivered""" status_db: Store = context.obj.status_db - for case in status_db.cases_to_analyze(pipeline=Workflow.FASTQ, threshold=False): + for case in status_db.cases_to_analyze(workflow=Workflow.FASTQ, threshold=False): context.invoke(store_fastq_analysis, case_id=case.internal_id, dry_run=dry_run) diff --git a/cg/cli/workflow/fastq/fastq_service.py b/cg/cli/workflow/fastq/fastq_service.py index c2075ab497..e6daa94603 100644 --- a/cg/cli/workflow/fastq/fastq_service.py +++ b/cg/cli/workflow/fastq/fastq_service.py @@ -25,7 +25,7 @@ def _get_case(self, case_id: str) -> Case: def _add_analysis_to_store(self, case: Case) -> None: new_analysis: Analysis = self.store.add_analysis( - pipeline=Workflow.FASTQ, + workflow=Workflow.FASTQ, completed_at=dt.datetime.now(), primary=True, started_at=dt.datetime.now(), diff --git a/cg/cli/workflow/fluffy/base.py b/cg/cli/workflow/fluffy/base.py index 6695419d42..1b9a44d991 100644 --- a/cg/cli/workflow/fluffy/base.py +++ b/cg/cli/workflow/fluffy/base.py @@ -25,9 +25,7 @@ def fluffy(context: click.Context): Fluffy workflow """ AnalysisAPI.get_help(context) - context.obj.meta_apis["analysis_api"] = FluffyAnalysisAPI( - config=context.obj, - ) + context.obj.meta_apis["analysis_api"] = FluffyAnalysisAPI(config=context.obj) fluffy.add_command(link) diff --git a/cg/cli/workflow/microsalt/base.py b/cg/cli/workflow/microsalt/base.py index 2ae4053bc8..90d5d581e2 100644 --- a/cg/cli/workflow/microsalt/base.py +++ b/cg/cli/workflow/microsalt/base.py @@ -14,7 +14,7 @@ from cg.meta.workflow.analysis import AnalysisAPI from cg.meta.workflow.microsalt import MicrosaltAnalysisAPI from cg.models.cg_config import CGConfig -from cg.store.models import Case, Sample +from cg.store.models import Sample LOG = logging.getLogger(__name__) @@ -44,9 +44,7 @@ def microsalt(context: click.Context) -> None: """Microbial workflow""" AnalysisAPI.get_help(context) - context.obj.meta_apis["analysis_api"] = MicrosaltAnalysisAPI( - config=context.obj, - ) + context.obj.meta_apis["analysis_api"] = MicrosaltAnalysisAPI(config=context.obj) microsalt.add_command(store) diff --git a/cg/cli/workflow/mip/base.py b/cg/cli/workflow/mip/base.py index 4ed2f3bf42..004738bb1c 100644 --- a/cg/cli/workflow/mip/base.py +++ b/cg/cli/workflow/mip/base.py @@ -141,7 +141,7 @@ def run( try: analysis_api.add_pending_trailblazer_analysis(case_id=case_id) analysis_api.set_statusdb_action(case_id=case_id, action="running") - LOG.info(f"{analysis_api.pipeline} run started!") + LOG.info(f"{analysis_api.workflow} run started!") except CgError as error: LOG.error(error) raise click.Abort diff --git a/cg/cli/workflow/mutant/base.py b/cg/cli/workflow/mutant/base.py index 8fa318e3f1..480b5b56f7 100644 --- a/cg/cli/workflow/mutant/base.py +++ b/cg/cli/workflow/mutant/base.py @@ -25,9 +25,7 @@ def mutant(context: click.Context) -> None: """Mutant analysis workflow""" AnalysisAPI.get_help(context) - context.obj.meta_apis["analysis_api"] = MutantAnalysisAPI( - config=context.obj, - ) + context.obj.meta_apis["analysis_api"] = MutantAnalysisAPI(config=context.obj) mutant.add_command(resolve_compression) diff --git a/cg/cli/workflow/raredisease/base.py b/cg/cli/workflow/raredisease/base.py index c1f1d38c42..d94b9dbc1c 100644 --- a/cg/cli/workflow/raredisease/base.py +++ b/cg/cli/workflow/raredisease/base.py @@ -19,9 +19,7 @@ def raredisease(context: click.Context) -> None: """NF-core/raredisease analysis workflow.""" AnalysisAPI.get_help(context) - context.obj.meta_apis[MetaApis.ANALYSIS_API] = RarediseaseAnalysisAPI( - config=context.obj, - ) + context.obj.meta_apis[MetaApis.ANALYSIS_API] = RarediseaseAnalysisAPI(config=context.obj) @raredisease.command("panel") diff --git a/cg/cli/workflow/rnafusion/base.py b/cg/cli/workflow/rnafusion/base.py index b42ada3f2a..bbfc71a051 100644 --- a/cg/cli/workflow/rnafusion/base.py +++ b/cg/cli/workflow/rnafusion/base.py @@ -42,9 +42,7 @@ def rnafusion(context: click.Context) -> None: """nf-core/rnafusion analysis workflow.""" AnalysisAPI.get_help(context) - context.obj.meta_apis[MetaApis.ANALYSIS_API] = RnafusionAnalysisAPI( - config=context.obj, - ) + context.obj.meta_apis[MetaApis.ANALYSIS_API] = RnafusionAnalysisAPI(config=context.obj) rnafusion.add_command(resolve_compression) @@ -108,9 +106,7 @@ def run( command_args: CommandArgs = CommandArgs( **{ "log": analysis_api.get_log_path( - case_id=case_id, - pipeline=analysis_api.pipeline, - log=log, + case_id=case_id, workflow=analysis_api.workflow, log=log ), "work_dir": analysis_api.get_workdir_path(case_id=case_id, work_dir=work_dir), "resume": not from_start, diff --git a/cg/cli/workflow/rnafusion/options.py b/cg/cli/workflow/rnafusion/options.py index 41564dfc08..05beab3ad3 100644 --- a/cg/cli/workflow/rnafusion/options.py +++ b/cg/cli/workflow/rnafusion/options.py @@ -7,7 +7,7 @@ is_flag=True, default=False, show_default=True, - help="Start pipeline from start without resuming execution", + help="Start workflow from start without resuming execution", ) OPTION_STRANDEDNESS = click.option( diff --git a/cg/cli/workflow/taxprofiler/base.py b/cg/cli/workflow/taxprofiler/base.py index 19cac206cd..ecdc7436c9 100644 --- a/cg/cli/workflow/taxprofiler/base.py +++ b/cg/cli/workflow/taxprofiler/base.py @@ -40,9 +40,7 @@ def taxprofiler(context: click.Context) -> None: """nf-core/taxprofiler analysis workflow.""" AnalysisAPI.get_help(context) - context.obj.meta_apis[MetaApis.ANALYSIS_API] = TaxprofilerAnalysisAPI( - config=context.obj, - ) + context.obj.meta_apis[MetaApis.ANALYSIS_API] = TaxprofilerAnalysisAPI(config=context.obj) taxprofiler.add_command(resolve_compression) @@ -106,9 +104,7 @@ def run( command_args: CommandArgs = CommandArgs( **{ "log": analysis_api.get_log_path( - case_id=case_id, - pipeline=analysis_api.pipeline, - log=log, + case_id=case_id, workflow=analysis_api.workflow, log=log ), "work_dir": analysis_api.get_workdir_path(case_id=case_id, work_dir=work_dir), "resume": not from_start, diff --git a/cg/cli/workflow/taxprofiler/options.py b/cg/cli/workflow/taxprofiler/options.py index 5774a2589f..b9a1c04243 100644 --- a/cg/cli/workflow/taxprofiler/options.py +++ b/cg/cli/workflow/taxprofiler/options.py @@ -7,7 +7,7 @@ is_flag=True, default=False, show_default=True, - help="Start pipeline from the start", + help="Start workflow from the start", ) OPTION_INSTRUMENT_PLATFORM = click.option( diff --git a/cg/constants/housekeeper_tags.py b/cg/constants/housekeeper_tags.py index 36d43e2578..410f66c520 100644 --- a/cg/constants/housekeeper_tags.py +++ b/cg/constants/housekeeper_tags.py @@ -87,7 +87,7 @@ class GensAnalysisTag: class BalsamicProtectedTags: - """Balsamic pipeline protected tags by type.""" + """Balsamic workflow protected tags by type.""" QC: list[list[str]] = [ ["balsamic-config"], diff --git a/cg/constants/observations.py b/cg/constants/observations.py index 5e0d97832e..d68b28d0a2 100644 --- a/cg/constants/observations.py +++ b/cg/constants/observations.py @@ -6,7 +6,7 @@ from cg.constants.sequencing import SequencingMethod LOQUSDB_ID = "_id" -LOQUSDB_SUPPORTED_PIPELINES = [Workflow.MIP_DNA, Workflow.BALSAMIC] +LOQUSDB_SUPPORTED_WORKFLOWS = [Workflow.MIP_DNA, Workflow.BALSAMIC] LOQUSDB_MIP_SEQUENCING_METHODS = [SequencingMethod.WGS, SequencingMethod.WES] LOQUSDB_BALSAMIC_SEQUENCING_METHODS = [SequencingMethod.WGS] diff --git a/cg/constants/report.py b/cg/constants/report.py index 60f3228dc2..1801c183e8 100644 --- a/cg/constants/report.py +++ b/cg/constants/report.py @@ -5,7 +5,7 @@ BALSAMIC_REPORT_ACCREDITED_PANELS: list[str] = ["gmsmyeloid"] -REPORT_SUPPORTED_PIPELINES: tuple[Workflow, ...] = ( +REPORT_SUPPORTED_WORKFLOW: tuple[Workflow, ...] = ( Workflow.BALSAMIC, Workflow.BALSAMIC_UMI, Workflow.BALSAMIC_QC, @@ -73,9 +73,9 @@ # Data analysis required fields REQUIRED_DATA_ANALYSIS_FIELDS: list[str] = [ - "customer_pipeline", - "pipeline", - "pipeline_version", + "customer_workflow", + "workflow", + "workflow_version", "genome_build", ] diff --git a/cg/meta/clean/api.py b/cg/meta/clean/api.py index a240482d40..2254e2f4d3 100644 --- a/cg/meta/clean/api.py +++ b/cg/meta/clean/api.py @@ -19,16 +19,16 @@ def __init__(self, status_db: Store, housekeeper_api: HousekeeperAPI): self.status_db = status_db self.housekeeper_api = housekeeper_api - def get_bundle_files(self, before: datetime, pipeline: Workflow) -> Iterator[list[File]]: - """Get any bundle files for a specific version""" + def get_bundle_files(self, before: datetime, workflow: Workflow) -> Iterator[list[File]]: + """Get any bundle files for a specific version.""" analysis: Analysis LOG.debug( - f"number of {pipeline} analyses before: {before} : {len(self.status_db.get_analyses_for_pipeline_started_at_before(pipeline=pipeline, started_at_before=before))}" + f"number of {workflow} analyses before: {before} : {len(self.status_db.get_analyses_for_workflow_started_at_before(workflow=workflow, started_at_before=before))}" ) - for analysis in self.status_db.get_analyses_for_pipeline_started_at_before( - pipeline=pipeline, started_at_before=before + for analysis in self.status_db.get_analyses_for_workflow_started_at_before( + workflow=workflow, started_at_before=before ): bundle_name = analysis.case.internal_id @@ -39,7 +39,7 @@ def get_bundle_files(self, before: datetime, pipeline: Workflow) -> Iterator[lis LOG.warning( f"Version not found for " f"bundle:{bundle_name}; " - f"pipeline: {pipeline}; " + f"workflow: {workflow}; " f"date {analysis.started_at}" ) continue @@ -47,7 +47,7 @@ def get_bundle_files(self, before: datetime, pipeline: Workflow) -> Iterator[lis LOG.info( f"Version found for " f"bundle:{bundle_name}; " - f"pipeline: {pipeline}; " + f"workflow: {workflow}; " f"date {analysis.started_at}" ) yield self.housekeeper_api.get_files( @@ -77,18 +77,15 @@ def has_protected_tags(file: File, protected_tags_lists: list[list[str]]) -> boo def get_unprotected_existing_bundle_files(self, before: datetime) -> Iterator[File]: """Returns all existing bundle files from analyses started before 'before' that have no protected tags""" - pipeline: Workflow - for pipeline in Workflow: - protected_tags_lists = WORKFLOW_PROTECTED_TAGS.get(pipeline) + workflow: Workflow + for workflow in Workflow: + protected_tags_lists = WORKFLOW_PROTECTED_TAGS.get(workflow) if not protected_tags_lists: - LOG.debug(f"No protected tags defined for {pipeline}, skipping") + LOG.debug(f"No protected tags defined for {workflow}, skipping") continue hk_files: list[File] - for hk_files in self.get_bundle_files( - before=before, - pipeline=pipeline, - ): + for hk_files in self.get_bundle_files(before=before, workflow=workflow): hk_file: File for hk_file in hk_files: if self.has_protected_tags(hk_file, protected_tags_lists=protected_tags_lists): diff --git a/cg/meta/report/balsamic.py b/cg/meta/report/balsamic.py index bdd789ce17..da22b87c1d 100644 --- a/cg/meta/report/balsamic.py +++ b/cg/meta/report/balsamic.py @@ -167,7 +167,7 @@ def get_required_fields(self, case: CaseModel) -> dict: analysis_type: str = case.data_analysis.type required_data_analysis_fields: list[str] = ( REQUIRED_DATA_ANALYSIS_FIELDS - if self.analysis_api.pipeline == Workflow.BALSAMIC_QC + if self.analysis_api.workflow == Workflow.BALSAMIC_QC else REQUIRED_DATA_ANALYSIS_BALSAMIC_FIELDS ) required_sample_metadata_fields: list[str] = [] diff --git a/cg/meta/report/report_api.py b/cg/meta/report/report_api.py index 19c115976c..7bd156136b 100644 --- a/cg/meta/report/report_api.py +++ b/cg/meta/report/report_api.py @@ -126,14 +126,14 @@ def render_delivery_report(self, report_data: dict) -> str: template: Template = env.get_template(self.get_template_name()) return template.render(**report_data) - def get_cases_without_delivery_report(self, pipeline: Workflow) -> list[Case]: + def get_cases_without_delivery_report(self, workflow: Workflow) -> list[Case]: """Returns a list of cases that has been stored and need a delivery report.""" stored_cases: list[Case] = [] - analyses: Query = self.status_db.analyses_to_delivery_report(pipeline=pipeline)[ + analyses: Query = self.status_db.analyses_to_delivery_report(workflow=workflow)[ :MAX_ITEMS_TO_RETRIEVE ] - for analysis_obj in analyses: - case: Case = analysis_obj.case + for analysis in analyses: + case: Case = analysis.case last_version: Version = self.housekeeper_api.last_version(bundle=case.internal_id) hk_file: File = self.housekeeper_api.get_files( bundle=case.internal_id, version=last_version.id if last_version else None @@ -147,15 +147,15 @@ def get_cases_without_delivery_report(self, pipeline: Workflow) -> list[Case]: ) return stored_cases - def get_cases_without_uploaded_delivery_report(self, pipeline: Workflow) -> list[Case]: + def get_cases_without_uploaded_delivery_report(self, workflow: Workflow) -> list[Case]: """Returns a list of cases that need a delivery report to be uploaded.""" - analyses: Query = self.status_db.analyses_to_upload_delivery_reports(pipeline=pipeline)[ + analyses: Query = self.status_db.analyses_to_upload_delivery_reports(workflow=workflow)[ :MAX_ITEMS_TO_RETRIEVE ] - return [analysis_obj.case for analysis_obj in analyses] + return [analysis.case for analysis in analyses] def update_delivery_report_date(self, case: Case, analysis_date: datetime) -> None: - """Updates the date when delivery report was created.""" + """Updates the date when a delivery report was created.""" analysis: Analysis = self.status_db.get_analysis_by_case_entry_id_and_started_at( case_entry_id=case.id, started_at_date=analysis_date ) @@ -280,11 +280,11 @@ def get_lims_sample(self, sample_id: str) -> dict | None: LOG.info(f"Could not fetch sample {sample_id} from LIMS: {ex}") return lims_sample - def get_pipeline_accreditation_limitation(self, application_tag: str) -> str | None: - """Return pipeline specific limitations given an application tag.""" + def get_workflow_accreditation_limitation(self, application_tag: str) -> str | None: + """Return workflow specific limitations given an application tag.""" application_limitation: ApplicationLimitations = ( - self.status_db.get_application_limitation_by_tag_and_pipeline( - tag=application_tag, pipeline=self.analysis_api.pipeline + self.status_db.get_application_limitation_by_tag_and_workflow( + tag=application_tag, workflow=self.analysis_api.workflow ) ) return application_limitation.limitations if application_limitation else None @@ -302,7 +302,7 @@ def get_sample_application_data(self, lims_sample: dict) -> ApplicationModel: description=application.description, details=application.details, limitations=application.limitations, - pipeline_limitations=self.get_pipeline_accreditation_limitation(application.tag), + workflow_limitations=self.get_workflow_accreditation_limitation(application.tag), accredited=application.is_accredited, external=application.is_external, ) @@ -337,12 +337,12 @@ def get_case_analysis_data( analysis: Analysis, analysis_metadata: AnalysisModel, ) -> DataAnalysisModel: - """Return pipeline attributes used for data analysis.""" + """Return workflow attributes used for data analysis.""" return DataAnalysisModel( - customer_pipeline=case.data_analysis, + customer_workflow=case.data_analysis, data_delivery=case.data_delivery, - pipeline=analysis.pipeline, - pipeline_version=analysis.pipeline_version, + workflow=analysis.pipeline, + workflow_version=analysis.pipeline_version, type=self.get_data_analysis_type(case=case), genome_build=self.get_genome_build(analysis_metadata=analysis_metadata), variant_callers=self.get_variant_callers(_analysis_metadata=analysis_metadata), @@ -419,7 +419,7 @@ def get_required_fields(self, case: CaseModel) -> dict: raise NotImplementedError def get_template_name(self) -> str: - """Return pipeline specific template name.""" + """Return workflow specific template name.""" raise NotImplementedError @staticmethod @@ -448,10 +448,10 @@ def get_timestamp_required_fields(case: CaseModel, required_fields: list) -> dic return ReportAPI.get_sample_required_fields(case=case, required_fields=required_fields) def get_hk_scout_file_tags(self, scout_tag: str) -> list | None: - """Return pipeline specific uploaded to Scout Housekeeper file tags given a Scout key.""" + """Return workflow specific uploaded to Scout Housekeeper file tags given a Scout key.""" tags = self.get_upload_case_tags().get(scout_tag) return list(tags) if tags else None def get_upload_case_tags(self): - """Return pipeline specific upload case tags.""" + """Return workflow specific upload case tags.""" raise NotImplementedError diff --git a/cg/meta/report/templates/balsamic_report.html b/cg/meta/report/templates/balsamic_report.html index 477eec7531..db4462ae99 100644 --- a/cg/meta/report/templates/balsamic_report.html +++ b/cg/meta/report/templates/balsamic_report.html @@ -85,7 +85,7 @@

Kundinformation

{{ sample.source }}* {{ sample.ticket }} {{ sample.application.tag }}* - {{ case.data_analysis.customer_pipeline }}* + {{ case.data_analysis.customer_workflow }}* {{ sample.tumour }}* {% endfor %} @@ -126,7 +126,7 @@

Kundinformation

{% endif %} {{ sample.methods.sequencing }} {{ sample.timestamps.reads_updated_at }} - {{ case.data_analysis.pipeline }} + {{ case.data_analysis.workflow }} {% endfor %} @@ -146,12 +146,12 @@

Kundinformation

{{ case.name }}* - {{ case.data_analysis.pipeline_version }} + {{ case.data_analysis.workflow_version }} {{ case.data_analysis.genome_build }} {{ case.data_analysis.type }} - {% if case.data_analysis.pipeline != 'balsamic-qc' %} + {% if case.data_analysis.workflow != 'balsamic-qc' %} Tillämpade filter för variantanrop: {{ case.data_analysis.variant_callers }}
@@ -271,8 +271,8 @@

Begränsningar av analysen: {{ application.tag }}

{{ application.limitations }}

- {% if application.pipeline_limitations != 'N/A' %} -

{{ application.pipeline_limitations }}

+ {% if application.workflow_limitations != 'N/A' %} +

{{ application.workflow_limitations }}

{% endif %} {% endif %} diff --git a/cg/meta/report/templates/mip-dna_report.html b/cg/meta/report/templates/mip-dna_report.html index f323922573..05d7639469 100644 --- a/cg/meta/report/templates/mip-dna_report.html +++ b/cg/meta/report/templates/mip-dna_report.html @@ -96,7 +96,7 @@

Kundinformation

{{ sample.source }}* {{ sample.ticket }} {{ sample.application.tag }}* - {{ case.data_analysis.customer_pipeline }}* + {{ case.data_analysis.customer_workflow }}* {% endfor %} @@ -127,7 +127,7 @@

Kundinformation

{{ sample.metadata.bait_set }} {{ sample.methods.sequencing }} {{ sample.timestamps.reads_updated_at }} - {{ case.data_analysis.pipeline }} + {{ case.data_analysis.workflow }} {% endfor %} @@ -147,7 +147,7 @@

Kundinformation

{{ case.name }}* - {{ case.data_analysis.pipeline_version }} + {{ case.data_analysis.workflow_version }} {{ case.data_analysis.panels }} {{ case.data_analysis.genome_build }} @@ -240,8 +240,8 @@

Begränsningar av analysen: {{ application.tag }}

{{ application.limitations }}

- {% if application.pipeline_limitations != 'N/A' %} -

{{ application.pipeline_limitations }}

+ {% if application.workflow_limitations != 'N/A' %} +

{{ application.workflow_limitations }}

{% endif %} {% endif %} diff --git a/cg/meta/report/templates/rnafusion_report.html b/cg/meta/report/templates/rnafusion_report.html index 8bc187c689..08232acce2 100644 --- a/cg/meta/report/templates/rnafusion_report.html +++ b/cg/meta/report/templates/rnafusion_report.html @@ -85,7 +85,7 @@

Kundinformation

{{ sample.source }}* {{ sample.ticket }} {{ sample.application.tag }}* - {{ case.data_analysis.customer_pipeline }}* + {{ case.data_analysis.customer_workflow }}* {{ sample.tumour }}* {% endfor %} @@ -115,7 +115,7 @@

Kundinformation

{{ sample.timestamps.prepared_at }} {{ sample.methods.sequencing }} {{ sample.timestamps.reads_updated_at }} - {{ case.data_analysis.pipeline }} + {{ case.data_analysis.workflow }} {% endfor %} @@ -135,7 +135,7 @@

Kundinformation

{{ case.name }}* - {{ case.data_analysis.pipeline_version }} + {{ case.data_analysis.workflow_version }} {{ case.data_analysis.panels }} {{ case.data_analysis.genome_build }} @@ -251,8 +251,8 @@

Begränsningar av analysen: {{ application.tag }}

{{ application.limitations }}

- {% if application.pipeline_limitations != 'N/A' %} -

{{ application.pipeline_limitations }}

+ {% if application.workflow_limitations != 'N/A' %} +

{{ application.workflow_limitations }}

{% endif %} {% endif %} diff --git a/cg/meta/rsync/rsync_api.py b/cg/meta/rsync/rsync_api.py index f35292c962..3cda74465d 100644 --- a/cg/meta/rsync/rsync_api.py +++ b/cg/meta/rsync/rsync_api.py @@ -35,7 +35,7 @@ def __init__(self, config: CGConfig): self.account: str = config.data_delivery.account self.log_dir: Path = Path(config.data_delivery.base_path) self.mail_user: str = config.data_delivery.mail_user - self.pipeline: str = Workflow.RSYNC + self.workflow: str = Workflow.RSYNC @property def slurm_quality_of_service(self) -> str: diff --git a/cg/meta/upload/gt.py b/cg/meta/upload/gt.py index 8a884090ad..097396abdf 100644 --- a/cg/meta/upload/gt.py +++ b/cg/meta/upload/gt.py @@ -25,7 +25,7 @@ def __init__( self.hk = hk_api self.gt = gt_api - def data(self, analysis_obj: Analysis) -> dict: + def data(self, analysis: Analysis) -> dict: """Fetch data about an analysis to load genotypes. Returns: dict on form @@ -41,19 +41,19 @@ def data(self, analysis_obj: Analysis) -> dict: } """ - case_id = analysis_obj.case.internal_id + case_id = analysis.case.internal_id LOG.info(f"Fetching upload genotype data for {case_id}") hk_version = self.hk.last_version(case_id) hk_bcf = self.get_bcf_file(hk_version) data = {"bcf": hk_bcf.full_path} - if analysis_obj.pipeline in [Workflow.BALSAMIC, Workflow.BALSAMIC_UMI]: - data["samples_sex"] = self._get_samples_sex_balsamic(case_obj=analysis_obj.case) - elif analysis_obj.pipeline == Workflow.MIP_DNA: + if analysis.pipeline in [Workflow.BALSAMIC, Workflow.BALSAMIC_UMI]: + data["samples_sex"] = self._get_samples_sex_balsamic(case_obj=analysis.case) + elif analysis.pipeline == Workflow.MIP_DNA: data["samples_sex"] = self._get_samples_sex_mip( - case_obj=analysis_obj.case, hk_version=hk_version + case_obj=analysis.case, hk_version=hk_version ) else: - raise ValueError(f"Workflow {analysis_obj.pipeline} does not support Genotype upload") + raise ValueError(f"Workflow {analysis.pipeline} does not support Genotype upload") return data def _get_samples_sex_mip(self, case_obj: Case, hk_version: Version) -> dict: diff --git a/cg/meta/upload/nipt/nipt.py b/cg/meta/upload/nipt/nipt.py index f6cd05eb39..6d6e24f4cb 100644 --- a/cg/meta/upload/nipt/nipt.py +++ b/cg/meta/upload/nipt/nipt.py @@ -105,7 +105,7 @@ def get_results_file_path(self, hk_results_file: str) -> Path: def get_all_upload_analyses(self) -> list[Analysis]: """Gets all nipt analyses that are ready to be uploaded""" - return self.status_db.get_latest_analysis_to_upload_for_pipeline(pipeline=Workflow.FLUFFY) + return self.status_db.get_latest_analysis_to_upload_for_workflow(workflow=Workflow.FLUFFY) def upload_to_ftp_server(self, results_file: Path) -> None: """Upload the result file to the ftp server""" diff --git a/cg/meta/upload/scout/uploadscoutapi.py b/cg/meta/upload/scout/uploadscoutapi.py index 63d0d9be11..52e58bcaed 100644 --- a/cg/meta/upload/scout/uploadscoutapi.py +++ b/cg/meta/upload/scout/uploadscoutapi.py @@ -57,17 +57,17 @@ def __init__( self.lims = lims_api self.status_db = status_db - def generate_config(self, analysis_obj: Analysis) -> ScoutLoadConfig: + def generate_config(self, analysis: Analysis) -> ScoutLoadConfig: """Fetch data about an analysis to load Scout.""" LOG.info("Generate scout load config") # Fetch last version from housekeeper # This should be safe since analyses are only added if data is analysed - hk_version_obj: Version = self.housekeeper.last_version(analysis_obj.case.internal_id) + hk_version_obj: Version = self.housekeeper.last_version(analysis.case.internal_id) LOG.debug(f"Found housekeeper version {hk_version_obj.id}") - LOG.info("Found pipeline %s", analysis_obj.pipeline) - config_builder = self.get_config_builder(analysis=analysis_obj, hk_version=hk_version_obj) + LOG.info(f"Found workflow {analysis.pipeline}") + config_builder = self.get_config_builder(analysis=analysis, hk_version=hk_version_obj) config_builder.build_load_config() @@ -115,10 +115,10 @@ def add_scout_config_to_hk( return file_obj def get_multiqc_html_report( - self, case_id: str, pipeline: Workflow + self, case_id: str, workflow: Workflow ) -> tuple[ScoutCustomCaseReportTags, File | None]: """Return a multiqc report for a case in Housekeeper.""" - if pipeline == Workflow.MIP_RNA: + if workflow == Workflow.MIP_RNA: return ( ScoutCustomCaseReportTags.MULTIQC_RNA, self.housekeeper.files(bundle=case_id, tags=HK_MULTIQC_HTML_TAG).first(), @@ -432,7 +432,7 @@ def filter_cases_related_to_dna_sample( list_of_dna_cases: list[Case], collaborators: set[Customer] ) -> list[str]: """Filters the given list of DNA samples and returns a subset of uploaded cases ordered by customers in the - specified list of collaborators and within the correct pipeline.""" + specified list of collaborators and within the correct workflow.""" filtered_dna_cases: list[str] = [] for case in list_of_dna_cases: if ( diff --git a/cg/meta/upload/upload_api.py b/cg/meta/upload/upload_api.py index 8d71822158..c514a3ad24 100644 --- a/cg/meta/upload/upload_api.py +++ b/cg/meta/upload/upload_api.py @@ -31,7 +31,7 @@ def __init__(self, config: CGConfig, analysis_api: AnalysisAPI): ) def upload(self, ctx: click.Context, case: Case, restart: bool) -> None: - """Uploads pipeline specific analysis data and files""" + """Uploads workflow specific analysis data and files.""" raise NotImplementedError diff --git a/cg/meta/workflow/analysis.py b/cg/meta/workflow/analysis.py index 26f8d8fbb2..75c1e0ff63 100644 --- a/cg/meta/workflow/analysis.py +++ b/cg/meta/workflow/analysis.py @@ -43,12 +43,12 @@ def add_gene_panel_combo(default_panels: set[str]) -> set[str]: class AnalysisAPI(MetaAPI): """ - Parent class containing all methods that are either shared or overridden by other workflow APIs + Parent class containing all methods that are either shared or overridden by other workflow APIs. """ - def __init__(self, pipeline: Workflow, config: CGConfig): + def __init__(self, workflow: Workflow, config: CGConfig): super().__init__(config=config) - self.pipeline = pipeline + self.workflow = workflow self._process = None @property @@ -107,7 +107,7 @@ def get_slurm_qos_for_case(self, case_id: str) -> str: return Priority.priority_to_slurm_qos().get(priority) def get_workflow_manager(self) -> str: - """Get workflow manager for a given pipeline.""" + """Get workflow manager for a given workflow.""" return WorkflowManager.Slurm.value def get_case_path(self, case_id: str) -> list[Path] | Path: @@ -183,13 +183,13 @@ def upload_bundle_statusdb(self, case_id: str, dry_run: bool = False) -> None: LOG.info(f"Storing analysis in StatusDB for {case_id}") case_obj: Case = self.status_db.get_case_by_internal_id(internal_id=case_id) analysis_start: dt.datetime = self.get_bundle_created_date(case_id=case_id) - pipeline_version: str = self.get_pipeline_version(case_id=case_id) + workflow_version: str = self.get_workflow_version(case_id=case_id) new_analysis: Case = self.status_db.add_analysis( - pipeline=self.pipeline, - version=pipeline_version, - started_at=analysis_start, + workflow=self.workflow, + version=workflow_version, completed_at=dt.datetime.now(), primary=(len(case_obj.analyses) == 0), + started_at=analysis_start, ) new_analysis.case = case_obj if dry_run: @@ -216,7 +216,7 @@ def add_pending_trailblazer_analysis(self, case_id: str) -> None: out_dir=self.get_job_ids_path(case_id).parent.as_posix(), config_path=self.get_job_ids_path(case_id).as_posix(), slurm_quality_of_service=self.get_slurm_qos_for_case(case_id), - data_analysis=str(self.pipeline), + data_analysis=str(self.workflow), ticket=self.status_db.get_latest_ticket_from_case(case_id), workflow_manager=self.get_workflow_manager(), ) @@ -225,7 +225,7 @@ def get_hermes_transformed_deliverables(self, case_id: str) -> dict: return self.hermes_api.create_housekeeper_bundle( bundle_name=case_id, deliverables=self.get_deliverables_file_path(case_id=case_id), - pipeline=str(self.pipeline), + workflow=str(self.workflow), analysis_type=self.get_bundle_deliverables_type(case_id), created=self.get_bundle_created_date(case_id), ).model_dump() @@ -233,15 +233,15 @@ def get_hermes_transformed_deliverables(self, case_id: str) -> dict: def get_bundle_created_date(self, case_id: str) -> dt.datetime: return self.get_date_from_file_path(self.get_deliverables_file_path(case_id=case_id)) - def get_pipeline_version(self, case_id: str) -> str: + def get_workflow_version(self, case_id: str) -> str: """ - Calls the pipeline to get the pipeline version number. If fails, returns a placeholder value instead. + Calls the workflow to get the workflow version number. If fails, returns a placeholder value instead. """ try: self.process.run_command(["--version"]) return list(self.process.stdout_lines())[0].split()[-1] except (Exception, CalledProcessError): - LOG.warning("Could not retrieve %s workflow version!", self.pipeline) + LOG.warning(f"Could not retrieve {self.workflow} workflow version!") return "0.0.0" def set_statusdb_action(self, case_id: str, action: str | None, dry_run: bool = False) -> None: @@ -263,13 +263,13 @@ def set_statusdb_action(self, case_id: str, action: str | None, dry_run: bool = def get_analyses_to_clean(self, before: dt.datetime) -> list[Analysis]: analyses_to_clean = self.status_db.get_analyses_to_clean( - pipeline=self.pipeline, before=before + before=before, workflow=self.workflow ) return analyses_to_clean def get_cases_to_analyze(self) -> list[Case]: return self.status_db.cases_to_analyze( - pipeline=self.pipeline, threshold=self.use_read_count_threshold + workflow=self.workflow, threshold=self.use_read_count_threshold ) def get_cases_to_store(self) -> list[Case]: @@ -277,7 +277,7 @@ def get_cases_to_store(self) -> list[Case]: and is ready to be stored in Housekeeper.""" return [ case - for case in self.status_db.get_running_cases_in_pipeline(pipeline=self.pipeline) + for case in self.status_db.get_running_cases_in_workflow(workflow=self.workflow) if self.trailblazer_api.is_latest_analysis_completed(case_id=case.internal_id) ] @@ -286,7 +286,7 @@ def get_cases_to_qc(self) -> list[Case]: and is ready for QC metrics checks.""" return [ case - for case in self.status_db.get_running_cases_in_pipeline(pipeline=self.pipeline) + for case in self.status_db.get_running_cases_in_workflow(workflow=self.workflow) if self.trailblazer_api.is_latest_analysis_qc(case_id=case.internal_id) ] @@ -307,7 +307,7 @@ def link_fastq_files_for_sample( ) -> None: """ Link FASTQ files for a sample to the work directory. - If pipeline input requires concatenated fastq, files can also be concatenated + If workflow input requires concatenated fastq, files can also be concatenated """ linked_reads_paths: dict[int, list[Path]] = {1: [], 2: []} concatenated_paths: dict[int, str] = {1: "", 2: ""} diff --git a/cg/meta/workflow/balsamic.py b/cg/meta/workflow/balsamic.py index 675917ff2f..13332b8a66 100644 --- a/cg/meta/workflow/balsamic.py +++ b/cg/meta/workflow/balsamic.py @@ -41,9 +41,9 @@ class BalsamicAnalysisAPI(AnalysisAPI): def __init__( self, config: CGConfig, - pipeline: Workflow = Workflow.BALSAMIC, + workflow: Workflow = Workflow.BALSAMIC, ): - super().__init__(config=config, pipeline=pipeline) + super().__init__(workflow=workflow, config=config) self.account: str = config.balsamic.slurm.account self.binary_path: str = config.balsamic.binary_path self.balsamic_cache: str = config.balsamic.balsamic_cache @@ -94,7 +94,7 @@ def get_case_path(self, case_id: str) -> Path: def get_cases_to_analyze(self) -> list[Case]: cases_query: list[Case] = self.status_db.cases_to_analyze( - pipeline=self.pipeline, threshold=self.use_read_count_threshold + workflow=self.workflow, threshold=self.use_read_count_threshold ) cases_to_analyze = [] for case_obj in cases_query: @@ -456,7 +456,7 @@ def get_verified_config_case_arguments( config_case: dict[str, str] = { "case_id": case_id, - "analysis_workflow": self.pipeline, + "analysis_workflow": self.workflow, "genome_version": genome_version, "sex": verified_sex, "panel_bed": verified_panel_bed, @@ -528,8 +528,8 @@ def resolve_target_bed(self, panel_bed: str | None, link_object: CaseSample) -> return None return self.get_target_bed_from_lims(link_object.case.internal_id) - def get_pipeline_version(self, case_id: str) -> str: - LOG.debug("Fetch pipeline version") + def get_workflow_version(self, case_id: str) -> str: + LOG.debug("Fetch workflow version") config_data: dict = ReadFile.get_content_from_file( file_format=FileFormat.JSON, file_path=self.get_case_config_path(case_id=case_id) ) diff --git a/cg/meta/workflow/balsamic_pon.py b/cg/meta/workflow/balsamic_pon.py index 498f2eaf26..72a4d3466e 100644 --- a/cg/meta/workflow/balsamic_pon.py +++ b/cg/meta/workflow/balsamic_pon.py @@ -19,9 +19,9 @@ class BalsamicPonAnalysisAPI(BalsamicAnalysisAPI): def __init__( self, config: CGConfig, - pipeline: Workflow = Workflow.BALSAMIC_PON, + workflow: Workflow = Workflow.BALSAMIC_PON, ): - super().__init__(config=config, pipeline=pipeline) + super().__init__(config=config, workflow=workflow) def config_case( self, diff --git a/cg/meta/workflow/balsamic_qc.py b/cg/meta/workflow/balsamic_qc.py index 2dd274c332..9a1ebbc091 100644 --- a/cg/meta/workflow/balsamic_qc.py +++ b/cg/meta/workflow/balsamic_qc.py @@ -16,6 +16,6 @@ class BalsamicQCAnalysisAPI(BalsamicAnalysisAPI): def __init__( self, config: CGConfig, - pipeline: Workflow = Workflow.BALSAMIC_QC, + workflow: Workflow = Workflow.BALSAMIC_QC, ): - super().__init__(config=config, pipeline=pipeline) + super().__init__(config=config, workflow=workflow) diff --git a/cg/meta/workflow/balsamic_umi.py b/cg/meta/workflow/balsamic_umi.py index d6fcaded8e..e04033925d 100644 --- a/cg/meta/workflow/balsamic_umi.py +++ b/cg/meta/workflow/balsamic_umi.py @@ -16,6 +16,6 @@ class BalsamicUmiAnalysisAPI(BalsamicAnalysisAPI): def __init__( self, config: CGConfig, - pipeline: Workflow = Workflow.BALSAMIC_UMI, + workflow: Workflow = Workflow.BALSAMIC_UMI, ): - super().__init__(config=config, pipeline=pipeline) + super().__init__(config=config, workflow=workflow) diff --git a/cg/meta/workflow/fastq.py b/cg/meta/workflow/fastq.py index 7b30caff9e..bb548ca4d1 100644 --- a/cg/meta/workflow/fastq.py +++ b/cg/meta/workflow/fastq.py @@ -136,7 +136,7 @@ def create_fastq_name( meta: str | None = None, ) -> str: """Name a FASTQ file with standard conventions and - no naming constrains from the pipeline.""" + no naming constrains from the workflow.""" flow_cell: str = f"{flow_cell}-undetermined" if undetermined else flow_cell date: str = date if isinstance(date, str) else date.strftime("%y%m%d") return f"{lane}_{date}_{flow_cell}_{sample}_{index}_{read_direction}{FileExtensions.FASTQ}{FileExtensions.GZIP}" diff --git a/cg/meta/workflow/fluffy.py b/cg/meta/workflow/fluffy.py index 666050107a..63c9cfbb8d 100644 --- a/cg/meta/workflow/fluffy.py +++ b/cg/meta/workflow/fluffy.py @@ -74,15 +74,12 @@ class FluffyAnalysisAPI(AnalysisAPI): def __init__( self, config: CGConfig, - pipeline: Workflow = Workflow.FLUFFY, + workflow: Workflow = Workflow.FLUFFY, ): self.root_dir = Path(config.fluffy.root_dir) LOG.info("Set root dir to %s", config.fluffy.root_dir) self.fluffy_config = Path(config.fluffy.config_path) - super().__init__( - pipeline, - config, - ) + super().__init__(workflow, config) @property def use_read_count_threshold(self) -> bool: @@ -264,7 +261,7 @@ def get_cases_to_store(self) -> list[Case]: and is ready to be stored in Housekeeper.""" return [ case - for case in self.status_db.get_running_cases_in_pipeline(pipeline=self.pipeline) + for case in self.status_db.get_running_cases_in_workflow(workflow=self.workflow) if Path(self.get_analysis_finish_path(case_id=case.internal_id)).exists() ] diff --git a/cg/meta/workflow/microsalt/microsalt.py b/cg/meta/workflow/microsalt/microsalt.py index a449870a6d..8745100bc1 100644 --- a/cg/meta/workflow/microsalt/microsalt.py +++ b/cg/meta/workflow/microsalt/microsalt.py @@ -26,8 +26,8 @@ class MicrosaltAnalysisAPI(AnalysisAPI): """API to manage Microsalt Analyses""" - def __init__(self, config: CGConfig, pipeline: Workflow = Workflow.MICROSALT): - super().__init__(pipeline, config) + def __init__(self, config: CGConfig, workflow: Workflow = Workflow.MICROSALT): + super().__init__(workflow, config) self.root_dir = config.microsalt.root self.queries_path = config.microsalt.queries_path self.quality_checker = QualityController(config.status_db) @@ -280,7 +280,7 @@ def get_completed_cases(self) -> list[Case]: """Return cases that are completed in trailblazer.""" return [ case - for case in self.status_db.get_running_cases_in_pipeline(self.pipeline) + for case in self.status_db.get_running_cases_in_workflow(self.workflow) if self.trailblazer_api.is_latest_analysis_completed(case.internal_id) ] diff --git a/cg/meta/workflow/mip.py b/cg/meta/workflow/mip.py index 14bf80446d..769a3b2d7f 100644 --- a/cg/meta/workflow/mip.py +++ b/cg/meta/workflow/mip.py @@ -39,8 +39,8 @@ class MipAnalysisAPI(AnalysisAPI): """The workflow is accessed through Trailblazer but cg provides additional conventions and hooks into the status database that makes managing analyses simpler""" - def __init__(self, config: CGConfig, pipeline: Workflow): - super().__init__(pipeline, config) + def __init__(self, config: CGConfig, workflow: Workflow): + super().__init__(workflow, config) @property def root(self) -> str: @@ -51,7 +51,7 @@ def conda_env(self) -> str: raise NotImplementedError @property - def mip_pipeline(self) -> str: + def mip_workflow(self) -> str: raise NotImplementedError @property @@ -269,7 +269,7 @@ def get_skip_evaluation_flag(self, case_id: str, skip_evaluation: bool) -> bool: def get_cases_to_analyze(self) -> list[Case]: """Return cases to analyze.""" cases_query: list[Case] = self.status_db.cases_to_analyze( - pipeline=self.pipeline, threshold=self.use_read_count_threshold + workflow=self.workflow, threshold=self.use_read_count_threshold ) cases_to_analyze = [] for case_obj in cases_query: @@ -318,9 +318,9 @@ def get_job_ids_path(self, case_id: str) -> Path: def config_sample(self, link_obj: CaseSample, panel_bed: str) -> dict: raise NotImplementedError - def get_pipeline_version(self, case_id: str) -> str: + def get_workflow_version(self, case_id: str) -> str: """Get MIP version from sample info file""" - LOG.debug("Fetch pipeline version") + LOG.debug("Fetch workflow version") sample_info_raw: dict = ReadFile.get_content_from_file( file_format=FileFormat.YAML, file_path=self.get_sample_info_path(case_id) ) diff --git a/cg/meta/workflow/mip_dna.py b/cg/meta/workflow/mip_dna.py index e611d3e35e..060bb08cbd 100644 --- a/cg/meta/workflow/mip_dna.py +++ b/cg/meta/workflow/mip_dna.py @@ -9,8 +9,8 @@ class MipDNAAnalysisAPI(MipAnalysisAPI): - def __init__(self, config: CGConfig, pipeline: Workflow = Workflow.MIP_DNA): - super().__init__(config, pipeline) + def __init__(self, config: CGConfig, workflow: Workflow = Workflow.MIP_DNA): + super().__init__(config, workflow) @property def root(self) -> str: @@ -25,7 +25,7 @@ def conda_env(self) -> str: return self.config.mip_rd_dna.conda_env @property - def mip_pipeline(self) -> str: + def mip_workflow(self) -> str: return self.config.mip_rd_dna.pipeline @property @@ -40,7 +40,7 @@ def use_read_count_threshold(self) -> bool: def process(self) -> Process: if not self._process: self._process = Process( - binary=f"{self.script} {self.mip_pipeline}", + binary=f"{self.script} {self.mip_workflow}", conda_binary=f"{self.conda_binary}" if self.conda_binary else None, config=self.config.mip_rd_dna.mip_config, environment=self.conda_env, diff --git a/cg/meta/workflow/mip_rna.py b/cg/meta/workflow/mip_rna.py index 08f11dda21..88dba88606 100644 --- a/cg/meta/workflow/mip_rna.py +++ b/cg/meta/workflow/mip_rna.py @@ -7,8 +7,8 @@ class MipRNAAnalysisAPI(MipAnalysisAPI): - def __init__(self, config: CGConfig, pipeline: Workflow = Workflow.MIP_RNA): - super().__init__(config, pipeline) + def __init__(self, config: CGConfig, workflow: Workflow = Workflow.MIP_RNA): + super().__init__(config, workflow) @property def root(self) -> str: @@ -23,7 +23,7 @@ def conda_env(self) -> str: return self.config.mip_rd_rna.conda_env @property - def mip_pipeline(self) -> str: + def mip_workflow(self) -> str: return self.config.mip_rd_rna.pipeline @property @@ -38,7 +38,7 @@ def use_read_count_threshold(self) -> bool: def process(self) -> Process: if not self._process: self._process = Process( - binary=f"{self.script} {self.mip_pipeline}", + binary=f"{self.script} {self.mip_workflow}", conda_binary=f"{self.conda_binary}" if self.conda_binary else None, config=self.config.mip_rd_rna.mip_config, environment=self.conda_env, diff --git a/cg/meta/workflow/mutant.py b/cg/meta/workflow/mutant.py index ac179e44ec..2ff4f9a14f 100644 --- a/cg/meta/workflow/mutant.py +++ b/cg/meta/workflow/mutant.py @@ -19,9 +19,9 @@ class MutantAnalysisAPI(AnalysisAPI): def __init__( self, config: CGConfig, - pipeline: Workflow = Workflow.MUTANT, + workflow: Workflow = Workflow.MUTANT, ): - super().__init__(config=config, pipeline=pipeline) + super().__init__(workflow=workflow, config=config) self.root_dir = config.mutant.root @property @@ -187,7 +187,7 @@ def get_cases_to_store(self) -> list[Case]: and is ready to be stored in Housekeeper.""" return [ case - for case in self.status_db.get_running_cases_in_pipeline(pipeline=self.pipeline) + for case in self.status_db.get_running_cases_in_workflow(workflow=self.workflow) if Path(self.get_deliverables_file_path(case_id=case.internal_id)).exists() ] @@ -204,7 +204,7 @@ def link_nanopore_fastq_for_sample( ) -> None: """ Link FASTQ files for a nanopore sample to working directory. - If pipeline input requires concatenated fastq, files can also be concatenated + If workflow input requires concatenated fastq, files can also be concatenated """ read_paths = [] files: list[dict] = self.get_metadata_for_nanopore_sample(sample=sample) diff --git a/cg/meta/workflow/nf_analysis.py b/cg/meta/workflow/nf_analysis.py index cde1f311b4..ba8402fadb 100644 --- a/cg/meta/workflow/nf_analysis.py +++ b/cg/meta/workflow/nf_analysis.py @@ -28,17 +28,17 @@ class NfAnalysisAPI(AnalysisAPI): """Parent class for handling NF-core analyses.""" - def __init__(self, config: CGConfig, pipeline: Workflow): - super().__init__(config=config, pipeline=pipeline) - self.pipeline: Workflow = pipeline + def __init__(self, config: CGConfig, workflow: Workflow): + super().__init__(workflow=workflow, config=config) + self.workflow: Workflow = workflow self.root_dir: str | None = None - self.nfcore_pipeline_path: str | None = None + self.nfcore_workflow_path: str | None = None self.references: str | None = None self.profile: str | None = None self.conda_env: str | None = None self.conda_binary: str | None = None self.tower_binary_path: str | None = None - self.tower_pipeline: str | None = None + self.tower_workflow: str | None = None self.account: str | None = None self.email: str | None = None self.compute_env_base: str | None = None @@ -69,7 +69,7 @@ def get_workflow_manager(self) -> str: """Get workflow manager from Tower.""" return WorkflowManager.Tower.value - def get_pipeline_version(self, case_id: str) -> str: + def get_workflow_version(self, case_id: str) -> str: """Get pipeline version from config.""" return self.revision @@ -122,14 +122,14 @@ def create_case_directory(self, case_id: str, dry_run: bool = False) -> None: if not dry_run: Path(self.get_case_path(case_id=case_id)).mkdir(parents=True, exist_ok=True) - def get_log_path(self, case_id: str, pipeline: str, log: str = None) -> Path: + def get_log_path(self, case_id: str, workflow: str, log: str = None) -> Path: """Path to NF log.""" if log: return log launch_time: str = datetime.now().strftime("%Y-%m-%d_%H.%M.%S") return Path( self.get_case_path(case_id), - f"{case_id}_{pipeline}_nextflow_{launch_time}", + f"{case_id}_{workflow}_nextflow_{launch_time}", ).with_suffix(FileExtensions.LOG) def get_workdir_path(self, case_id: str, work_dir: Path | None = None) -> Path: @@ -166,11 +166,11 @@ def verify_deliverables_file_exists(self, case_id: str) -> None: if not Path(self.get_deliverables_file_path(case_id=case_id)).exists(): raise CgError(f"No deliverables file found for case {case_id}") - def write_params_file(self, case_id: str, pipeline_parameters: dict) -> None: + def write_params_file(self, case_id: str, workflow_parameters: dict) -> None: """Write params-file for analysis.""" LOG.debug("Writing parameters file") write_yaml_nextflow_style( - content=pipeline_parameters, + content=workflow_parameters, file_path=self.get_params_file_path(case_id=case_id), ) @@ -222,7 +222,7 @@ def _run_analysis_with_nextflow( LOG.info("Workflow will be executed using Nextflow") parameters: list[str] = NextflowHandler.get_nextflow_run_parameters( case_id=case_id, - pipeline_path=self.nfcore_pipeline_path, + pipeline_path=self.nfcore_workflow_path, root_dir=self.root_dir, command_args=command_args.dict(), ) @@ -258,8 +258,7 @@ def _run_analysis_with_tower( ) else: parameters: list[str] = NfTowerHandler.get_tower_launch_parameters( - tower_pipeline=self.tower_pipeline, - command_args=command_args.dict(), + tower_workflow=self.tower_workflow, command_args=command_args.dict() ) self.process.run_command(parameters=parameters, dry_run=dry_run) if self.process.stderr: @@ -322,7 +321,7 @@ def get_multiqc_json_path(self, case_id: str) -> Path: MultiQC.MULTIQC_DATA + FileExtensions.JSON, ) - def get_pipeline_metrics(self) -> dict: + def get_workflow_metrics(self) -> dict: """Get nf-core pipeline metrics constants.""" return {} @@ -342,7 +341,7 @@ def get_metric_base_list(self, sample_id: str, metrics_values: dict) -> list[Met name=metric_name, step=MultiQC.MULTIQC, value=metric_value, - condition=self.get_pipeline_metrics().get(metric_name, None), + condition=self.get_workflow_metrics().get(metric_name, None), ) ) return metric_base_list diff --git a/cg/meta/workflow/nf_handlers.py b/cg/meta/workflow/nf_handlers.py index 38fca3f9e0..5e859a9bc3 100644 --- a/cg/meta/workflow/nf_handlers.py +++ b/cg/meta/workflow/nf_handlers.py @@ -30,7 +30,7 @@ class NfTowerHandler(NfBaseHandler): """ @classmethod - def get_tower_launch_parameters(cls, tower_pipeline: str, command_args: dict) -> list[str]: + def get_tower_launch_parameters(cls, tower_workflow: str, command_args: dict) -> list[str]: """Returns a tower launch command given a dictionary with arguments.""" tower_options: list[str] = build_command_from_dict( @@ -48,7 +48,7 @@ def get_tower_launch_parameters(cls, tower_pipeline: str, command_args: dict) -> }, exclude_true=True, ) - return ["launch"] + tower_options + [tower_pipeline] + return ["launch"] + tower_options + [tower_workflow] @classmethod def get_tower_relaunch_parameters(cls, from_tower_id: int, command_args: dict) -> list[str]: diff --git a/cg/meta/workflow/prepare_fastq.py b/cg/meta/workflow/prepare_fastq.py index 52176f3397..570238a4ee 100644 --- a/cg/meta/workflow/prepare_fastq.py +++ b/cg/meta/workflow/prepare_fastq.py @@ -61,7 +61,7 @@ def is_sample_decompression_needed(self, sample_id: str) -> bool: @staticmethod def _should_skip_sample(case: Case, sample: Sample): """ - For some pipelines, we want to start a partial analysis disregarding the samples with no reads. + For some workflows, we want to start a partial analysis disregarding the samples with no reads. This method returns true if we should skip the sample. """ if case.data_analysis in PIPELINES_USING_PARTIAL_ANALYSES and not sample.has_reads: diff --git a/cg/meta/workflow/raredisease.py b/cg/meta/workflow/raredisease.py index 3cacc4febb..011fe4711b 100644 --- a/cg/meta/workflow/raredisease.py +++ b/cg/meta/workflow/raredisease.py @@ -19,9 +19,9 @@ class RarediseaseAnalysisAPI(NfAnalysisAPI): def __init__( self, config: CGConfig, - pipeline: Workflow = Workflow.RAREDISEASE, + workflow: Workflow = Workflow.RAREDISEASE, ): - super().__init__(config=config, pipeline=pipeline) + super().__init__(config=config, workflow=workflow) @property def root(self) -> str: diff --git a/cg/meta/workflow/rnafusion.py b/cg/meta/workflow/rnafusion.py index 79702efc55..9afa61aba2 100644 --- a/cg/meta/workflow/rnafusion.py +++ b/cg/meta/workflow/rnafusion.py @@ -33,17 +33,17 @@ class RnafusionAnalysisAPI(NfAnalysisAPI): def __init__( self, config: CGConfig, - pipeline: Workflow = Workflow.RNAFUSION, + workflow: Workflow = Workflow.RNAFUSION, ): - super().__init__(config=config, pipeline=pipeline) + super().__init__(config=config, workflow=workflow) self.root_dir: str = config.rnafusion.root - self.nfcore_pipeline_path: str = config.rnafusion.pipeline_path + self.nfcore_workflow_path: str = config.rnafusion.pipeline_path self.references: str = config.rnafusion.references self.profile: str = config.rnafusion.profile self.conda_env: str = config.rnafusion.conda_env self.conda_binary: str = config.rnafusion.conda_binary self.tower_binary_path: str = config.tower_binary_path - self.tower_pipeline: str = config.rnafusion.tower_pipeline + self.tower_workflow: str = config.rnafusion.tower_pipeline self.account: str = config.rnafusion.slurm.account self.email: str = config.rnafusion.slurm.mail_user self.compute_env_base: str = config.rnafusion.compute_env @@ -98,7 +98,7 @@ def get_sample_sheet_content(self, case_id: str, strandedness: Strandedness) -> ) return content_per_sample - def get_pipeline_parameters( + def get_workflow_parameters( self, case_id: str, genomes_base: Path | None = None ) -> RnafusionParameters: """Get Rnafusion parameters.""" @@ -128,7 +128,7 @@ def config_case( sample_sheet_content: list[list[Any]] = self.get_sample_sheet_content( case_id=case_id, strandedness=strandedness ) - pipeline_parameters: RnafusionParameters = self.get_pipeline_parameters( + workflow_parameters: RnafusionParameters = self.get_workflow_parameters( case_id=case_id, genomes_base=genomes_base ) if dry_run: @@ -139,7 +139,7 @@ def config_case( file_path=self.get_sample_sheet_path(case_id=case_id), header=RnafusionSampleSheetEntry.headers(), ) - self.write_params_file(case_id=case_id, pipeline_parameters=pipeline_parameters.dict()) + self.write_params_file(case_id=case_id, workflow_parameters=workflow_parameters.dict()) def parse_multiqc_json_for_case(self, case_id: str) -> dict: """Parse a multiqc_data.json file and returns a dictionary with metric name and metric values for a case.""" @@ -202,5 +202,5 @@ def get_latest_metadata(self, case_id: str) -> RnafusionAnalysis: qc_metrics: list[MetricsBase] = self.get_multiqc_json_metrics(case_id) return self.parse_analysis(qc_metrics_raw=qc_metrics) - def get_pipeline_metrics(self) -> dict: + def get_workflow_metrics(self) -> dict: return RNAFUSION_METRIC_CONDITIONS diff --git a/cg/meta/workflow/taxprofiler.py b/cg/meta/workflow/taxprofiler.py index 106452ea7f..e8972d2e6d 100644 --- a/cg/meta/workflow/taxprofiler.py +++ b/cg/meta/workflow/taxprofiler.py @@ -27,11 +27,11 @@ class TaxprofilerAnalysisAPI(NfAnalysisAPI): def __init__( self, config: CGConfig, - pipeline: Workflow = Workflow.TAXPROFILER, + workflow: Workflow = Workflow.TAXPROFILER, ): - super().__init__(config=config, pipeline=pipeline) + super().__init__(config=config, workflow=workflow) self.root_dir: str = config.taxprofiler.root - self.nfcore_pipeline_path: str = config.taxprofiler.pipeline_path + self.nfcore_workflow_path: str = config.taxprofiler.pipeline_path self.conda_env: str = config.taxprofiler.conda_env self.conda_binary: str = config.taxprofiler.conda_binary self.profile: str = config.taxprofiler.profile @@ -39,7 +39,7 @@ def __init__( self.hostremoval_reference: Path = Path(config.taxprofiler.hostremoval_reference) self.databases: Path = Path(config.taxprofiler.databases) self.tower_binary_path: str = config.tower_binary_path - self.tower_pipeline: str = config.taxprofiler.tower_pipeline + self.tower_workflow: str = config.taxprofiler.tower_pipeline self.account: str = config.taxprofiler.slurm.account self.email: str = config.taxprofiler.slurm.mail_user self.nextflow_binary_path: str = config.taxprofiler.binary_path @@ -86,7 +86,7 @@ def get_sample_sheet_content( ) return sample_sheet_content - def get_pipeline_parameters(self, case_id: str) -> TaxprofilerParameters: + def get_workflow_parameters(self, case_id: str) -> TaxprofilerParameters: """Return Taxprofiler parameters.""" LOG.debug("Getting parameters information") return TaxprofilerParameters( @@ -112,7 +112,7 @@ def config_case( instrument_platform=instrument_platform, fasta=fasta, ) - pipeline_parameters: TaxprofilerParameters = self.get_pipeline_parameters(case_id=case_id) + workflow_parameters: TaxprofilerParameters = self.get_workflow_parameters(case_id=case_id) if dry_run: LOG.info("Dry run: Config files will not be written") return @@ -121,7 +121,7 @@ def config_case( file_path=self.get_sample_sheet_path(case_id=case_id), header=TaxprofilerSampleSheetEntry.headers(), ) - self.write_params_file(case_id=case_id, pipeline_parameters=pipeline_parameters.dict()) + self.write_params_file(case_id=case_id, workflow_parameters=workflow_parameters.dict()) def get_multiqc_json_metrics(self, case_id: str) -> list[MetricsBase]: """Return a list of the metrics specified in a MultiQC json file for the case samples.""" diff --git a/cg/models/report/metadata.py b/cg/models/report/metadata.py index 610cea3560..d2c51935e8 100644 --- a/cg/models/report/metadata.py +++ b/cg/models/report/metadata.py @@ -28,7 +28,7 @@ class MipDNASampleMetadataModel(SampleMetadataModel): Attributes: bait_set: panel bed used for the analysis; source: LIMS - gender: gender estimated by the pipeline; source: pipeline workflow + gender: gender estimated by the workflow; source: pipeline workflow mapped_reads: percentage of reads aligned to the reference sequence; source: pipeline workflow mean_target_coverage: mean coverage of a target region; source: pipeline workflow pct_10x: percent of targeted bases that are covered to 10X coverage or more; source: pipeline workflow diff --git a/cg/models/report/report.py b/cg/models/report/report.py index 88a251ce73..8734685452 100644 --- a/cg/models/report/report.py +++ b/cg/models/report/report.py @@ -3,7 +3,7 @@ from pydantic import BaseModel, BeforeValidator, model_validator from typing_extensions import Annotated -from cg.constants import NA_FIELD, REPORT_SUPPORTED_PIPELINES +from cg.constants import NA_FIELD, REPORT_SUPPORTED_WORKFLOW from cg.models.report.sample import ApplicationModel, SampleModel from cg.models.report.validators import ( get_analysis_type_as_string, @@ -58,13 +58,13 @@ class ScoutReportFiles(BaseModel): class DataAnalysisModel(BaseModel): """ - Model that describes the pipeline attributes used for the data analysis + Model that describes the workflow attributes used for the data analysis Attributes: - customer_pipeline: data analysis requested by the customer; source: StatusDB/family/data_analysis + customer_workflow: data analysis requested by the customer; source: StatusDB/family/data_analysis data_delivery: data delivery requested by the customer; source: StatusDB/family/data_delivery - pipeline: actual pipeline used for analysis; source: statusDB/analysis/pipeline - pipeline_version: pipeline version; source: statusDB/analysis/pipeline_version + workflow: actual workflow used for analysis; source: statusDB/analysis/pipeline + workflow_version: workflow version; source: statusDB/analysis/pipeline_version type: analysis type carried out; source: pipeline workflow genome_build: build version of the genome reference; source: pipeline workflow variant_callers: variant-calling filters; source: pipeline workflow @@ -72,10 +72,10 @@ class DataAnalysisModel(BaseModel): scout_files: list of file names uploaded to Scout """ - customer_pipeline: Annotated[str, BeforeValidator(get_report_string)] = NA_FIELD + customer_workflow: Annotated[str, BeforeValidator(get_report_string)] = NA_FIELD data_delivery: Annotated[str, BeforeValidator(get_report_string)] = NA_FIELD - pipeline: Annotated[str, BeforeValidator(get_report_string)] = NA_FIELD - pipeline_version: Annotated[str, BeforeValidator(get_report_string)] = NA_FIELD + workflow: Annotated[str, BeforeValidator(get_report_string)] = NA_FIELD + workflow_version: Annotated[str, BeforeValidator(get_report_string)] = NA_FIELD type: Annotated[str, BeforeValidator(get_analysis_type_as_string)] = NA_FIELD genome_build: Annotated[str, BeforeValidator(get_report_string)] = NA_FIELD variant_callers: Annotated[str, BeforeValidator(get_list_as_string)] = NA_FIELD @@ -83,16 +83,16 @@ class DataAnalysisModel(BaseModel): scout_files: ScoutReportFiles @model_validator(mode="after") - def check_supported_pipeline(self) -> "DataAnalysisModel": - """Check if the report generation supports a specific pipeline and analysis type.""" - if self.pipeline != self.customer_pipeline: + def check_supported_workflow(self) -> "DataAnalysisModel": + """Check if the report generation supports a specific workflow and analysis type.""" + if self.workflow != self.customer_workflow: LOG.error( - f"The analysis requested by the customer ({self.customer_pipeline}) does not match the one " - f"executed ({self.pipeline})" + f"The analysis requested by the customer ({self.customer_workflow}) does not match the one " + f"executed ({self.workflow})" ) raise ValueError - if self.pipeline not in REPORT_SUPPORTED_PIPELINES: - LOG.error(f"The pipeline {self.pipeline} does not support delivery report generation") + if self.workflow not in REPORT_SUPPORTED_WORKFLOW: + LOG.error(f"The workflow {self.workflow} does not support delivery report generation") raise ValueError return self diff --git a/cg/models/report/sample.py b/cg/models/report/sample.py index b931956b67..a7a080b292 100644 --- a/cg/models/report/sample.py +++ b/cg/models/report/sample.py @@ -37,7 +37,7 @@ class ApplicationModel(BaseModel): description: Annotated[str, BeforeValidator(get_report_string)] = NA_FIELD details: Annotated[str, BeforeValidator(get_report_string)] = NA_FIELD limitations: Annotated[str, BeforeValidator(get_report_string)] = NA_FIELD - pipeline_limitations: Annotated[str, BeforeValidator(get_report_string)] = NA_FIELD + workflow_limitations: Annotated[str, BeforeValidator(get_report_string)] = NA_FIELD accredited: bool | None = None external: bool | None = None diff --git a/cg/models/report/validators.py b/cg/models/report/validators.py index bed6a8797c..108013ba47 100644 --- a/cg/models/report/validators.py +++ b/cg/models/report/validators.py @@ -72,6 +72,6 @@ def get_prep_category_as_string(prep_category: PrepCategory | None) -> str: def get_analysis_type_as_string(analysis_type: str | None, info: ValidationInfo) -> str: """Return the analysis type as an accepted string value for the delivery report.""" - if analysis_type and Workflow.BALSAMIC in info.data.get("pipeline"): + if analysis_type and Workflow.BALSAMIC in info.data.get("workflow"): analysis_type: str = BALSAMIC_ANALYSIS_TYPE.get(analysis_type) return get_report_string(analysis_type) diff --git a/cg/resources/rnafusion_bundle_filenames.csv b/cg/resources/rnafusion_bundle_filenames.csv index 2166c811a0..ea2556bbcf 100644 --- a/cg/resources/rnafusion_bundle_filenames.csv +++ b/cg/resources/rnafusion_bundle_filenames.csv @@ -66,7 +66,7 @@ tag: multiqc-html - format: csv id: CASEID - path: PATHTOCASE/pipeline_info/samplesheet.valid.csv + path: PATHTOCASE/workflow_info/samplesheet.valid.csv path_index: ~ step: samplesheet-valid tag: samplesheet-valid diff --git a/cg/server/api.py b/cg/server/api.py index 04446cc360..52ef0b6854 100644 --- a/cg/server/api.py +++ b/cg/server/api.py @@ -219,15 +219,13 @@ def parse_families_in_collaboration(): """Return cases in collaboration.""" customer_internal_id = request.args.get("customer") - pipeline = request.args.get("data_analysis") + workflow = request.args.get("data_analysis") case_search_pattern = request.args.get("enquiry") customer = db.get_customer_by_internal_id(customer_internal_id=customer_internal_id) - cases = db.get_cases_by_customer_pipeline_and_case_search( - case_search=case_search_pattern, - customer=customer, - pipeline=pipeline, + cases = db.get_cases_by_customer_workflow_and_case_search( + customer=customer, workflow=workflow, case_search=case_search_pattern ) case_dicts = [case.to_dict(links=True) for case in cases] diff --git a/cg/store/base.py b/cg/store/base.py index 533d456a44..9d0bf2413f 100644 --- a/cg/store/base.py +++ b/cg/store/base.py @@ -141,17 +141,17 @@ def _get_filtered_case_query( if name: filter_functions.append(CaseFilter.FILTER_BY_NAME_SEARCH) if data_analysis: - filter_functions.append(CaseFilter.FILTER_BY_PIPELINE_SEARCH) + filter_functions.append(CaseFilter.FILTER_BY_WORKFLOW_SEARCH) cases_query = apply_case_filter( cases=cases_query, filter_functions=filter_functions, - order_date=filter_case_order_date, action=case_action, - priority=priority, internal_id_search=internal_id, name_search=name, - pipeline_search=data_analysis, + order_date=filter_case_order_date, + workflow_search=data_analysis, + priority=priority, ) # customer filters diff --git a/cg/store/crud/create.py b/cg/store/crud/create.py index 471a9b97f0..d8e1c6fe7d 100644 --- a/cg/store/crud/create.py +++ b/cg/store/crud/create.py @@ -135,7 +135,7 @@ def add_application_version( @staticmethod def add_application_limitation( application: Application, - pipeline: str, + workflow: str, limitations: str, comment: str = "Dummy comment", created_at: datetime = datetime.now(), @@ -145,7 +145,7 @@ def add_application_limitation( """Build a new application limitations record.""" return ApplicationLimitations( application=application, - pipeline=pipeline, + pipeline=workflow, limitations=limitations, comment=comment, created_at=created_at, @@ -267,7 +267,7 @@ def add_flow_cell( def add_analysis( self, - pipeline: Workflow, + workflow: Workflow, version: str = None, completed_at: datetime = None, primary: bool = False, @@ -277,7 +277,7 @@ def add_analysis( ) -> Analysis: """Build a new Analysis record.""" return Analysis( - pipeline=str(pipeline), + pipeline=workflow, pipeline_version=version, completed_at=completed_at, is_primary=primary, diff --git a/cg/store/crud/read.py b/cg/store/crud/read.py index a473f99c81..df5d2b1cf8 100644 --- a/cg/store/crud/read.py +++ b/cg/store/crud/read.py @@ -126,36 +126,36 @@ def get_application_by_case(self, case_id: str) -> Application: def get_application_limitations_by_tag(self, tag: str) -> list[ApplicationLimitations] | None: """Return application limitations given the application tag.""" return apply_application_limitations_filter( - application_limitations=self._get_join_application_limitations_query(), filter_functions=[ApplicationLimitationsFilter.FILTER_BY_TAG], + application_limitations=self._get_join_application_limitations_query(), tag=tag, ).all() - def get_application_limitation_by_tag_and_pipeline( - self, tag: str, pipeline: Workflow + def get_application_limitation_by_tag_and_workflow( + self, tag: str, workflow: Workflow ) -> ApplicationLimitations | None: - """Return an application limitation given the application tag and pipeline.""" + """Return an application limitation given the application tag and workflow.""" filter_functions: list[ApplicationLimitationsFilter] = [ ApplicationLimitationsFilter.FILTER_BY_TAG, - ApplicationLimitationsFilter.FILTER_BY_PIPELINE, + ApplicationLimitationsFilter.FILTER_BY_WORKFLOW, ] return apply_application_limitations_filter( - application_limitations=self._get_join_application_limitations_query(), filter_functions=filter_functions, + application_limitations=self._get_join_application_limitations_query(), tag=tag, - pipeline=pipeline, + workflow=workflow, ).first() - def get_latest_analysis_to_upload_for_pipeline(self, pipeline: str = None) -> list[Analysis]: - """Return latest not uploaded analysis for each case given a pipeline.""" + def get_latest_analysis_to_upload_for_workflow(self, workflow: str = None) -> list[Analysis]: + """Return latest not uploaded analysis for each case given a workflow.""" filter_functions: list[AnalysisFilter] = [ - AnalysisFilter.FILTER_WITH_PIPELINE, + AnalysisFilter.FILTER_WITH_WORKFLOW, AnalysisFilter.FILTER_IS_NOT_UPLOADED, ] return apply_analysis_filter( - analyses=self._get_latest_analyses_for_cases_query(), filter_functions=filter_functions, - pipeline=pipeline, + analyses=self._get_latest_analyses_for_cases_query(), + workflow=workflow, ).all() def get_analysis_by_case_entry_id_and_started_at( @@ -168,10 +168,10 @@ def get_analysis_by_case_entry_id_and_started_at( ] return apply_analysis_filter( + filter_functions=filter_functions, analyses=self._get_query(Analysis), case_entry_id=case_entry_id, started_at_date=started_at_date, - filter_functions=filter_functions, ).first() def get_cases_by_customer_and_case_name_search( @@ -233,35 +233,26 @@ def get_cases_by_customers_action_and_case_search( filtered_cases: Query = apply_case_filter( cases=self._get_query(table=Case), filter_functions=filter_functions, - customer_entry_ids=customer_entry_ids, action=action, case_search=case_search, + customer_entry_ids=customer_entry_ids, ) return filtered_cases.limit(limit=limit).all() - def get_cases_by_customer_pipeline_and_case_search( + def get_cases_by_customer_workflow_and_case_search( self, customer: Customer | None, - pipeline: str | None, + workflow: str | None, case_search: str | None, limit: int | None = 30, ) -> list[Case]: """ - Retrieve a list of cases filtered by customer, pipeline, and matching names or internal ids. - - Args: - customer (Customer | None): A customer object to filter cases by. - pipeline (str | None): The pipeline string to filter cases by. - case_search (str | None): The case search string to filter cases by. - limit (int | None, default=30): The maximum number of cases to return. - - Returns: - list[Case]: A list of filtered cases sorted by creation time and limited by the specified number. + Retrieve a list of cases filtered by customer, workflow, and matching names or internal ids. """ filter_functions: list[Callable] = [ CaseFilter.FILTER_BY_CUSTOMER_ENTRY_ID, CaseFilter.FILTER_BY_CASE_SEARCH, - CaseFilter.FILTER_WITH_PIPELINE, + CaseFilter.FILTER_WITH_WORKFLOW, CaseFilter.ORDER_BY_CREATED_AT, ] @@ -270,9 +261,9 @@ def get_cases_by_customer_pipeline_and_case_search( filtered_cases: Query = apply_case_filter( cases=self._get_query(table=Case), filter_functions=filter_functions, - customer_entry_id=customer_entry_id, case_search=case_search, - pipeline=pipeline, + customer_entry_id=customer_entry_id, + workflow=workflow, ) return filtered_cases.limit(limit=limit).all() @@ -300,9 +291,9 @@ def filter_cases_with_samples(self, case_ids: list[str]) -> list[str]: def get_cases_by_ticket_id(self, ticket_id: str) -> list[Case]: """Return cases associated with a given ticket id.""" return apply_case_filter( + cases=self._get_query(table=Case), filter_functions=[CaseFilter.FILTER_BY_TICKET], ticket_id=ticket_id, - cases=self._get_query(table=Case), ).all() def get_customer_id_from_ticket(self, ticket: str) -> str: @@ -315,9 +306,9 @@ def get_customer_id_from_ticket(self, ticket: str) -> str: def get_samples_from_ticket(self, ticket: str) -> list[Sample]: """Returns the samples related to given ticket.""" return apply_case_filter( + cases=self._get_join_sample_family_query(), filter_functions=[CaseFilter.FILTER_BY_TICKET], ticket_id=ticket, - cases=self._get_join_sample_family_query(), ).all() def get_latest_ticket_from_case(self, case_id: str) -> str: @@ -771,8 +762,8 @@ def is_case_external(self, case_id: str) -> bool: def get_case_by_internal_id(self, internal_id: str) -> Case | None: """Get case by internal id.""" return apply_case_filter( - filter_functions=[CaseFilter.FILTER_BY_INTERNAL_ID], cases=self._get_query(table=Case), + filter_functions=[CaseFilter.FILTER_BY_INTERNAL_ID], internal_id=internal_id, ).first() @@ -788,12 +779,12 @@ def verify_case_exists(self, case_internal_id: str) -> None: raise CgError LOG.info(f"Case {case_internal_id} exists in Status DB") - def get_running_cases_in_pipeline(self, pipeline: Workflow) -> list[Case]: + def get_running_cases_in_workflow(self, workflow: Workflow) -> list[Case]: """Return all running cases in a pipeline.""" return apply_case_filter( - filter_functions=[CaseFilter.FILTER_WITH_PIPELINE, CaseFilter.FILTER_IS_RUNNING], cases=self._get_query(table=Case), - pipeline=pipeline, + filter_functions=[CaseFilter.FILTER_WITH_WORKFLOW, CaseFilter.FILTER_IS_RUNNING], + workflow=workflow, ).all() def get_not_analysed_cases_by_sample_internal_id( @@ -1026,18 +1017,18 @@ def get_families_with_samples(self) -> Query: return self._get_join_cases_with_samples_query() def cases_to_analyze( - self, pipeline: Workflow = None, threshold: bool = False, limit: int = None + self, workflow: Workflow = None, threshold: bool = False, limit: int = None ) -> list[Case]: """Returns a list if cases ready to be analyzed or set to be reanalyzed.""" case_filter_functions: list[CaseFilter] = [ CaseFilter.FILTER_HAS_SEQUENCE, - CaseFilter.FILTER_WITH_PIPELINE, + CaseFilter.FILTER_WITH_WORKFLOW, CaseFilter.FILTER_FOR_ANALYSIS, ] cases = apply_case_filter( - filter_functions=case_filter_functions, cases=self.get_families_with_analyses(), - pipeline=pipeline, + filter_functions=case_filter_functions, + workflow=workflow, ) families: list[Query] = list(cases.order_by(Case.ordered_at)) @@ -1147,8 +1138,8 @@ def get_cases_to_compress(self, date_threshold: datetime) -> list[Case]: CaseFilter.FILTER_IS_COMPRESSIBLE, ] return apply_case_filter( - filter_functions=case_filter_functions, cases=self._get_query(table=Case), + filter_functions=case_filter_functions, creation_date=date_threshold, ).all() @@ -1455,10 +1446,10 @@ def _is_rerun( or (samples_sequenced_at and samples_sequenced_at < case_obj.ordered_at) ) - def get_analyses_to_upload(self, pipeline: Workflow = None) -> list[Analysis]: + def get_analyses_to_upload(self, workflow: Workflow = None) -> list[Analysis]: """Return analyses that have not been uploaded.""" analysis_filter_functions: list[AnalysisFilter] = [ - AnalysisFilter.FILTER_WITH_PIPELINE, + AnalysisFilter.FILTER_WITH_WORKFLOW, AnalysisFilter.FILTER_COMPLETED, AnalysisFilter.FILTER_IS_NOT_UPLOADED, AnalysisFilter.FILTER_VALID_IN_PRODUCTION, @@ -1467,11 +1458,11 @@ def get_analyses_to_upload(self, pipeline: Workflow = None) -> list[Analysis]: return apply_analysis_filter( filter_functions=analysis_filter_functions, analyses=self._get_join_analysis_case_query(), - pipeline=pipeline, + workflow=workflow, ).all() def get_analyses_to_clean( - self, before: datetime = datetime.now(), pipeline: Workflow = None + self, before: datetime = datetime.now(), workflow: Workflow = None ) -> list[Analysis]: """Return analyses that haven't been cleaned.""" filter_functions: list[AnalysisFilter] = [ @@ -1480,18 +1471,18 @@ def get_analyses_to_clean( AnalysisFilter.FILTER_STARTED_AT_BEFORE, AnalysisFilter.FILTER_CASE_ACTION_IS_NONE, ] - if pipeline: - filter_functions.append(AnalysisFilter.FILTER_WITH_PIPELINE) + if workflow: + filter_functions.append(AnalysisFilter.FILTER_WITH_WORKFLOW) return apply_analysis_filter( filter_functions=filter_functions, analyses=self._get_latest_analyses_for_cases_query(), - pipeline=pipeline, + workflow=workflow, started_at_date=before, ).all() - def get_analyses_for_case_and_pipeline_started_at_before( + def get_analyses_for_case_and_workflow_started_at_before( self, - pipeline: Workflow, + workflow: Workflow, started_at_before: datetime, case_internal_id: str, ) -> list[Analysis]: @@ -1500,15 +1491,15 @@ def get_analyses_for_case_and_pipeline_started_at_before( case_entry_id: int = case.id if case else None filter_functions: list[AnalysisFilter] = [ AnalysisFilter.FILTER_BY_CASE_ENTRY_ID, - AnalysisFilter.FILTER_WITH_PIPELINE, + AnalysisFilter.FILTER_WITH_WORKFLOW, AnalysisFilter.FILTER_STARTED_AT_BEFORE, ] return apply_analysis_filter( - analyses=self._get_query(table=Analysis), filter_functions=filter_functions, + analyses=self._get_query(table=Analysis), + workflow=workflow, case_entry_id=case_entry_id, started_at_date=started_at_before, - pipeline=pipeline, ).all() def get_analyses_for_case_started_at_before( @@ -1524,24 +1515,24 @@ def get_analyses_for_case_started_at_before( AnalysisFilter.FILTER_STARTED_AT_BEFORE, ] return apply_analysis_filter( - analyses=self._get_query(table=Analysis), filter_functions=filter_functions, + analyses=self._get_query(table=Analysis), case_entry_id=case_entry_id, started_at_date=started_at_before, ).all() - def get_analyses_for_pipeline_started_at_before( - self, pipeline: Workflow, started_at_before: datetime + def get_analyses_for_workflow_started_at_before( + self, workflow: Workflow, started_at_before: datetime ) -> list[Analysis]: """Return all analyses for a pipeline started before a certain date.""" filter_functions: list[AnalysisFilter] = [ - AnalysisFilter.FILTER_WITH_PIPELINE, + AnalysisFilter.FILTER_WITH_WORKFLOW, AnalysisFilter.FILTER_STARTED_AT_BEFORE, ] return apply_analysis_filter( filter_functions=filter_functions, analyses=self._get_query(table=Analysis), - pipeline=pipeline, + workflow=workflow, started_at_date=started_at_before, ).all() @@ -1553,27 +1544,27 @@ def get_analyses_started_at_before(self, started_at_before: datetime) -> list[An started_at_date=started_at_before, ).all() - def observations_to_upload(self, pipeline: Workflow = None) -> Query: + def observations_to_upload(self, workflow: Workflow = None) -> Query: """Return observations that have not been uploaded.""" case_filter_functions: list[CaseFilter] = [ - CaseFilter.FILTER_WITH_LOQUSDB_SUPPORTED_PIPELINE, + CaseFilter.FILTER_WITH_LOQUSDB_SUPPORTED_WORKFLOW, CaseFilter.FILTER_WITH_LOQUSDB_SUPPORTED_SEQUENCING_METHOD, ] records: Query = apply_case_filter( - filter_functions=case_filter_functions, cases=self.get_families_with_samples(), - pipeline=pipeline, + filter_functions=case_filter_functions, + workflow=workflow, ) return apply_sample_filter( filter_functions=[SampleFilter.FILTER_WITHOUT_LOQUSDB_ID], samples=records ) - def observations_uploaded(self, pipeline: Workflow = None) -> Query: + def observations_uploaded(self, workflow: Workflow = None) -> Query: """Return observations that have been uploaded.""" records: Query = apply_case_filter( - filter_functions=[CaseFilter.FILTER_WITH_LOQUSDB_SUPPORTED_PIPELINE], cases=self.get_families_with_samples(), - pipeline=pipeline, + filter_functions=[CaseFilter.FILTER_WITH_LOQUSDB_SUPPORTED_WORKFLOW], + workflow=workflow, ) records: Query = apply_sample_filter( filter_functions=[SampleFilter.FILTER_WITH_LOQUSDB_ID], samples=records @@ -1583,7 +1574,7 @@ def observations_uploaded(self, pipeline: Workflow = None) -> Query: def get_analyses(self) -> list[Analysis]: return self._get_query(table=Analysis).all() - def get_analyses_to_deliver_for_pipeline(self, pipeline: Workflow = None) -> list[Analysis]: + def get_analyses_to_deliver_for_pipeline(self, workflow: Workflow = None) -> list[Analysis]: """Return analyses that have been uploaded but not delivered.""" analyses: Query = apply_sample_filter( samples=self._get_join_analysis_sample_family_query(), @@ -1591,46 +1582,44 @@ def get_analyses_to_deliver_for_pipeline(self, pipeline: Workflow = None) -> lis ) filter_functions: list[AnalysisFilter] = [ AnalysisFilter.FILTER_IS_NOT_UPLOADED, - AnalysisFilter.FILTER_WITH_PIPELINE, + AnalysisFilter.FILTER_WITH_WORKFLOW, AnalysisFilter.ORDER_BY_UPLOADED_AT, ] return apply_analysis_filter( - analyses=analyses, filter_functions=filter_functions, pipeline=pipeline + filter_functions=filter_functions, analyses=analyses, workflow=workflow ).all() - def analyses_to_delivery_report(self, pipeline: Workflow = None) -> Query: + def analyses_to_delivery_report(self, workflow: Workflow | None = None) -> Query: """Return analyses that need a delivery report to be regenerated.""" records: Query = apply_case_filter( - filter_functions=[CaseFilter.FILTER_REPORT_SUPPORTED], cases=self._get_join_analysis_case_query(), - pipeline=pipeline, + filter_functions=[CaseFilter.FILTER_REPORT_SUPPORTED], ) analysis_filter_functions: list[AnalysisFilter] = [ - AnalysisFilter.FILTER_REPORT_BY_PIPELINE, + AnalysisFilter.FILTER_REPORT_BY_WORKFLOW, AnalysisFilter.FILTER_WITHOUT_DELIVERY_REPORT, AnalysisFilter.FILTER_VALID_IN_PRODUCTION, AnalysisFilter.ORDER_BY_COMPLETED_AT, ] return apply_analysis_filter( - filter_functions=analysis_filter_functions, analyses=records, pipeline=pipeline + filter_functions=analysis_filter_functions, analyses=records, workflow=workflow ) - def analyses_to_upload_delivery_reports(self, pipeline: Workflow = None) -> Query: + def analyses_to_upload_delivery_reports(self, workflow: Workflow = None) -> Query: """Return analyses that need a delivery report to be uploaded.""" records: Query = apply_case_filter( - filter_functions=[CaseFilter.FILTER_WITH_SCOUT_DELIVERY], cases=self._get_join_analysis_case_query(), - pipeline=pipeline, + filter_functions=[CaseFilter.FILTER_WITH_SCOUT_DELIVERY], ) analysis_filter_functions: list[AnalysisFilter] = [ - AnalysisFilter.FILTER_REPORT_BY_PIPELINE, + AnalysisFilter.FILTER_REPORT_BY_WORKFLOW, AnalysisFilter.FILTER_WITH_DELIVERY_REPORT, AnalysisFilter.FILTER_IS_NOT_UPLOADED, AnalysisFilter.FILTER_VALID_IN_PRODUCTION, AnalysisFilter.ORDER_BY_COMPLETED_AT, ] return apply_analysis_filter( - filter_functions=analysis_filter_functions, analyses=records, pipeline=pipeline + filter_functions=analysis_filter_functions, analyses=records, workflow=workflow ) def get_samples_to_deliver(self) -> list[Sample]: diff --git a/cg/store/filters/status_analysis_filters.py b/cg/store/filters/status_analysis_filters.py index 499a742c0f..56c4a315a7 100644 --- a/cg/store/filters/status_analysis_filters.py +++ b/cg/store/filters/status_analysis_filters.py @@ -4,7 +4,7 @@ from sqlalchemy.orm import Query -from cg.constants import REPORT_SUPPORTED_PIPELINES +from cg.constants import REPORT_SUPPORTED_WORKFLOW from cg.constants.constants import VALID_DATA_IN_PRODUCTION, Workflow from cg.store.models import Analysis, Case @@ -14,9 +14,9 @@ def filter_valid_analyses_in_production(analyses: Query, **kwargs) -> Query: return analyses.filter(VALID_DATA_IN_PRODUCTION < Analysis.completed_at) -def filter_analyses_with_pipeline(analyses: Query, pipeline: Workflow = None, **kwargs) -> Query: - """Return analyses with supplied pipeline.""" - return analyses.filter(Analysis.pipeline == str(pipeline)) if pipeline else analyses +def filter_analyses_with_workflow(analyses: Query, workflow: Workflow = None, **kwargs) -> Query: + """Return analyses with supplied workflow.""" + return analyses.filter(Analysis.pipeline == workflow) if workflow else analyses def filter_completed_analyses(analyses: Query, **kwargs) -> Query: @@ -44,14 +44,14 @@ def filter_analyses_without_delivery_report(analyses: Query, **kwargs) -> Query: return analyses.filter(Analysis.delivery_report_created_at.is_(None)) -def filter_report_analyses_by_pipeline( - analyses: Query, pipeline: Workflow = None, **kwargs +def filter_report_analyses_by_workflow( + analyses: Query, workflow: Workflow = None, **kwargs ) -> Query: - """Return the delivery report related analyses associated to the provided or supported pipelines.""" + """Return the delivery report related analyses associated to the provided or supported workflows.""" return ( - analyses.filter(Analysis.pipeline == str(pipeline)) - if pipeline - else analyses.filter(Analysis.pipeline.in_(REPORT_SUPPORTED_PIPELINES)) + analyses.filter(Analysis.pipeline == workflow) + if workflow + else analyses.filter(Analysis.pipeline.in_(REPORT_SUPPORTED_WORKFLOW)) ) @@ -93,7 +93,7 @@ def filter_analysis_case_action_is_none(analyses: Query, **kwargs) -> Query: def apply_analysis_filter( filter_functions: list[Callable], analyses: Query, - pipeline: Workflow = None, + workflow: Workflow = None, case_entry_id: int = None, completed_at_date: datetime = None, started_at_date: datetime = None, @@ -103,7 +103,7 @@ def apply_analysis_filter( for filter_function in filter_functions: analyses: Query = filter_function( analyses=analyses, - pipeline=pipeline, + workflow=workflow, case_entry_id=case_entry_id, completed_at_date=completed_at_date, started_at_date=started_at_date, @@ -115,13 +115,13 @@ class AnalysisFilter(Enum): """Define Analysis filter functions.""" FILTER_VALID_IN_PRODUCTION: Callable = filter_valid_analyses_in_production - FILTER_WITH_PIPELINE: Callable = filter_analyses_with_pipeline + FILTER_WITH_WORKFLOW: Callable = filter_analyses_with_workflow FILTER_COMPLETED: Callable = filter_completed_analyses FILTER_IS_UPLOADED: Callable = filter_uploaded_analyses FILTER_IS_NOT_UPLOADED: Callable = filter_not_uploaded_analyses FILTER_WITH_DELIVERY_REPORT: Callable = filter_analyses_with_delivery_report FILTER_WITHOUT_DELIVERY_REPORT: Callable = filter_analyses_without_delivery_report - FILTER_REPORT_BY_PIPELINE: Callable = filter_report_analyses_by_pipeline + FILTER_REPORT_BY_WORKFLOW: Callable = filter_report_analyses_by_workflow FILTER_BY_CASE_ENTRY_ID: Callable = filter_analyses_by_case_entry_id FILTER_IS_NOT_CLEANED: Callable = filter_analyses_not_cleaned FILTER_STARTED_AT_BEFORE: Callable = filter_analyses_started_before diff --git a/cg/store/filters/status_application_limitations_filters.py b/cg/store/filters/status_application_limitations_filters.py index 69f7e8cb56..d148504730 100644 --- a/cg/store/filters/status_application_limitations_filters.py +++ b/cg/store/filters/status_application_limitations_filters.py @@ -14,25 +14,25 @@ def filter_application_limitations_by_tag( return application_limitations.filter(Application.tag == tag) -def filter_application_limitations_by_pipeline( - application_limitations: Query, pipeline: Workflow, **kwargs +def filter_application_limitations_by_workflow( + application_limitations: Query, workflow: Workflow, **kwargs ) -> Query: - """Return application limitations by pipeline.""" - return application_limitations.filter(ApplicationLimitations.pipeline == pipeline) + """Return application limitations by workflow.""" + return application_limitations.filter(ApplicationLimitations.pipeline == workflow) def apply_application_limitations_filter( filter_functions: list[Callable], application_limitations: Query, tag: str = None, - pipeline: Workflow = None, + workflow: Workflow = None, ) -> Query: """Apply filtering functions to the application limitations queries and return filtered results.""" for filter_function in filter_functions: application_limitations: Query = filter_function( application_limitations=application_limitations, tag=tag, - pipeline=pipeline, + workflow=workflow, ) return application_limitations @@ -41,4 +41,4 @@ class ApplicationLimitationsFilter(Enum): """Define ApplicationLimitations filter functions.""" FILTER_BY_TAG = filter_application_limitations_by_tag - FILTER_BY_PIPELINE = filter_application_limitations_by_pipeline + FILTER_BY_WORKFLOW = filter_application_limitations_by_workflow diff --git a/cg/store/filters/status_case_filters.py b/cg/store/filters/status_case_filters.py index 231523f01a..4fa2610963 100644 --- a/cg/store/filters/status_case_filters.py +++ b/cg/store/filters/status_case_filters.py @@ -10,7 +10,7 @@ from cg.constants.observations import ( LOQUSDB_BALSAMIC_SEQUENCING_METHODS, LOQUSDB_MIP_SEQUENCING_METHODS, - LOQUSDB_SUPPORTED_PIPELINES, + LOQUSDB_SUPPORTED_WORKFLOWS, ) from cg.store.models import Analysis, Application, Case, Customer, Sample @@ -71,9 +71,9 @@ def filter_cases_by_name_search(cases: Query, name_search: str, **kwargs) -> Que return cases.filter(Case.name.like(f"%{name_search}%")) -def filter_cases_by_pipeline_search(cases: Query, pipeline_search: str, **kwargs) -> Query: - """Filter cases with pipeline search pattern.""" - return cases.filter(Case.data_analysis.ilike(f"%{pipeline_search}%")) +def filter_cases_by_workflow_search(cases: Query, workflow_search: str, **kwargs) -> Query: + """Filter cases with a workflow search pattern.""" + return cases.filter(Case.data_analysis.ilike(f"%{workflow_search}%")) def filter_cases_by_priority(cases: Query, priority: str, **kwargs) -> Query: @@ -109,7 +109,7 @@ def filter_cases_for_analysis(cases: Query, **kwargs) -> Query: def filter_cases_has_sequence(cases: Query, **kwargs) -> Query: - """Filter cases that is not sequenced according to record in StatusDB.""" + """Filter cases that are not sequenced according to record in StatusDB.""" return cases.filter(or_(Application.is_external, Sample.last_sequenced_at.isnot(None))) @@ -121,25 +121,25 @@ def filter_cases_not_analysed(cases: Query, **kwargs) -> Query: return cases.filter(and_(not_analyzed_condition, not_in_progress_condition)) -def filter_cases_with_pipeline(cases: Query, pipeline: Workflow = None, **kwargs) -> Query: - """Filter cases with pipeline.""" - return cases.filter(Case.data_analysis == pipeline) if pipeline else cases +def filter_cases_with_workflow(cases: Query, workflow: Workflow = None, **kwargs) -> Query: + """Filter cases with workflow.""" + return cases.filter(Case.data_analysis == workflow) if workflow else cases -def filter_cases_with_loqusdb_supported_pipeline( - cases: Query, pipeline: Workflow = None, **kwargs +def filter_cases_with_loqusdb_supported_workflow( + cases: Query, workflow: Workflow = None, **kwargs ) -> Query: - """Filter Loqusdb related cases with pipeline.""" + """Filter Loqusdb related cases with workflow.""" records: Query = ( - cases.filter(Case.data_analysis == pipeline) - if pipeline - else cases.filter(Case.data_analysis.in_(LOQUSDB_SUPPORTED_PIPELINES)) + cases.filter(Case.data_analysis == workflow) + if workflow + else cases.filter(Case.data_analysis.in_(LOQUSDB_SUPPORTED_WORKFLOWS)) ) return records.filter(Customer.loqus_upload == True) def filter_cases_with_loqusdb_supported_sequencing_method( - cases: Query, pipeline: Workflow = None, **kwargs + cases: Query, workflow: Workflow = None, **kwargs ) -> Query: """Filter cases with Loqusdb supported sequencing method.""" supported_sequencing_methods = { @@ -147,8 +147,8 @@ def filter_cases_with_loqusdb_supported_sequencing_method( Workflow.BALSAMIC: LOQUSDB_BALSAMIC_SEQUENCING_METHODS, } return ( - cases.filter(Application.prep_category.in_(supported_sequencing_methods[pipeline])) - if pipeline + cases.filter(Application.prep_category.in_(supported_sequencing_methods[workflow])) + if workflow else cases ) @@ -214,8 +214,8 @@ def apply_case_filter( name: str | None = None, name_search: str | None = None, order_date: datetime | None = None, - pipeline: Workflow | None = None, - pipeline_search: str | None = None, + workflow: Workflow | None = None, + workflow_search: str | None = None, priority: str | None = None, ticket_id: str | None = None, ) -> Query: @@ -234,8 +234,8 @@ def apply_case_filter( name=name, name_search=name_search, order_date=order_date, - pipeline=pipeline, - pipeline_search=pipeline_search, + workflow=workflow, + workflow_search=workflow_search, priority=priority, ticket_id=ticket_id, ) @@ -254,7 +254,7 @@ class CaseFilter(Enum): FILTER_BY_INTERNAL_ID_SEARCH: Callable = filter_cases_by_internal_id_search FILTER_BY_NAME: Callable = filter_cases_by_name FILTER_BY_NAME_SEARCH: Callable = filter_cases_by_name_search - FILTER_BY_PIPELINE_SEARCH: Callable = filter_cases_by_pipeline_search + FILTER_BY_WORKFLOW_SEARCH: Callable = filter_cases_by_workflow_search FILTER_BY_PRIORITY: Callable = filter_cases_by_priority FILTER_BY_TICKET: Callable = filter_cases_by_ticket_id FILTER_FOR_ANALYSIS: Callable = filter_cases_for_analysis @@ -266,10 +266,10 @@ class CaseFilter(Enum): FILTER_NOT_ANALYSED: Callable = filter_cases_not_analysed FILTER_OLD_BY_CREATION_DATE: Callable = filter_older_cases_by_creation_date FILTER_REPORT_SUPPORTED: Callable = filter_report_supported_data_delivery_cases - FILTER_WITH_LOQUSDB_SUPPORTED_PIPELINE: Callable = filter_cases_with_loqusdb_supported_pipeline + FILTER_WITH_LOQUSDB_SUPPORTED_WORKFLOW: Callable = filter_cases_with_loqusdb_supported_workflow FILTER_WITH_LOQUSDB_SUPPORTED_SEQUENCING_METHOD: Callable = ( filter_cases_with_loqusdb_supported_sequencing_method ) - FILTER_WITH_PIPELINE: Callable = filter_cases_with_pipeline + FILTER_WITH_WORKFLOW: Callable = filter_cases_with_workflow FILTER_WITH_SCOUT_DELIVERY: Callable = filter_cases_with_scout_data_delivery ORDER_BY_CREATED_AT: Callable = order_cases_by_created_at diff --git a/cg/store/models.py b/cg/store/models.py index 972f2bc700..f69332e4c6 100644 --- a/cg/store/models.py +++ b/cg/store/models.py @@ -496,16 +496,16 @@ def slurm_priority(self) -> SlurmQos: return SlurmQos(slurm_priority) def get_delivery_arguments(self) -> set[str]: - """Translates the case data_delivery field to pipeline specific arguments.""" + """Translates the case data_delivery field to workflow specific arguments.""" delivery_arguments: set[str] = set() requested_deliveries: list[str] = re.split("[-_]", self.data_delivery) - delivery_per_pipeline_map: dict[str, str] = { + delivery_per_workflow_map: dict[str, str] = { DataDelivery.FASTQ: Workflow.FASTQ, DataDelivery.ANALYSIS_FILES: self.data_analysis, } - for data_delivery, pipeline in delivery_per_pipeline_map.items(): + for data_delivery, workflow in delivery_per_workflow_map.items(): if data_delivery in requested_deliveries: - delivery_arguments.add(pipeline) + delivery_arguments.add(workflow) return delivery_arguments def to_dict(self, links: bool = False, analyses: bool = False) -> dict: diff --git a/tests/cli/clean/conftest.py b/tests/cli/clean/conftest.py index f065402b58..4e389ca755 100644 --- a/tests/cli/clean/conftest.py +++ b/tests/cli/clean/conftest.py @@ -63,10 +63,10 @@ def clean_context( helpers.add_analysis( store, case=case_to_clean, - pipeline=Workflow.BALSAMIC, started_at=timestamp_yesterday, uploaded_at=timestamp_yesterday, cleaned_at=None, + workflow=Workflow.BALSAMIC, ) Path(analysis_api.get_case_path(balsamic_case_clean)).mkdir(exist_ok=True, parents=True) @@ -88,10 +88,10 @@ def clean_context( helpers.add_analysis( store, case=case_to_not_clean, - pipeline=Workflow.BALSAMIC, started_at=timestamp_yesterday, uploaded_at=timestamp_yesterday, cleaned_at=None, + workflow=Workflow.BALSAMIC, ) Path(analysis_api.get_case_path(balsamic_case_not_clean)).mkdir(exist_ok=True, parents=True) cg_context.meta_apis["analysis_api"] = analysis_api @@ -159,10 +159,10 @@ def clean_context_microsalt( helpers.add_analysis( store, case=case_to_clean, - pipeline=Workflow.MICROSALT, started_at=timestamp_yesterday, uploaded_at=timestamp_yesterday, cleaned_at=None, + workflow=Workflow.MICROSALT, ) case_path_list = analysis_api.get_case_path(microsalt_case_clean) for path in case_path_list: @@ -186,10 +186,10 @@ def clean_context_microsalt( helpers.add_analysis( store, case=case_to_clean_dry_run, - pipeline=Workflow.MICROSALT, started_at=timestamp_yesterday, uploaded_at=timestamp_yesterday, cleaned_at=None, + workflow=Workflow.MICROSALT, ) case_path_list = analysis_api.get_case_path(microsalt_case_clean_dry) diff --git a/tests/cli/clean/test_balsamic_clean.py b/tests/cli/clean/test_balsamic_clean.py index 7b1fef0f4c..20c11f6bb4 100644 --- a/tests/cli/clean/test_balsamic_clean.py +++ b/tests/cli/clean/test_balsamic_clean.py @@ -82,10 +82,10 @@ def test_dry_run( base_store = clean_context.status_db helpers.add_analysis( base_store, - pipeline=Workflow.BALSAMIC, started_at=timestamp_yesterday, uploaded_at=timestamp_yesterday, cleaned_at=None, + workflow=Workflow.BALSAMIC, ) analysis_to_clean = base_store.get_case_by_internal_id(balsamic_case_clean).analyses[0] @@ -101,7 +101,7 @@ def test_dry_run( assert result.exit_code == EXIT_SUCCESS assert "Would have deleted" in caplog.text assert balsamic_case_clean in caplog.text - assert analysis_to_clean in base_store.get_analyses_to_clean(pipeline=Workflow.BALSAMIC) + assert analysis_to_clean in base_store.get_analyses_to_clean(workflow=Workflow.BALSAMIC) def test_cleaned_at_valid( diff --git a/tests/cli/clean/test_hk_bundle_files.py b/tests/cli/clean/test_hk_bundle_files.py index 79509e49fd..114d553350 100644 --- a/tests/cli/clean/test_hk_bundle_files.py +++ b/tests/cli/clean/test_hk_bundle_files.py @@ -12,7 +12,8 @@ def test_clean_hk_bundle_files_no_files(cli_runner: CliRunner, cg_context: CGCon # GIVEN a housekeeper api and a bundle without files bundle_name = "non_existing" assert not cg_context.housekeeper_api.bundle(bundle_name) - case = cg_context.status_db.get_case_by_internal_id(bundle_name) + cg_context.status_db.get_case_by_internal_id(bundle_name) + # WHEN running the clean hk alignment files command caplog.set_level(logging.INFO) result = cli_runner.invoke( @@ -22,7 +23,7 @@ def test_clean_hk_bundle_files_no_files(cli_runner: CliRunner, cg_context: CGCon # THEN assert it exits with success assert result.exit_code == 0 # THEN assert it was communicated that no files where found - assert f"Process freed 0.0GB. Dry run: False" in caplog.text + assert "Process freed 0.0GB. Dry run: False" in caplog.text def test_clean_hk_bundle_files_dry_run( @@ -31,7 +32,6 @@ def test_clean_hk_bundle_files_dry_run( cg_context: CGConfig, cli_runner: CliRunner, helpers: StoreHelpers, - mocker, timestamp: datetime, ): # GIVEN a housekeeper api with some alignment files diff --git a/tests/cli/clean/test_hk_case_bundle_files.py b/tests/cli/clean/test_hk_case_bundle_files.py index 22c228e33b..328a279937 100644 --- a/tests/cli/clean/test_hk_case_bundle_files.py +++ b/tests/cli/clean/test_hk_case_bundle_files.py @@ -72,10 +72,10 @@ def test_clean_hk_case_files_single_analysis( store: Store = context.status_db days_ago: int = 1 date_days_ago: dt.datetime = get_date_days_ago(days_ago) - pipeline: Workflow = Workflow.MIP_DNA + workflow: Workflow = Workflow.MIP_DNA analysis: Analysis = helpers.add_analysis( - store=store, started_at=date_days_ago, completed_at=date_days_ago, pipeline=pipeline + store=store, started_at=date_days_ago, completed_at=date_days_ago, workflow=workflow ) bundle_name: str = analysis.case.internal_id @@ -111,15 +111,15 @@ def test_clean_hk_case_files_analysis_with_protected_tag( store: Store = context.status_db days_ago: int = 1 date_days_ago: dt.datetime = get_date_days_ago(days_ago) - pipeline: Workflow = Workflow.MIP_DNA + workflow: Workflow = Workflow.MIP_DNA analysis: Analysis = helpers.add_analysis( - store=store, started_at=date_days_ago, completed_at=date_days_ago, pipeline=pipeline + store=store, started_at=date_days_ago, completed_at=date_days_ago, workflow=workflow ) bundle_name: str = analysis.case.internal_id # GIVEN a housekeeper api with some file with protected tags - protected_tags = WORKFLOW_PROTECTED_TAGS[pipeline][0] + protected_tags = WORKFLOW_PROTECTED_TAGS[workflow][0] hk_bundle_data["name"] = bundle_name hk_bundle_data["files"][0]["tags"] = protected_tags helpers.ensure_hk_bundle(cg_context.housekeeper_api, bundle_data=hk_bundle_data) diff --git a/tests/cli/clean/test_microbial_clean.py b/tests/cli/clean/test_microbial_clean.py index cc4007107c..1fe668d444 100644 --- a/tests/cli/clean/test_microbial_clean.py +++ b/tests/cli/clean/test_microbial_clean.py @@ -29,10 +29,10 @@ def test_dry_run( base_store = clean_context_microsalt.status_db helpers.add_analysis( base_store, - pipeline=Workflow.MICROSALT, started_at=timestamp_yesterday, uploaded_at=timestamp_yesterday, cleaned_at=None, + workflow=Workflow.MICROSALT, ) analysis_to_clean = base_store.get_case_by_internal_id(microsalt_case_clean_dry).analyses[0] @@ -58,7 +58,7 @@ def test_dry_run( # THEN the analysis should still be in the analyses_to_clean query since this is a dry-ryn assert analysis_to_clean.cleaned_at == None - assert analysis_to_clean in base_store.get_analyses_to_clean(pipeline=Workflow.MICROSALT) + assert analysis_to_clean in base_store.get_analyses_to_clean(workflow=Workflow.MICROSALT) def test_clean_run( @@ -77,10 +77,10 @@ def test_clean_run( base_store = clean_context_microsalt.status_db helpers.add_analysis( base_store, - pipeline=Workflow.MICROSALT, started_at=timestamp_yesterday, uploaded_at=timestamp_yesterday, cleaned_at=None, + workflow=Workflow.MICROSALT, ) analysis_to_clean = base_store.get_case_by_internal_id(microsalt_case_clean).analyses[0] @@ -106,4 +106,4 @@ def test_clean_run( # THEN the analysis should no longer be in the analyses_to_clean query assert isinstance(analysis_to_clean.cleaned_at, dt.datetime) - assert analysis_to_clean not in base_store.get_analyses_to_clean(pipeline=Workflow.MICROSALT) + assert analysis_to_clean not in base_store.get_analyses_to_clean(workflow=Workflow.MICROSALT) diff --git a/tests/cli/generate/report/conftest.py b/tests/cli/generate/report/conftest.py index 36a8d4b137..3b8651b463 100644 --- a/tests/cli/generate/report/conftest.py +++ b/tests/cli/generate/report/conftest.py @@ -36,9 +36,9 @@ def mip_dna_context(cg_context, helpers, case_id, real_housekeeper_api) -> CGCon helpers.add_analysis( store=store, case=case, - pipeline=Workflow.MIP_DNA, - delivery_reported_at=datetime.now(), started_at=datetime.now(), + delivery_reported_at=datetime.now(), + workflow=Workflow.MIP_DNA, ) helpers.add_relationship( store=store, diff --git a/tests/cli/generate/report/test_utils.py b/tests/cli/generate/report/test_utils.py index 1717801fd4..b114f20bca 100644 --- a/tests/cli/generate/report/test_utils.py +++ b/tests/cli/generate/report/test_utils.py @@ -8,7 +8,7 @@ from cg.cli.generate.report.utils import ( get_report_analysis_started, get_report_api, - get_report_api_pipeline, + get_report_api_workflow, get_report_case, ) from cg.constants import Workflow @@ -54,14 +54,14 @@ def test_get_report_api(delivery_report_click_context, cg_context, case_id): assert isinstance(report_api, MockMipDNAReportAPI) -def test_get_report_api_pipeline(delivery_report_click_context): - """Tests API assignment given a specific pipeline""" +def test_get_report_api_workflow(delivery_report_click_context): + """Tests API assignment given a specific workflow.""" - # GIVEN a click context and a specific pipeline - pipeline = Workflow.BALSAMIC_UMI + # GIVEN a click context and a specific workflow + workflow = Workflow.BALSAMIC_UMI # WHEN validating a report api - report_api = get_report_api_pipeline(delivery_report_click_context, pipeline) + report_api = get_report_api_workflow(delivery_report_click_context, workflow) # THEN the extracted API should match the expected type assert report_api diff --git a/tests/cli/upload/conftest.py b/tests/cli/upload/conftest.py index b4e8b7e64d..1568c7398f 100644 --- a/tests/cli/upload/conftest.py +++ b/tests/cli/upload/conftest.py @@ -253,7 +253,7 @@ def __init__(self, **kwargs): def _request_analysis(self, analysis_store_single_case): self.analysis = analysis_store_single_case - def generate_config(self, analysis_obj, **kwargs): + def generate_config(self, analysis, **kwargs): """Mock the generate config""" if self.missing_mandatory_field: self.config.vcf_snv = None diff --git a/tests/cli/upload/test_cli_scout.py b/tests/cli/upload/test_cli_scout.py index d53eb8245e..4c6bd78fcd 100644 --- a/tests/cli/upload/test_cli_scout.py +++ b/tests/cli/upload/test_cli_scout.py @@ -23,7 +23,7 @@ def test_get_upload_api(cg_context: CGConfig, case_id: str, helpers: StoreHelper case: Case = helpers.ensure_case( store=status_db, data_analysis=Workflow.BALSAMIC, case_id=case_id ) - helpers.add_analysis(store=status_db, pipeline=Workflow.BALSAMIC, case=case) + helpers.add_analysis(store=status_db, case=case, workflow=Workflow.BALSAMIC) # WHEN getting the upload API upload_api: UploadAPI = get_upload_api(cg_config=cg_context, case=case) @@ -47,7 +47,7 @@ def test_create_scout_load_config( case: Case = helpers.ensure_case( store=status_db, data_analysis=Workflow.BALSAMIC, case_id=case_id ) - helpers.add_analysis(store=status_db, pipeline=Workflow.BALSAMIC, case=case) + helpers.add_analysis(store=status_db, case=case, workflow=Workflow.BALSAMIC) with mock.patch.object(UploadScoutAPI, "generate_config", return_value=MockScoutLoadConfig()): # WHEN creating the scout load config diff --git a/tests/cli/upload/test_cli_upload.py b/tests/cli/upload/test_cli_upload.py index f665f6c098..3c422f6fdd 100644 --- a/tests/cli/upload/test_cli_upload.py +++ b/tests/cli/upload/test_cli_upload.py @@ -24,7 +24,7 @@ def test_upload_started_long_time_ago_raises_exception( case_id = case.internal_id today = datetime.now() upload_started = today - timedelta(hours=100) - helpers.add_analysis(disk_store, case=case, uploading=True, upload_started=upload_started) + helpers.add_analysis(disk_store, case=case, upload_started=upload_started, uploading=True) # WHEN trying to upload an analysis that was started a long time ago result = cli_runner.invoke(upload, ["-f", case_id], obj=base_context) diff --git a/tests/cli/upload/test_cli_upload_auto.py b/tests/cli/upload/test_cli_upload_auto.py index a30e8cd275..8c15bdd0ca 100644 --- a/tests/cli/upload/test_cli_upload_auto.py +++ b/tests/cli/upload/test_cli_upload_auto.py @@ -21,10 +21,10 @@ def test_upload_auto_with_pipeline_as_argument( """Test upload auto""" # GIVEN a store with a MIP analysis pipeline = Workflow.MIP_DNA - helpers.add_analysis(store=upload_context.status_db, completed_at=timestamp, pipeline=pipeline) + helpers.add_analysis(store=upload_context.status_db, completed_at=timestamp, workflow=pipeline) - # WHEN uploading all analysis from pipeline MIP + # WHEN uploading all analysis from workflow MIP caplog.set_level(logging.INFO) - cli_runner.invoke(upload_all_completed_analyses, ["--pipeline", "mip-dna"], obj=upload_context) + cli_runner.invoke(upload_all_completed_analyses, ["--workflow", "mip-dna"], obj=upload_context) # THEN assert that the MIP analysis was successfully uploaded assert "Uploading analysis for case" in caplog.text diff --git a/tests/cli/upload/test_cli_upload_nipt.py b/tests/cli/upload/test_cli_upload_nipt.py index 77404560bf..44883b7438 100644 --- a/tests/cli/upload/test_cli_upload_nipt.py +++ b/tests/cli/upload/test_cli_upload_nipt.py @@ -113,7 +113,7 @@ def test_nipt_statina_upload_auto( analysis_obj: Analysis = helpers.add_analysis( store=upload_context.status_db, completed_at=datetime.datetime.now(), - pipeline=Workflow.FLUFFY, + workflow=Workflow.FLUFFY, ) assert analysis_obj.completed_at assert not analysis_obj.uploaded_at @@ -173,7 +173,7 @@ def test_nipt_statina_upload_auto_analysis_without_case( analysis_obj: Analysis = helpers.add_analysis( store=upload_context.status_db, completed_at=datetime.datetime.now(), - pipeline=Workflow.FLUFFY, + workflow=Workflow.FLUFFY, ) analysis_obj.case = None mocker.patch.object(NiptUploadAPI, "get_all_upload_analyses", return_value=[analysis_obj]) @@ -195,7 +195,7 @@ def test_nipt_statina_upload_auto_dry_run( analysis_obj: Analysis = helpers.add_analysis( store=upload_context.status_db, completed_at=datetime.datetime.now(), - pipeline=Workflow.FLUFFY, + workflow=Workflow.FLUFFY, ) assert analysis_obj.completed_at assert not analysis_obj.uploaded_at diff --git a/tests/cli/workflow/balsamic/conftest.py b/tests/cli/workflow/balsamic/conftest.py index c832891c84..32b5ecb113 100644 --- a/tests/cli/workflow/balsamic/conftest.py +++ b/tests/cli/workflow/balsamic/conftest.py @@ -835,7 +835,7 @@ def mock_deliverable(balsamic_dir: Path, deliverable_data: dict, balsamic_case_i @pytest.fixture def hermes_deliverables(deliverable_data: dict, balsamic_case_id: str) -> dict: - hermes_output: dict = {"pipeline": "balsamic", "bundle_id": balsamic_case_id, "files": []} + hermes_output: dict = {"workflow": "balsamic", "bundle_id": balsamic_case_id, "files": []} for file_info in deliverable_data["files"]: tags: list[str] = [] if "html" in file_info["format"]: @@ -851,7 +851,7 @@ def hermes_deliverables(deliverable_data: dict, balsamic_case_id: str) -> dict: @pytest.fixture def malformed_hermes_deliverables(hermes_deliverables: dict) -> dict: malformed_deliverable = hermes_deliverables.copy() - malformed_deliverable.pop("pipeline") + malformed_deliverable.pop("workflow") return malformed_deliverable diff --git a/tests/cli/workflow/balsamic/test_compound_commands.py b/tests/cli/workflow/balsamic/test_compound_commands.py index dc4a12177f..9d2bdea6d2 100644 --- a/tests/cli/workflow/balsamic/test_compound_commands.py +++ b/tests/cli/workflow/balsamic/test_compound_commands.py @@ -5,7 +5,13 @@ from cg.apps.hermes.hermes_api import HermesApi from cg.apps.hermes.models import CGDeliverables -from cg.cli.workflow.balsamic.base import balsamic, start, start_available, store, store_available +from cg.cli.workflow.balsamic.base import ( + balsamic, + start, + start_available, + store, + store_available, +) from cg.meta.workflow.balsamic import BalsamicAnalysisAPI from cg.models.cg_config import CGConfig @@ -73,7 +79,7 @@ def test_store( # Make sure the bundle was not present in the store assert not balsamic_context.housekeeper_api.bundle(case_id) - # Make sure analysis not already stored in ClinicalDB + # Make sure analysis not already stored in ClinicalDB assert not balsamic_context.status_db.get_case_by_internal_id(internal_id=case_id).analyses # GIVEN that HermesAPI returns a deliverables output diff --git a/tests/cli/workflow/balsamic/test_store_housekeeper.py b/tests/cli/workflow/balsamic/test_store_housekeeper.py index c3030cdcd1..fef680276b 100644 --- a/tests/cli/workflow/balsamic/test_store_housekeeper.py +++ b/tests/cli/workflow/balsamic/test_store_housekeeper.py @@ -105,7 +105,7 @@ def test_case_with_malformed_deliverables_file( # GIVEN that the output is malformed with pytest.raises(ValidationError): analysis_api.hermes_api.convert_deliverables( - deliverables_file=Path("a_file"), pipeline="balsamic" + deliverables_file=Path("a_file"), workflow="balsamic" ) # GIVEN case-id diff --git a/tests/cli/workflow/rnafusion/test_cli_rnafusion_store_housekeeper.py b/tests/cli/workflow/rnafusion/test_cli_rnafusion_store_housekeeper.py index c9ee5d0f52..bc18db0efe 100644 --- a/tests/cli/workflow/rnafusion/test_cli_rnafusion_store_housekeeper.py +++ b/tests/cli/workflow/rnafusion/test_cli_rnafusion_store_housekeeper.py @@ -101,7 +101,7 @@ def test_case_with_malformed_deliverables_file( # GIVEN that the output is malformed with pytest.raises(ValidationError): analysis_api.hermes_api.convert_deliverables( - deliverables_file=Path("a_file"), pipeline="rnafusion" + deliverables_file=Path("a_file"), workflow="rnafusion" ) # GIVEN case-id @@ -134,7 +134,7 @@ def test_valid_case( # Make sure nothing is currently stored in Housekeeper - # Make sure analysis not already stored in StatusDB + # Make sure analysis not already stored in StatusDB assert not rnafusion_context.status_db.get_case_by_internal_id(internal_id=case_id).analyses # GIVEN that HermesAPI returns a deliverables output @@ -151,7 +151,7 @@ def test_valid_case( assert rnafusion_context.status_db.get_case_by_internal_id(internal_id=case_id).analyses assert rnafusion_context.meta_apis["analysis_api"].housekeeper_api.bundle(case_id) - # THEN pipeline version should be correctly stored + # THEN workflow version should be correctly stored assert ( rnafusion_context.status_db.get_case_by_internal_id(internal_id=case_id) .analyses[0] diff --git a/tests/conftest.py b/tests/conftest.py index 56c7f0b692..5416f95f61 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -2198,7 +2198,7 @@ def rnafusion_sample_sheet_content( @pytest.fixture(scope="function") def hermes_deliverables(deliverable_data: dict, rnafusion_case_id: str) -> dict: - hermes_output: dict = {"pipeline": "rnafusion", "bundle_id": rnafusion_case_id, "files": []} + hermes_output: dict = {"workflow": "rnafusion", "bundle_id": rnafusion_case_id, "files": []} for file_info in deliverable_data["files"]: tags: list[str] = [] if "html" in file_info["format"]: @@ -2210,7 +2210,7 @@ def hermes_deliverables(deliverable_data: dict, rnafusion_case_id: str) -> dict: @pytest.fixture(scope="function") def malformed_hermes_deliverables(hermes_deliverables: dict) -> dict: malformed_deliverable: dict = hermes_deliverables.copy() - malformed_deliverable.pop("pipeline") + malformed_deliverable.pop("workflow") return malformed_deliverable diff --git a/tests/meta/report/conftest.py b/tests/meta/report/conftest.py index d1f179ed53..7a44757a07 100644 --- a/tests/meta/report/conftest.py +++ b/tests/meta/report/conftest.py @@ -25,7 +25,7 @@ def report_api_mip_dna( ) -> MipDNAReportAPI: """MIP DNA ReportAPI fixture.""" cg_context.meta_apis["analysis_api"] = MockMipAnalysis( - config=cg_context, pipeline=Workflow.MIP_DNA + config=cg_context, workflow=Workflow.MIP_DNA ) cg_context.status_db_ = report_store cg_context.lims_api_ = MockLimsAPI(cg_context, lims_samples) @@ -77,7 +77,7 @@ def case_samples_data(case_id: str, report_api_mip_dna: MipDNAReportAPI): @pytest.fixture(scope="function") def mip_analysis_api(cg_context: CGConfig) -> MockMipAnalysis: """MIP analysis mock data.""" - return MockMipAnalysis(config=cg_context, pipeline=Workflow.MIP_DNA) + return MockMipAnalysis(config=cg_context, workflow=Workflow.MIP_DNA) @pytest.fixture(scope="session") @@ -99,9 +99,9 @@ def report_store(analysis_store, helpers, timestamp_yesterday): """A mock store instance for report testing.""" case = analysis_store.get_cases()[0] helpers.add_analysis( - analysis_store, case, pipeline=Workflow.MIP_DNA, started_at=timestamp_yesterday + analysis_store, case, started_at=timestamp_yesterday, workflow=Workflow.MIP_DNA ) - helpers.add_analysis(analysis_store, case, pipeline=Workflow.MIP_DNA, started_at=datetime.now()) + helpers.add_analysis(analysis_store, case, started_at=datetime.now(), workflow=Workflow.MIP_DNA) # Mock sample dates to calculate processing times for family_sample in analysis_store.get_case_samples_by_case_id( case_internal_id=case.internal_id diff --git a/tests/meta/report/test_report_api.py b/tests/meta/report/test_report_api.py index deaf7dc343..86d1521fc3 100644 --- a/tests/meta/report/test_report_api.py +++ b/tests/meta/report/test_report_api.py @@ -378,7 +378,7 @@ def test_get_case_analysis_data( ) # THEN check if the retrieved analysis data is correct - assert case_analysis_data.pipeline == "mip-dna" + assert case_analysis_data.workflow == "mip-dna" assert case_analysis_data.panels == "IEM, EP" assert case_analysis_data.scout_files @@ -417,7 +417,7 @@ def test_get_case_analysis_data_pipeline_not_supported( case_mip_dna: Case, caplog: LogCaptureFixture, ): - """Test validation error if the analysis pipeline is not supported by the delivery report workflow.""" + """Test validation error if the analysis workflow is not supported by the delivery report workflow.""" # GIVEN a pre-built case with Fluffy as data analysis case_mip_dna.data_analysis = Workflow.FLUFFY @@ -435,7 +435,7 @@ def test_get_case_analysis_data_pipeline_not_supported( case=case_mip_dna, analysis=mip_analysis, analysis_metadata=mip_metadata ) assert ( - f"The pipeline {case_mip_dna.data_analysis} does not support delivery report generation" + f"The workflow {case_mip_dna.data_analysis} does not support delivery report generation" in caplog.text ) diff --git a/tests/meta/upload/conftest.py b/tests/meta/upload/conftest.py index cef428bef7..ef8f35069f 100644 --- a/tests/meta/upload/conftest.py +++ b/tests/meta/upload/conftest.py @@ -105,11 +105,7 @@ def mip_dna_case(mip_dna_context: CGConfig, helpers: StoreHelpers) -> Case: ) helpers.add_relationship(store=store, case=mip_dna_case, sample=dna_mip_sample) - helpers.add_analysis( - store=store, - case=mip_dna_case, - pipeline=Workflow.MIP_DNA, - ) + helpers.add_analysis(store=store, case=mip_dna_case, workflow=Workflow.MIP_DNA) return mip_dna_case @@ -124,7 +120,5 @@ def mip_rna_case(mip_rna_context: CGConfig, case_id: str): def mip_rna_analysis(mip_rna_context: CGConfig, helpers: StoreHelpers, mip_rna_case: Case) -> Case: """Return a MIP RNA analysis.""" return helpers.add_analysis( - store=mip_rna_context.status_db, - case=mip_rna_case, - pipeline=Workflow.MIP_RNA, + store=mip_rna_context.status_db, case=mip_rna_case, workflow=Workflow.MIP_RNA ) diff --git a/tests/meta/upload/scout/conftest.py b/tests/meta/upload/scout/conftest.py index f7c841701a..041345b5d5 100644 --- a/tests/meta/upload/scout/conftest.py +++ b/tests/meta/upload/scout/conftest.py @@ -508,8 +508,8 @@ def mip_dna_analysis( store=analysis_store_trio, case=case, started_at=timestamp, - pipeline=Workflow.MIP_DNA, completed_at=timestamp, + workflow=Workflow.MIP_DNA, ) for link in case.links: helpers.add_phenotype_groups_to_sample( @@ -621,7 +621,7 @@ def lims_api(lims_samples: list[dict]) -> MockLimsAPI: @pytest.fixture(name="mip_analysis_api") def mip_analysis_api(cg_context: CGConfig) -> MockMipAnalysis: """Return a MIP analysis API.""" - return MockMipAnalysis(config=cg_context, pipeline=Workflow.MIP_DNA) + return MockMipAnalysis(config=cg_context, workflow=Workflow.MIP_DNA) @pytest.fixture(name="upload_scout_api") @@ -634,7 +634,7 @@ def upload_scout_api( store: Store, ) -> UploadScoutAPI: """Return upload Scout API.""" - analysis_mock = MockMipAnalysis(config=cg_context, pipeline=Workflow.MIP_DNA) + analysis_mock = MockMipAnalysis(config=cg_context, workflow=Workflow.MIP_DNA) lims_api = MockLimsAPI(samples=lims_samples) return UploadScoutAPI( @@ -657,7 +657,7 @@ def upload_mip_analysis_scout_api( store: Store, ) -> Generator[UploadScoutAPI, None, None]: """Return MIP upload Scout API.""" - analysis_mock = MockMipAnalysis(config=cg_context, pipeline=Workflow.MIP_DNA) + analysis_mock = MockMipAnalysis(config=cg_context, workflow=Workflow.MIP_DNA) lims_api = MockLimsAPI(samples=lims_samples) yield UploadScoutAPI( @@ -680,7 +680,7 @@ def upload_balsamic_analysis_scout_api( store: Store, ) -> Generator[UploadScoutAPI, None, None]: """Return Balsamic upload Scout API.""" - analysis_mock = MockMipAnalysis(config=cg_context, pipeline=Workflow.MIP_DNA) + analysis_mock = MockMipAnalysis(config=cg_context, workflow=Workflow.MIP_DNA) lims_api = MockLimsAPI(samples=lims_samples) yield UploadScoutAPI( @@ -721,7 +721,7 @@ def upload_rnafusion_analysis_scout_api( store: Store, ) -> UploadScoutAPI: """Fixture for upload_scout_api.""" - analysis_mock = MockMipAnalysis(config=cg_context, pipeline=Workflow.MIP_DNA) + analysis_mock = MockMipAnalysis(config=cg_context, workflow=Workflow.MIP_DNA) lims_api = MockLimsAPI(samples=lims_samples) _api = UploadScoutAPI( diff --git a/tests/meta/upload/scout/test_generate_load_config.py b/tests/meta/upload/scout/test_generate_load_config.py index 557ee00c3f..16f64c7fc3 100644 --- a/tests/meta/upload/scout/test_generate_load_config.py +++ b/tests/meta/upload/scout/test_generate_load_config.py @@ -49,7 +49,7 @@ def test_generate_balsamic_load_config( # GIVEN an upload scout api with some balsamic information # WHEN generating a load config - config = upload_balsamic_analysis_scout_api.generate_config(analysis_obj=balsamic_analysis_obj) + config = upload_balsamic_analysis_scout_api.generate_config(analysis=balsamic_analysis_obj) # THEN assert that the config is a balsamic config assert isinstance(config, BalsamicLoadConfig) @@ -64,9 +64,7 @@ def test_generate_balsamic_umi_load_config( # GIVEN an upload scout api with some balsamic information # WHEN generating a load config - config = upload_balsamic_analysis_scout_api.generate_config( - analysis_obj=balsamic_umi_analysis_obj - ) + config = upload_balsamic_analysis_scout_api.generate_config(analysis=balsamic_umi_analysis_obj) # THEN assert that the config is a balsamic-umi config assert isinstance(config, BalsamicUmiLoadConfig) @@ -83,7 +81,7 @@ def test_generate_rnafusion_load_config( # WHEN generating a load config config: ScoutLoadConfig = upload_rnafusion_analysis_scout_api.generate_config( - analysis_obj=rnafusion_analysis_obj + analysis=rnafusion_analysis_obj ) # THEN assert that the config is a rnafusion config @@ -102,7 +100,7 @@ def test_generate_config_adds_meta_result_key( # WHEN generating the scout config for the analysis result_data: ScoutLoadConfig = upload_mip_analysis_scout_api.generate_config( - analysis_obj=mip_dna_analysis + analysis=mip_dna_analysis ) # THEN the config should contain the rank model version used diff --git a/tests/meta/upload/scout/test_meta_upload_scoutapi_rna.py b/tests/meta/upload/scout/test_meta_upload_scoutapi_rna.py index 47f36fa311..80a30ef296 100644 --- a/tests/meta/upload/scout/test_meta_upload_scoutapi_rna.py +++ b/tests/meta/upload/scout/test_meta_upload_scoutapi_rna.py @@ -619,7 +619,7 @@ def test_map_dna_cases_to_dna_sample_incorrect_pipeline( dna_case: Case = rna_store.get_case_by_internal_id(dna_case_id) rna_sample: Sample = rna_store.get_sample_by_internal_id(rna_sample_son_id) - # GIVEN that the DNA case has a different pipeline than the expected pipeline + # GIVEN that the DNA case has a different workflow than the expected workflow dna_case.data_analysis = Workflow.FASTQ # WHEN mapping the DNA case name to the DNA sample name in the related DNA cases @@ -676,7 +676,7 @@ def test_get_multiqc_html_report( # WHEN getting the multiqc html report report_type, multiqc_report = upload_mip_analysis_scout_api.get_multiqc_html_report( - case_id=dna_case_id, pipeline=case.data_analysis + case_id=dna_case_id, workflow=case.data_analysis ) # THEN the multiqc html report should be returned and the correct report type diff --git a/tests/meta/upload/test_upload_genotypes_api.py b/tests/meta/upload/test_upload_genotypes_api.py index e136ae7bb6..4c0c988eea 100644 --- a/tests/meta/upload/test_upload_genotypes_api.py +++ b/tests/meta/upload/test_upload_genotypes_api.py @@ -61,7 +61,7 @@ def test_get_data( UploadGenotypesAPI.analysis_sex.return_value = genotype_analysis_sex # WHEN parsing the data - result = upload_genotypes_api.data(analysis_obj=analysis_obj) + result = upload_genotypes_api.data(analysis=analysis_obj) # THEN assert that the result looks like expected assert len(result["samples_sex"]) == 3 diff --git a/tests/meta/workflow/test_nf_analysis.py b/tests/meta/workflow/test_nf_analysis.py index 196e42984a..d122cbecef 100644 --- a/tests/meta/workflow/test_nf_analysis.py +++ b/tests/meta/workflow/test_nf_analysis.py @@ -45,7 +45,7 @@ def test_create_metrics_deliverables_content( case_id: str = request.getfixturevalue(case_id) request.getfixturevalue(analysis_finish) - # GIVEN a Nextflow pipeline analysis API and a list of QC metrics + # GIVEN a Nextflow workflow analysis API and a list of QC metrics analysis_api: NfAnalysisAPI = context.meta_apis["analysis_api"] # WHEN writing the metrics deliverables file diff --git a/tests/models/report/test_validators.py b/tests/models/report/test_validators.py index 51b7e01cf1..78a0486177 100644 --- a/tests/models/report/test_validators.py +++ b/tests/models/report/test_validators.py @@ -186,7 +186,7 @@ def test_get_analysis_type_as_string(): # GIVEN a WGS analysis type and a model info dictionary analysis_type: AnalysisType = AnalysisType.WHOLE_GENOME_SEQUENCING model_info: ValidationInfo = ValidationInfo - model_info.data: dict[str, Any] = {"pipeline": Workflow.MIP_DNA.value} + model_info.data: dict[str, Any] = {"workflow": Workflow.MIP_DNA.value} # WHEN performing the validation validated_analysis_type: str = get_analysis_type_as_string( @@ -203,7 +203,7 @@ def test_get_analysis_type_as_string_balsamic(): # GIVEN a WGS analysis type and a model info dictionary analysis_type: str = "tumor_normal_wgs" model_info: ValidationInfo = ValidationInfo - model_info.data: dict[str, Any] = {"pipeline": Workflow.BALSAMIC.value} + model_info.data: dict[str, Any] = {"workflow": Workflow.BALSAMIC.value} # WHEN performing the validation validated_analysis_type: str = get_analysis_type_as_string( diff --git a/tests/store/api/conftest.py b/tests/store/api/conftest.py index 399be74b55..e1d02a2e99 100644 --- a/tests/store/api/conftest.py +++ b/tests/store/api/conftest.py @@ -74,17 +74,17 @@ def store_with_analyses_for_cases( analysis_store, case=case, started_at=timestamp_yesterday, + completed_at=timestamp_yesterday, uploaded_at=timestamp_yesterday, delivery_reported_at=None, - completed_at=timestamp_yesterday, ) helpers.add_analysis( analysis_store, case=case, started_at=timestamp_now, + completed_at=timestamp_now, uploaded_at=timestamp_now, delivery_reported_at=None, - completed_at=timestamp_now, ) sample = helpers.add_sample(analysis_store, delivered_at=timestamp_now) link: CaseSample = analysis_store.relate_sample( diff --git a/tests/store/conftest.py b/tests/store/conftest.py index f1ef329851..63669253eb 100644 --- a/tests/store/conftest.py +++ b/tests/store/conftest.py @@ -326,15 +326,15 @@ def store_with_application_limitations( application=store_with_an_application_with_and_without_attributes.get_application_by_tag( StoreConstants.TAG_APPLICATION_WITH_ATTRIBUTES.value ), - pipeline=Workflow.MIP_DNA, + workflow=Workflow.MIP_DNA, ) - for pipeline in [Workflow.MIP_DNA, Workflow.BALSAMIC]: + for workflow in [Workflow.MIP_DNA, Workflow.BALSAMIC]: helpers.ensure_application_limitation( store=store_with_an_application_with_and_without_attributes, application=store_with_an_application_with_and_without_attributes.get_application_by_tag( StoreConstants.TAG_APPLICATION_WITHOUT_ATTRIBUTES.value ), - pipeline=pipeline, + workflow=workflow, ) return store_with_an_application_with_and_without_attributes @@ -415,11 +415,11 @@ def store_with_older_and_newer_analyses( helpers.add_analysis( store=base_store, case=case, - pipeline=Workflow.BALSAMIC, started_at=time, completed_at=time, uploaded_at=time, cleaned_at=time, + workflow=Workflow.BALSAMIC, ) yield base_store @@ -557,7 +557,7 @@ def store_with_analyses_for_cases_not_uploaded_fluffy( started_at=timestamp_yesterday, uploaded_at=timestamp_yesterday, delivery_reported_at=None, - pipeline=Workflow.FLUFFY, + workflow=Workflow.FLUFFY, ) helpers.add_analysis( analysis_store, @@ -565,7 +565,7 @@ def store_with_analyses_for_cases_not_uploaded_fluffy( started_at=timestamp_now, uploaded_at=None, delivery_reported_at=None, - pipeline=Workflow.FLUFFY, + workflow=Workflow.FLUFFY, ) sample = helpers.add_sample(analysis_store, delivered_at=timestamp_now) link: CaseSample = analysis_store.relate_sample( diff --git a/tests/store/crud/conftest.py b/tests/store/crud/conftest.py index 99a23504a5..6398d6dc4b 100644 --- a/tests/store/crud/conftest.py +++ b/tests/store/crud/conftest.py @@ -172,7 +172,7 @@ def store_with_analyses_for_cases_not_uploaded_microsalt( started_at=timestamp_yesterday, uploaded_at=timestamp_yesterday, delivery_reported_at=None, - pipeline=Workflow.MICROSALT, + workflow=Workflow.MICROSALT, ) helpers.add_analysis( analysis_store, @@ -180,7 +180,7 @@ def store_with_analyses_for_cases_not_uploaded_microsalt( started_at=timestamp_now, uploaded_at=None, delivery_reported_at=None, - pipeline=Workflow.MICROSALT, + workflow=Workflow.MICROSALT, ) sample = helpers.add_sample(analysis_store, delivered_at=timestamp_now) link: CaseSample = analysis_store.relate_sample( @@ -207,19 +207,19 @@ def store_with_analyses_for_cases_to_deliver( analysis_store, case=case, started_at=timestamp_yesterday, + completed_at=timestamp_yesterday, uploaded_at=None, delivery_reported_at=None, - completed_at=timestamp_yesterday, - pipeline=Workflow.FLUFFY, + workflow=Workflow.FLUFFY, ) helpers.add_analysis( analysis_store, case=case, started_at=timestamp_now, + completed_at=timestamp_now, uploaded_at=None, delivery_reported_at=None, - completed_at=timestamp_now, - pipeline=Workflow.MIP_DNA, + workflow=Workflow.MIP_DNA, ) sample = helpers.add_sample(analysis_store, delivered_at=None) link: CaseSample = analysis_store.relate_sample( diff --git a/tests/store/crud/read/test_read.py b/tests/store/crud/read/test_read.py index 85d9727ad1..49dca0babd 100644 --- a/tests/store/crud/read/test_read.py +++ b/tests/store/crud/read/test_read.py @@ -122,7 +122,7 @@ def test_case_in_uploaded_observations(helpers: StoreHelpers, sample_store: Stor """Test retrieval of uploaded observations.""" # GIVEN a case with observations that has been uploaded to Loqusdb - analysis: Analysis = helpers.add_analysis(store=sample_store, pipeline=Workflow.MIP_DNA) + analysis: Analysis = helpers.add_analysis(store=sample_store, workflow=Workflow.MIP_DNA) analysis.case.customer.loqus_upload = True sample: Sample = helpers.add_sample(sample_store, loqusdb_id=loqusdb_id) link = sample_store.relate_sample(analysis.case, sample, PhenotypeStatus.UNKNOWN) @@ -142,7 +142,7 @@ def test_case_not_in_uploaded_observations(helpers: StoreHelpers, sample_store: """Test retrieval of uploaded observations that have not been uploaded to Loqusdb.""" # GIVEN a case with observations that has not been uploaded to loqusdb - analysis: Analysis = helpers.add_analysis(store=sample_store, pipeline=Workflow.MIP_DNA) + analysis: Analysis = helpers.add_analysis(store=sample_store, workflow=Workflow.MIP_DNA) analysis.case.customer.loqus_upload = True sample: Sample = helpers.add_sample(sample_store) link = sample_store.relate_sample(analysis.case, sample, PhenotypeStatus.UNKNOWN) @@ -162,7 +162,7 @@ def test_case_in_observations_to_upload(helpers: StoreHelpers, sample_store: Sto """Test extraction of ready to be uploaded to Loqusdb cases.""" # GIVEN a case with completed analysis and samples w/o loqusdb_id - analysis: Analysis = helpers.add_analysis(store=sample_store, pipeline=Workflow.MIP_DNA) + analysis: Analysis = helpers.add_analysis(store=sample_store, workflow=Workflow.MIP_DNA) analysis.case.customer.loqus_upload = True sample: Sample = helpers.add_sample(sample_store) link = sample_store.relate_sample(analysis.case, sample, PhenotypeStatus.UNKNOWN) @@ -184,7 +184,7 @@ def test_case_not_in_observations_to_upload( """Test case extraction that should not be uploaded to Loqusdb.""" # GIVEN a case with completed analysis and samples with a Loqusdb ID - analysis: Analysis = helpers.add_analysis(store=sample_store, pipeline=Workflow.MIP_DNA) + analysis: Analysis = helpers.add_analysis(store=sample_store, workflow=Workflow.MIP_DNA) analysis.case.customer.loqus_upload = True sample: Sample = helpers.add_sample(sample_store, loqusdb_id=loqusdb_id) link = sample_store.relate_sample(analysis.case, sample, PhenotypeStatus.UNKNOWN) @@ -219,9 +219,9 @@ def test_analyses_to_upload_when_no_pipeline(helpers, sample_store, timestamp): # GIVEN a store with one analysis helpers.add_analysis(store=sample_store, completed_at=timestamp) - # WHEN fetching all analysis that are ready for upload without specifying pipeline + # WHEN fetching all analysis that are ready for upload without specifying workflow records: list[Analysis] = [ - analysis_obj for analysis_obj in sample_store.get_analyses_to_upload(pipeline=None) + analysis_obj for analysis_obj in sample_store.get_analyses_to_upload(workflow=None) ] # THEN one analysis object should be returned @@ -231,11 +231,11 @@ def test_analyses_to_upload_when_no_pipeline(helpers, sample_store, timestamp): def test_analyses_to_upload_when_analysis_has_pipeline(helpers, sample_store, timestamp): """Test analyses to upload to when existing pipeline.""" # GIVEN a store with an analysis that has been run with MIP - helpers.add_analysis(store=sample_store, completed_at=timestamp, pipeline=Workflow.MIP_DNA) + helpers.add_analysis(store=sample_store, completed_at=timestamp, workflow=Workflow.MIP_DNA) # WHEN fetching all analyses that are ready for upload and analysed with MIP records: list[Analysis] = [ - analysis_obj for analysis_obj in sample_store.get_analyses_to_upload(pipeline=None) + analysis_obj for analysis_obj in sample_store.get_analyses_to_upload(workflow=None) ] # THEN one analysis object should be returned @@ -246,15 +246,15 @@ def test_analyses_to_upload_when_filtering_with_pipeline(helpers, sample_store, """Test analyses to upload to when existing pipeline and using it in filtering.""" # GIVEN a store with an analysis that is analysed with MIP pipeline = Workflow.MIP_DNA - helpers.add_analysis(store=sample_store, completed_at=timestamp, pipeline=pipeline) + helpers.add_analysis(store=sample_store, completed_at=timestamp, workflow=pipeline) # WHEN fetching all pipelines that are analysed with MIP records: list[Analysis] = [ - analysis_obj for analysis_obj in sample_store.get_analyses_to_upload(pipeline=pipeline) + analysis_obj for analysis_obj in sample_store.get_analyses_to_upload(workflow=pipeline) ] for analysis_obj in records: - # THEN the pipeline should be MIP in the analysis object + # THEN the workflow should be MIP in the analysis object assert analysis_obj.pipeline == str(pipeline) @@ -262,11 +262,11 @@ def test_analyses_to_upload_with_pipeline_and_no_complete_at(helpers, sample_sto """Test analyses to upload to when existing pipeline and using it in filtering.""" # GIVEN a store with an analysis that is analysed with MIP but does not have a completed_at pipeline = Workflow.MIP_DNA - helpers.add_analysis(store=sample_store, completed_at=None, pipeline=pipeline) + helpers.add_analysis(store=sample_store, completed_at=None, workflow=pipeline) # WHEN fetching all analyses that are ready for upload and analysed by MIP records: list[Analysis] = [ - analysis_obj for analysis_obj in sample_store.get_analyses_to_upload(pipeline=pipeline) + analysis_obj for analysis_obj in sample_store.get_analyses_to_upload(workflow=pipeline) ] # THEN no analysis object should be returned since they where not completed @@ -276,12 +276,12 @@ def test_analyses_to_upload_with_pipeline_and_no_complete_at(helpers, sample_sto def test_analyses_to_upload_when_filtering_with_missing_pipeline(helpers, sample_store, timestamp): """Test analyses to upload to when missing pipeline and using it in filtering.""" # GIVEN a store with an analysis that has been analysed with "missing_pipeline" - helpers.add_analysis(store=sample_store, completed_at=timestamp, pipeline=Workflow.MIP_DNA) + helpers.add_analysis(store=sample_store, completed_at=timestamp, workflow=Workflow.MIP_DNA) # WHEN fetching all analyses that was analysed with MIP records: list[Analysis] = [ analysis_obj - for analysis_obj in sample_store.get_analyses_to_upload(pipeline=Workflow.FASTQ) + for analysis_obj in sample_store.get_analyses_to_upload(workflow=Workflow.FASTQ) ] # THEN no analysis object should be returned, since there were no MIP analyses @@ -917,19 +917,19 @@ def test_get_application_limitations_by_tag( ) -def test_get_application_limitation_by_tag_and_pipeline( +def test_get_application_limitation_by_tag_and_workflow( store_with_application_limitations: Store, tag: str = StoreConstants.TAG_APPLICATION_WITH_ATTRIBUTES.value, - pipeline: Workflow = Workflow.MIP_DNA, + workflow: Workflow = Workflow.MIP_DNA, ) -> ApplicationLimitations: - """Test get application limitations by application tag and pipeline.""" + """Test get application limitations by application tag and workflow.""" # GIVEN a store with some application limitations - # WHEN filtering by a given application tag and pipeline + # WHEN filtering by a given application tag and workflow application_limitation: ApplicationLimitations = ( - store_with_application_limitations.get_application_limitation_by_tag_and_pipeline( - tag=tag, pipeline=pipeline + store_with_application_limitations.get_application_limitation_by_tag_and_workflow( + tag=tag, workflow=workflow ) ) @@ -937,7 +937,7 @@ def test_get_application_limitation_by_tag_and_pipeline( assert ( application_limitation and application_limitation.application.tag == tag - and application_limitation.pipeline == pipeline + and application_limitation.pipeline == workflow ) diff --git a/tests/store/crud/read/test_read_analyses_to_clean.py b/tests/store/crud/read/test_read_analyses_to_clean.py index 3a160b0442..527d13db92 100644 --- a/tests/store/crud/read/test_read_analyses_to_clean.py +++ b/tests/store/crud/read/test_read_analyses_to_clean.py @@ -52,19 +52,19 @@ def test_analysis_excluded(analysis_store: Store, helpers, timestamp_now: dateti assert analysis not in analyses_to_clean -def test_pipeline_included( +def test_workflow_included( analysis_store: Store, helpers, timestamp_now: datetime, timestamp_yesterday: datetime ): - """Tests that analyses that are included depending on pipeline.""" + """Tests that analyses that are included depending on workflow.""" - # GIVEN an analysis that is uploaded and pipeline is specified - pipeline = Workflow.BALSAMIC + # GIVEN an analysis that is uploaded and workflow is specified + workflow = Workflow.BALSAMIC analysis = helpers.add_analysis( analysis_store, - pipeline=pipeline, started_at=timestamp_yesterday, uploaded_at=timestamp_yesterday, cleaned_at=None, + workflow=workflow, ) sample = helpers.add_sample(analysis_store, delivered_at=timestamp_yesterday) link: CaseSample = analysis_store.relate_sample( @@ -72,28 +72,28 @@ def test_pipeline_included( ) analysis_store.session.add(link) - # WHEN calling the analyses_to_clean specifying the used pipeline + # WHEN calling the analyses_to_clean specifying the used workflow analyses_to_clean = analysis_store.get_analyses_to_clean( - pipeline=pipeline, before=timestamp_now + before=timestamp_now, workflow=workflow ) # THEN this analysis should be returned assert analysis in analyses_to_clean -def test_pipeline_excluded(analysis_store: Store, helpers, timestamp_now: datetime): +def test_workflow_excluded(analysis_store: Store, helpers, timestamp_now: datetime): """Tests that analyses are excluded depending on pipeline.""" # GIVEN an analysis that is uploaded - used_pipeline = Workflow.BALSAMIC - wrong_pipeline = Workflow.MIP_DNA + used_workflow = Workflow.BALSAMIC + wrong_workflow = Workflow.MIP_DNA analysis = helpers.add_analysis( analysis_store, - pipeline=used_pipeline, started_at=timestamp_now, uploaded_at=timestamp_now, cleaned_at=None, + workflow=used_workflow, ) sample = helpers.add_sample(analysis_store, delivered_at=timestamp_now) link: CaseSample = analysis_store.relate_sample( @@ -101,8 +101,8 @@ def test_pipeline_excluded(analysis_store: Store, helpers, timestamp_now: dateti ) analysis_store.session.add(link) - # WHEN calling the analyses_to_clean specifying another pipeline - analyses_to_clean = analysis_store.get_analyses_to_clean(pipeline=wrong_pipeline) + # WHEN calling the analyses_to_clean specifying another workflow + analyses_to_clean = analysis_store.get_analyses_to_clean(workflow=wrong_workflow) # THEN this analysis should not be returned assert analysis not in analyses_to_clean diff --git a/tests/store/crud/read/test_read_analyses_to_delivery_report.py b/tests/store/crud/read/test_read_analyses_to_delivery_report.py index 5fbe4508b9..2772c56081 100644 --- a/tests/store/crud/read/test_read_analyses_to_delivery_report.py +++ b/tests/store/crud/read/test_read_analyses_to_delivery_report.py @@ -9,16 +9,16 @@ def test_missing(analysis_store: Store, helpers: StoreHelpers, timestamp_now): - """Tests that analyses that are completed, but lacks delivery report are returned.""" + """Test that analyses that are completed, but lacks a delivery report returned.""" # GIVEN an analysis that is delivered but has no delivery report - pipeline = Workflow.BALSAMIC + workflow = Workflow.BALSAMIC analysis = helpers.add_analysis( analysis_store, started_at=timestamp_now, completed_at=timestamp_now, uploaded_at=timestamp_now, - pipeline=pipeline, + workflow=workflow, data_delivery=DataDelivery.SCOUT, ) sample = helpers.add_sample(analysis_store, delivered_at=timestamp_now) @@ -30,7 +30,7 @@ def test_missing(analysis_store: Store, helpers: StoreHelpers, timestamp_now): assert analysis.delivery_report_created_at is None # WHEN calling the analyses_to_delivery_report - analyses = analysis_store.analyses_to_delivery_report(pipeline=pipeline).all() + analyses = analysis_store.analyses_to_delivery_report(workflow=workflow).all() # THEN this analyse should be returned assert analysis in analyses @@ -43,7 +43,7 @@ def test_outdated_analysis( # GIVEN an analysis that is older than Hasta timestamp_old_analysis = get_date("2017-09-26") - pipeline = Workflow.BALSAMIC + workflow = Workflow.BALSAMIC # GIVEN a delivery report created at date which is older than the upload date to trigger delivery report generation @@ -53,7 +53,7 @@ def test_outdated_analysis( started_at=timestamp_old_analysis, uploaded_at=timestamp_now, delivery_reported_at=timestamp_yesterday, - pipeline=pipeline, + workflow=workflow, ) # GIVEN samples which has been delivered @@ -66,7 +66,7 @@ def test_outdated_analysis( analysis_store.session.add(link) # WHEN calling the analyses_to_delivery_report - analyses = analysis_store.analyses_to_delivery_report(pipeline=pipeline).all() + analyses = analysis_store.analyses_to_delivery_report(workflow=workflow).all() # THEN this analyses should not be returned assert len(analyses) == 0 @@ -78,19 +78,19 @@ def test_analyses_to_upload_delivery_reports( """Tests extraction of analyses ready for delivery report upload""" # GIVEN an analysis that has a delivery report generated - pipeline = Workflow.BALSAMIC + workflow = Workflow.BALSAMIC analysis = helpers.add_analysis( analysis_store, started_at=timestamp_now, completed_at=timestamp_now, uploaded_at=None, delivery_reported_at=timestamp_now, - pipeline=pipeline, + workflow=workflow, data_delivery=DataDelivery.FASTQ_ANALYSIS_SCOUT, ) # WHEN calling the analyses_to_upload_delivery_reports - analyses = analysis_store.analyses_to_upload_delivery_reports(pipeline=pipeline).all() + analyses = analysis_store.analyses_to_upload_delivery_reports(workflow=workflow).all() # THEN the previously defined analysis should be returned assert analysis in analyses diff --git a/tests/store/crud/read/test_read_analysis.py b/tests/store/crud/read/test_read_analysis.py index e4bd6f0aa7..8b46d981b7 100644 --- a/tests/store/crud/read/test_read_analysis.py +++ b/tests/store/crud/read/test_read_analysis.py @@ -15,15 +15,15 @@ def test_get_latest_nipt_analysis_to_upload( store_with_analyses_for_cases_not_uploaded_fluffy: Store, timestamp_now: datetime, - pipeline: str = Workflow.FLUFFY, + workflow: str = Workflow.FLUFFY, ): """Test get the latest NIPT analysis to upload.""" # GIVEN an analysis that is not delivery reported but there exists a newer analysis # WHEN fetching the latest analysis to upload to nipt analyses: list[Analysis] = ( - store_with_analyses_for_cases_not_uploaded_fluffy.get_latest_analysis_to_upload_for_pipeline( - pipeline=pipeline + store_with_analyses_for_cases_not_uploaded_fluffy.get_latest_analysis_to_upload_for_workflow( + workflow=workflow ) ) @@ -31,21 +31,21 @@ def test_get_latest_nipt_analysis_to_upload( for analysis in analyses: assert analysis.started_at == timestamp_now assert analysis.uploaded_at is None - assert analysis.pipeline == pipeline + assert analysis.pipeline == workflow def test_get_latest_microsalt_analysis_to_upload( store_with_analyses_for_cases_not_uploaded_microsalt: Store, timestamp_now: datetime, - pipeline: str = Workflow.MICROSALT, + workflow: str = Workflow.MICROSALT, ): """Test get the latest microsalt analysis to upload.""" # GIVEN an analysis that is not delivery reported but there exists a newer analysis # WHEN fetching the latest analysis to upload to microsalt analyses: list[Analysis] = ( - store_with_analyses_for_cases_not_uploaded_microsalt.get_latest_analysis_to_upload_for_pipeline( - pipeline=pipeline + store_with_analyses_for_cases_not_uploaded_microsalt.get_latest_analysis_to_upload_for_workflow( + workflow=workflow ) ) @@ -53,25 +53,25 @@ def test_get_latest_microsalt_analysis_to_upload( for analysis in analyses: assert analysis.started_at == timestamp_now assert analysis.uploaded_at is None - assert analysis.pipeline == pipeline + assert analysis.pipeline == workflow def test_get_analyses_to_deliver_for_pipeline( store_with_analyses_for_cases_to_deliver: Store, - pipeline: Workflow = Workflow.FLUFFY, + workflow: Workflow = Workflow.FLUFFY, ): # GIVEN a store with multiple analyses to deliver # WHEN fetching the latest analysis to upload to nipt analyses = store_with_analyses_for_cases_to_deliver.get_analyses_to_deliver_for_pipeline( - pipeline=pipeline + workflow=workflow ) # THEN only the newest analysis should be returned for analysis in analyses: assert analysis.case.internal_id in ["test_case_1", "yellowhog"] assert analysis.uploaded_at is None - assert analysis.pipeline == pipeline + assert analysis.pipeline == workflow def test_get_analyses(store_with_analyses_for_cases: Store): @@ -95,7 +95,7 @@ def test_get_families_with_extended_models( # GIVEN a completed analysis test_analysis: Analysis = helpers.add_analysis( - base_store, completed_at=timestamp_now, pipeline=Workflow.MIP_DNA + base_store, completed_at=timestamp_now, workflow=Workflow.MIP_DNA ) # Given an action set to analyze @@ -139,7 +139,7 @@ def test_get_cases_with_samples_query( # GIVEN a completed analysis test_analysis: Analysis = helpers.add_analysis( - base_store, completed_at=timestamp_now, pipeline=Workflow.MIP_DNA + base_store, completed_at=timestamp_now, workflow=Workflow.MIP_DNA ) # GIVEN a database with a case with one of sequenced samples and completed analysis @@ -165,7 +165,7 @@ def test_that_many_cases_can_have_one_sample_each( ) # WHEN getting cases to analyse - cases: list[Case] = base_store.cases_to_analyze(pipeline=Workflow.MIP_DNA) + cases: list[Case] = base_store.cases_to_analyze(workflow=Workflow.MIP_DNA) # THEN cases should contain all cases since they are to be analysed assert len(cases) == len(test_cases) @@ -193,7 +193,7 @@ def test_that_cases_can_have_many_samples( base_store.session.add(link) # WHEN getting cases to analyse - cases: list[Case] = base_store.cases_to_analyze(pipeline=Workflow.MIP_DNA) + cases: list[Case] = base_store.cases_to_analyze(workflow=Workflow.MIP_DNA) # THEN cases should be returned assert cases @@ -214,7 +214,7 @@ def test_external_sample_to_re_analyse( # GIVEN a completed analysis test_analysis: Analysis = helpers.add_analysis( - base_store, completed_at=timestamp_now, pipeline=Workflow.MIP_DNA + base_store, completed_at=timestamp_now, workflow=Workflow.MIP_DNA ) assert test_analysis.completed_at @@ -226,7 +226,7 @@ def test_external_sample_to_re_analyse( base_store.session.add(link) # WHEN getting cases to analyse - cases: list[Case] = base_store.cases_to_analyze(pipeline=Workflow.MIP_DNA) + cases: list[Case] = base_store.cases_to_analyze(workflow=Workflow.MIP_DNA) # THEN cases should be returned assert cases @@ -249,7 +249,7 @@ def test_new_external_case_not_in_result(base_store: Store, helpers: StoreHelper base_store.session.add(link) # WHEN getting cases to analyse - cases: list[Case] = base_store.cases_to_analyze(pipeline=Workflow.BALSAMIC) + cases: list[Case] = base_store.cases_to_analyze(workflow=Workflow.BALSAMIC) # THEN cases should not contain the test case assert test_case not in cases @@ -264,7 +264,7 @@ def test_case_to_re_analyse(base_store: Store, helpers: StoreHelpers, timestamp_ # GIVEN a completed analysis test_analysis: Analysis = helpers.add_analysis( - base_store, completed_at=timestamp_now, pipeline=Workflow.MIP_DNA + base_store, completed_at=timestamp_now, workflow=Workflow.MIP_DNA ) # Given an action set to analyze @@ -275,7 +275,7 @@ def test_case_to_re_analyse(base_store: Store, helpers: StoreHelpers, timestamp_ base_store.session.add(link) # WHEN getting cases to analyse - cases: list[Case] = base_store.cases_to_analyze(pipeline=Workflow.MIP_DNA) + cases: list[Case] = base_store.cases_to_analyze(workflow=Workflow.MIP_DNA) # THEN cases should be returned assert cases @@ -304,7 +304,7 @@ def test_all_samples_and_analysis_completed( base_store.session.add(link) # WHEN getting cases to analyse - cases: list[Case] = base_store.cases_to_analyze(pipeline=Workflow.MIP_DNA) + cases: list[Case] = base_store.cases_to_analyze(workflow=Workflow.MIP_DNA) # THEN cases should not contain the test case assert not cases @@ -326,7 +326,7 @@ def test_specified_analysis_in_result( base_store.session.add(link) # WHEN getting cases to analyse - cases: list[Case] = base_store.cases_to_analyze(pipeline=Workflow.BALSAMIC) + cases: list[Case] = base_store.cases_to_analyze(workflow=Workflow.BALSAMIC) # THEN cases should be returned assert cases @@ -351,8 +351,8 @@ def test_exclude_other_pipeline_analysis_from_result( link = base_store.relate_sample(test_case, test_sample, PhenotypeStatus.UNKNOWN) base_store.session.add(link) - # WHEN getting cases to analyse for another pipeline - cases: list[Case] = base_store.cases_to_analyze(pipeline=Workflow.MIP_DNA) + # WHEN getting cases to analyse for another workflow + cases: list[Case] = base_store.cases_to_analyze(workflow=Workflow.MIP_DNA) # THEN cases should not contain the test case assert test_case not in cases @@ -383,7 +383,7 @@ def test_one_of_two_sequenced_samples( base_store.session.add_all([link_1, link_2]) # WHEN getting cases to analyse - cases: list[Case] = base_store.cases_to_analyze(pipeline=Workflow.MIP_DNA, threshold=True) + cases: list[Case] = base_store.cases_to_analyze(workflow=Workflow.MIP_DNA, threshold=True) # THEN no cases should be returned assert not cases @@ -407,7 +407,7 @@ def test_one_of_one_sequenced_samples( assert test_sample.last_sequenced_at is not None # WHEN getting cases to analyse - cases: list[Case] = base_store.cases_to_analyze(pipeline=Workflow.MIP_DNA) + cases: list[Case] = base_store.cases_to_analyze(workflow=Workflow.MIP_DNA) # THEN cases should be returned assert cases @@ -419,7 +419,7 @@ def test_one_of_one_sequenced_samples( def test_get_analyses_for_case_and_pipeline_before( store_with_analyses_for_cases_not_uploaded_fluffy: Store, timestamp_now: datetime, - pipeline: Workflow = Workflow.FLUFFY, + workflow: Workflow = Workflow.FLUFFY, case_id: str = "yellowhog", ): """Test to get all analyses before a given date.""" @@ -428,8 +428,8 @@ def test_get_analyses_for_case_and_pipeline_before( # WHEN getting all analyses before a given date analyses: list[Analysis] = ( - store_with_analyses_for_cases_not_uploaded_fluffy.get_analyses_for_case_and_pipeline_started_at_before( - case_internal_id=case_id, started_at_before=timestamp_now, pipeline=pipeline + store_with_analyses_for_cases_not_uploaded_fluffy.get_analyses_for_case_and_workflow_started_at_before( + workflow=workflow, started_at_before=timestamp_now, case_internal_id=case_id ) ) @@ -437,7 +437,7 @@ def test_get_analyses_for_case_and_pipeline_before( for analysis in analyses: assert analysis.started_at < timestamp_now assert analysis.case.internal_id == case_id - assert analysis.pipeline == pipeline + assert analysis.pipeline == workflow def test_get_analyses_for_case_before( @@ -466,7 +466,7 @@ def test_get_analyses_for_case_before( def test_get_analyses_for_pipeline_before( store_with_analyses_for_cases_not_uploaded_fluffy: Store, timestamp_now: datetime, - pipeline: Workflow = Workflow.FLUFFY, + workflow: Workflow = Workflow.FLUFFY, ): """Test to get all analyses for a pipeline before a given date.""" @@ -474,15 +474,15 @@ def test_get_analyses_for_pipeline_before( # WHEN getting all analyses before a given date analyses: list[Analysis] = ( - store_with_analyses_for_cases_not_uploaded_fluffy.get_analyses_for_pipeline_started_at_before( - started_at_before=timestamp_now, pipeline=pipeline + store_with_analyses_for_cases_not_uploaded_fluffy.get_analyses_for_workflow_started_at_before( + workflow=workflow, started_at_before=timestamp_now ) ) # THEN assert that the analyses before the given date are returned for analysis in analyses: assert analysis.started_at < timestamp_now - assert analysis.pipeline == pipeline + assert analysis.pipeline == workflow def test_get_analyses_before( diff --git a/tests/store/crud/read/test_read_case.py b/tests/store/crud/read/test_read_case.py index 5af8e24dec..3ada6ea675 100644 --- a/tests/store/crud/read/test_read_case.py +++ b/tests/store/crud/read/test_read_case.py @@ -50,40 +50,40 @@ def test_get_cases_by_customers_action_and_case_search_pattern( assert case_search in case.name -def test_get_cases_by_customer_pipeline_and_case_search_pattern( +def test_get_cases_by_customer_workflow_and_case_search_pattern( store_with_cases_and_customers: Store, ): - """Test that only cases with the specified customer, pipeline, and case search pattern are returned.""" + """Test that only cases with the specified customer, workflow, and case search pattern are returned.""" # GIVEN a store with some cases and customers case = store_with_cases_and_customers._get_query(table=Case).first() - # Set the pipeline and case_search + # Set the workflow and case_search customer = case.customer - pipeline = case.data_analysis + workflow = case.data_analysis case_search = case.name[:3] - # WHEN calling get_cases_by_customer_pipeline_and_case_search_pattern with customer, pipeline, and case_search - cases = store_with_cases_and_customers.get_cases_by_customer_pipeline_and_case_search( - customer=customer, pipeline=pipeline, case_search=case_search + # WHEN calling get_cases_by_customer_workflow_and_case_search_pattern with customer, workflow, and case_search + cases = store_with_cases_and_customers.get_cases_by_customer_workflow_and_case_search( + customer=customer, workflow=workflow, case_search=case_search ) - # THEN cases with the specified customer, pipeline, and case search pattern should be returned + # THEN cases with the specified customer, workflow, and case search pattern should be returned for case in cases: assert case.customer == customer - assert case.data_analysis == pipeline + assert case.data_analysis == workflow assert case_search in case.name -def test_get_running_cases_in_pipeline(store_with_cases_and_customers: Store): +def test_get_running_cases_in_workflow(store_with_cases_and_customers: Store): """Test that only cases with the specified pipeline, and have action "running" are returned.""" # GIVEN a store with some cases - # WHEN getting cases with a pipeline and are running - cases: list[Case] = store_with_cases_and_customers.get_running_cases_in_pipeline( - pipeline=Workflow.MIP_DNA + # WHEN getting cases with a workflow and are running + cases: list[Case] = store_with_cases_and_customers.get_running_cases_in_workflow( + workflow=Workflow.MIP_DNA ) - # THEN cases with the specified pipeline, and case action is returned + # THEN cases with the specified workflow, and case action is returned for case in cases: assert case.action == CaseActions.RUNNING assert case.data_analysis == Workflow.MIP_DNA @@ -1344,21 +1344,21 @@ def test_analysis_uploaded_at(base_store: Store, helpers): assert case.get("analysis_uploaded_at") is not None -def test_analysis_pipeline(base_store: Store, helpers): - """Test to that cases displays pipeline""" +def test_analysis_workflow(base_store: Store, helpers): + """Test to that cases displays workflow.""" - # GIVEN a database with an analysis that has pipeline - pipeline = Workflow.BALSAMIC - analysis = helpers.add_analysis(base_store, pipeline=pipeline) + # GIVEN a database with an analysis that has workflow + workflow = Workflow.BALSAMIC + analysis = helpers.add_analysis(base_store, workflow=workflow) assert analysis.pipeline is not None # WHEN getting active cases cases = base_store.cases() - # THEN cases should contain info on pipeline + # THEN cases should contain info on workflow assert cases for case in cases: - assert case.get("analysis_pipeline") == str(pipeline) + assert case.get("analysis_pipeline") == str(workflow) def test_samples_delivered(base_store: Store, helpers): diff --git a/tests/store/filters/test_status_analyses_filters.py b/tests/store/filters/test_status_analyses_filters.py index 2393b43d15..42c9360d7c 100644 --- a/tests/store/filters/test_status_analyses_filters.py +++ b/tests/store/filters/test_status_analyses_filters.py @@ -9,11 +9,11 @@ filter_analyses_not_cleaned, filter_analyses_started_before, filter_analyses_with_delivery_report, - filter_analyses_with_pipeline, + filter_analyses_with_workflow, filter_analyses_without_delivery_report, filter_completed_analyses, filter_not_uploaded_analyses, - filter_report_analyses_by_pipeline, + filter_report_analyses_by_workflow, filter_uploaded_analyses, filter_valid_analyses_in_production, order_analyses_by_completed_at_asc, @@ -52,18 +52,18 @@ def test_filter_valid_analyses_in_production( assert outdated_analysis not in analyses -def test_filter_analyses_with_pipeline(base_store: Store, helpers: StoreHelpers, case: Case): - """Test analyses filtering by pipeline.""" +def test_filter_analyses_with_workflow(base_store: Store, helpers: StoreHelpers, case: Case): + """Test analyses filtering by workflow.""" # GIVEN a set of mock analyses - balsamic_analysis: Analysis = helpers.add_analysis(store=base_store, pipeline=Workflow.BALSAMIC) + balsamic_analysis: Analysis = helpers.add_analysis(store=base_store, workflow=Workflow.BALSAMIC) mip_analysis: Analysis = helpers.add_analysis( - store=base_store, case=case, pipeline=Workflow.MIP_DNA + store=base_store, case=case, workflow=Workflow.MIP_DNA ) # WHEN extracting the analyses - analyses: Query = filter_analyses_with_pipeline( - analyses=base_store._get_query(table=Analysis), pipeline=Workflow.BALSAMIC + analyses: Query = filter_analyses_with_workflow( + analyses=base_store._get_query(table=Analysis), workflow=Workflow.BALSAMIC ) # ASSERT that analyses is a query @@ -166,18 +166,18 @@ def test_filter_analyses_without_delivery_report(base_store: Store, helpers: Sto assert analysis_without_delivery_report in analyses -def test_filter_report_analyses_by_pipeline(base_store: Store, helpers: StoreHelpers, case: Case): +def test_filter_report_analyses_by_workflow(base_store: Store, helpers: StoreHelpers, case: Case): """Test filtering delivery report related analysis by pipeline.""" # GIVEN a set of mock analysis - balsamic_analysis: Analysis = helpers.add_analysis(store=base_store, pipeline=Workflow.BALSAMIC) + balsamic_analysis: Analysis = helpers.add_analysis(store=base_store, workflow=Workflow.BALSAMIC) fluffy_analysis: Analysis = helpers.add_analysis( - store=base_store, case=case, pipeline=Workflow.FLUFFY + store=base_store, case=case, workflow=Workflow.FLUFFY ) # WHEN filtering delivery report related analyses - analyses: Query = filter_report_analyses_by_pipeline( - analyses=base_store._get_query(table=Analysis), pipeline=Workflow.BALSAMIC + analyses: Query = filter_report_analyses_by_workflow( + analyses=base_store._get_query(table=Analysis), workflow=Workflow.BALSAMIC ) # ASSERT that analyses is a query @@ -262,7 +262,7 @@ def test_filter_analysis_started_before( store=base_store, started_at=timestamp_now - timedelta(days=1) ) analysis: Analysis = helpers.add_analysis( - store=base_store, started_at=timestamp_now, case=analysis_old.case + store=base_store, case=analysis_old.case, started_at=timestamp_now ) # WHEN filtering the analyses by started_at @@ -286,7 +286,7 @@ def test_filter_analysis_not_cleaned( # GIVEN a set of mock analyses analysis_cleaned: Analysis = helpers.add_analysis(store=base_store, cleaned_at=timestamp_now) analysis: Analysis = helpers.add_analysis( - store=base_store, cleaned_at=None, case=analysis_cleaned.case + store=base_store, case=analysis_cleaned.case, cleaned_at=None ) # WHEN filtering the analyses by cleaned_at @@ -310,9 +310,7 @@ def test_filter_analyses_by_started_at( store=base_store, started_at=timestamp_now ) analysis_started_old: Analysis = helpers.add_analysis( - store=base_store, - started_at=timestamp_yesterday, - case=analysis_started_now.case, + store=base_store, case=analysis_started_now.case, started_at=timestamp_yesterday ) # WHEN filtering the analyses by started_at diff --git a/tests/store/filters/test_status_application_limitations_filters.py b/tests/store/filters/test_status_application_limitations_filters.py index d1a4b5632a..e8b3ce1a48 100644 --- a/tests/store/filters/test_status_application_limitations_filters.py +++ b/tests/store/filters/test_status_application_limitations_filters.py @@ -2,8 +2,8 @@ from cg.constants import Workflow from cg.store.filters.status_application_limitations_filters import ( - filter_application_limitations_by_pipeline, filter_application_limitations_by_tag, + filter_application_limitations_by_workflow, ) from cg.store.store import Store from tests.store.conftest import StoreConstants @@ -34,18 +34,18 @@ def test_filter_application_limitations_by_tag( ) -def test_filter_application_limitations_by_pipeline( +def test_filter_application_limitations_by_workflow( store_with_application_limitations: Store, - pipeline=Workflow.BALSAMIC, + workflow=Workflow.BALSAMIC, ) -> None: """Test to get application limitations by pipeline.""" # GIVEN a store with application limitations # WHEN getting an application limitations by pipeline - application_limitations: Query = filter_application_limitations_by_pipeline( + application_limitations: Query = filter_application_limitations_by_workflow( application_limitations=store_with_application_limitations._get_join_application_limitations_query(), - pipeline=pipeline, + workflow=workflow, ) # ASSERT that application limitations is a query @@ -55,5 +55,5 @@ def test_filter_application_limitations_by_pipeline( assert ( application_limitations.all() and len(application_limitations.all()) == 1 - and application_limitations.all()[0].pipeline == pipeline + and application_limitations.all()[0].pipeline == workflow ) diff --git a/tests/store/filters/test_status_cases_filters.py b/tests/store/filters/test_status_cases_filters.py index a9f0628584..443c58c0ad 100644 --- a/tests/store/filters/test_status_cases_filters.py +++ b/tests/store/filters/test_status_cases_filters.py @@ -11,16 +11,16 @@ filter_cases_by_customer_entry_ids, filter_cases_by_entry_id, filter_cases_by_name, - filter_cases_by_pipeline_search, filter_cases_by_priority, filter_cases_by_ticket_id, + filter_cases_by_workflow_search, filter_cases_for_analysis, filter_cases_has_sequence, filter_cases_not_analysed, - filter_cases_with_loqusdb_supported_pipeline, filter_cases_with_loqusdb_supported_sequencing_method, - filter_cases_with_pipeline, + filter_cases_with_loqusdb_supported_workflow, filter_cases_with_scout_data_delivery, + filter_cases_with_workflow, filter_inactive_analysis_cases, filter_newer_cases_by_order_date, filter_older_cases_by_creation_date, @@ -140,10 +140,10 @@ def test_filter_cases_has_sequence_when_not_external_nor_sequenced( assert not cases.all() -def test_filter_cases_with_pipeline_when_correct_pipline( +def test_filter_cases_with_workflow_when_correct_workflow( base_store: Store, helpers: StoreHelpers, timestamp_now: datetime ): - """Test that no case is returned when there are no cases with the specified pipeline.""" + """Test that no case is returned when there are no cases with the specified workflow.""" # GIVEN a sequenced sample test_sample: Sample = helpers.add_sample(base_store, last_sequenced_at=timestamp_now) @@ -158,17 +158,17 @@ def test_filter_cases_with_pipeline_when_correct_pipline( # GIVEN a cases Query cases: Query = base_store._get_outer_join_cases_with_analyses_query() - # WHEN getting cases to analyse for another pipeline - cases: list[Query] = list(filter_cases_with_pipeline(cases=cases, pipeline=Workflow.BALSAMIC)) + # WHEN getting cases to analyse for another workflow + cases: list[Query] = list(filter_cases_with_workflow(cases=cases, workflow=Workflow.BALSAMIC)) # THEN cases should contain the test case assert cases -def test_filter_cases_with_pipeline_when_incorrect_pipline( +def test_filter_cases_with_workflow_when_incorrect_pipline( base_store: Store, helpers: StoreHelpers, timestamp_now: datetime ): - """Test that no case is returned when there are no cases with the specified pipeline.""" + """Test that no case is returned when there are no cases with the specified workflow.""" # GIVEN a sequenced sample test_sample: Sample = helpers.add_sample(base_store, last_sequenced_at=timestamp_now) @@ -183,14 +183,14 @@ def test_filter_cases_with_pipeline_when_incorrect_pipline( # GIVEN a cases Query cases: Query = base_store._get_outer_join_cases_with_analyses_query() - # WHEN getting cases to analyse for another pipeline - cases: list[Query] = list(filter_cases_with_pipeline(cases=cases, pipeline=Workflow.MIP_DNA)) + # WHEN getting cases to analyse for another workflow + cases: list[Query] = list(filter_cases_with_workflow(cases=cases, workflow=Workflow.MIP_DNA)) # THEN cases should not contain the test case assert not cases -def test_filter_cases_with_loqusdb_supported_pipeline( +def test_filter_cases_with_loqusdb_supported_workflow( base_store: Store, helpers: StoreHelpers, timestamp_now: datetime ): """Test retrieval of cases that support Loqusdb upload.""" @@ -219,7 +219,7 @@ def test_filter_cases_with_loqusdb_supported_pipeline( cases: Query = base_store._get_outer_join_cases_with_analyses_query() # WHEN getting cases with pipeline - cases: list[Query] = list(filter_cases_with_loqusdb_supported_pipeline(cases=cases)) + cases: list[Query] = list(filter_cases_with_loqusdb_supported_workflow(cases=cases)) # THEN only the Loqusdb supported case should be extracted assert test_mip_case in cases @@ -246,7 +246,7 @@ def test_filter_cases_with_loqusdb_supported_sequencing_method( # WHEN retrieving the available cases cases: Query = filter_cases_with_loqusdb_supported_sequencing_method( - cases=cases, pipeline=Workflow.MIP_DNA + cases=cases, workflow=Workflow.MIP_DNA ) # ASSERT that cases is a query @@ -276,7 +276,7 @@ def test_filter_cases_with_loqusdb_supported_sequencing_method_empty( # WHEN retrieving the valid cases cases: Query = filter_cases_with_loqusdb_supported_sequencing_method( - cases=cases, pipeline=Workflow.MIP_DNA + cases=cases, workflow=Workflow.MIP_DNA ) # ASSERT that cases is a query @@ -296,7 +296,7 @@ def test_filter_cases_for_analysis( # GIVEN a completed analysis test_analysis: Analysis = helpers.add_analysis( - base_store, completed_at=timestamp_now, pipeline=Workflow.MIP_DNA + base_store, completed_at=timestamp_now, workflow=Workflow.MIP_DNA ) # Given an action set to analyze @@ -363,7 +363,7 @@ def test_filter_cases_for_analysis_when_cases_with_no_action_and_new_sequence_da ) # GIVEN a completed analysis - test_analysis: Analysis = helpers.add_analysis(base_store, pipeline=Workflow.MIP_DNA) + test_analysis: Analysis = helpers.add_analysis(base_store, workflow=Workflow.MIP_DNA) # Given an action set to None test_analysis.case.action = None @@ -399,7 +399,7 @@ def test_filter_cases_for_analysis_when_cases_with_no_action_and_old_sequence_da ) # GIVEN a completed analysis - test_analysis: Analysis = helpers.add_analysis(base_store, pipeline=Workflow.MIP_DNA) + test_analysis: Analysis = helpers.add_analysis(base_store, workflow=Workflow.MIP_DNA) # Given an action set to None test_analysis.case.action: str | None = None @@ -840,59 +840,59 @@ def test_filter_cases_not_analysed_in_progress( assert filtered_cases.count() == 0 -def test_filter_cases_by_pipeline_search_no_matching_pipeline( +def test_filter_cases_by_workflow_search_no_matching_workflow( store_with_multiple_cases_and_samples: Store, ): - """Test that no cases are returned when there are no cases with matching pipeline search.""" + """Test that no cases are returned when there are no cases with matching workflow search.""" # GIVEN a store containing cases with different pipeline names cases_query: Query = store_with_multiple_cases_and_samples._get_query(table=Case) - pipeline_search = "non_existent_pipeline" + workflow_search = "non_existent_pipeline" - # WHEN filtering cases by a non-matching pipeline search - filtered_cases: Query = filter_cases_by_pipeline_search( - cases=cases_query, pipeline_search=pipeline_search + # WHEN filtering cases by a non-matching workflow search + filtered_cases: Query = filter_cases_by_workflow_search( + cases=cases_query, workflow_search=workflow_search ) # THEN the query should return no cases assert filtered_cases.count() == 0 -def test_filter_cases_by_pipeline_search_partial_match( +def test_filter_cases_by_workflow_search_partial_match( store_with_multiple_cases_and_samples: Store, ): """Test that cases with partially matching pipeline search are returned.""" # GIVEN a store containing cases with different pipeline names cases_query: Query = store_with_multiple_cases_and_samples._get_query(table=Case) - pipeline_search = cases_query.first().data_analysis[:3] + workflow_search = cases_query.first().data_analysis[:3] - # WHEN filtering cases by a partially matching pipeline search - filtered_cases: Query = filter_cases_by_pipeline_search( - cases=cases_query, pipeline_search=pipeline_search + # WHEN filtering cases by a partially matching workflow search + filtered_cases: Query = filter_cases_by_workflow_search( + cases=cases_query, workflow_search=workflow_search ) - # THEN the query should return the cases with partially matching pipeline names + # THEN the query should return the cases with partially matching workflow names assert filtered_cases.count() > 0 for case in filtered_cases: - assert pipeline_search in case.data_analysis + assert workflow_search in case.data_analysis -def test_filter_cases_by_pipeline_search_exact_match( +def test_filter_cases_by_workflow_search_exact_match( store_with_multiple_cases_and_samples: Store, ): - """Test that cases with exactly matching pipeline search are returned.""" + """Test that cases with exactly matching workflow search are returned.""" # GIVEN a store containing cases with different pipeline names cases_query: Query = store_with_multiple_cases_and_samples._get_query(table=Case) - pipeline_search = cases_query.first().data_analysis + workflow_search = cases_query.first().data_analysis - # WHEN filtering cases by an exactly matching pipeline search - filtered_cases: Query = filter_cases_by_pipeline_search( - cases=cases_query, pipeline_search=pipeline_search + # WHEN filtering cases by an exactly matching workflow search + filtered_cases: Query = filter_cases_by_workflow_search( + cases=cases_query, workflow_search=workflow_search ) - # THEN the query should return the cases with exactly matching pipeline names + # THEN the query should return the cases with exactly matching workflow names assert filtered_cases.count() > 0 for case in filtered_cases: - assert case.data_analysis == pipeline_search + assert case.data_analysis == workflow_search def test_filter_cases_by_priority_no_matching_priority( diff --git a/tests/store_helpers.py b/tests/store_helpers.py index 392751baf7..da781985ce 100644 --- a/tests/store_helpers.py +++ b/tests/store_helpers.py @@ -241,23 +241,20 @@ def add_application( def ensure_application_limitation( store: Store, application: Application, - pipeline: str = Workflow.MIP_DNA, + workflow: str = Workflow.MIP_DNA, limitations: str = "Dummy limitations", **kwargs, ) -> ApplicationLimitations: """Ensure that application limitations exists in store.""" application_limitation: ApplicationLimitations = ( - store.get_application_limitation_by_tag_and_pipeline( - tag=application.tag, pipeline=pipeline + store.get_application_limitation_by_tag_and_workflow( + tag=application.tag, workflow=workflow ) ) if application_limitation: return application_limitation application_limitation: ApplicationLimitations = store.add_application_limitation( - application=application, - pipeline=pipeline, - limitations=limitations, - **kwargs, + application=application, workflow=workflow, limitations=limitations, **kwargs ) store.session.add(application_limitation) store.session.commit() @@ -319,7 +316,7 @@ def add_analysis( upload_started: datetime = None, delivery_reported_at: datetime = None, cleaned_at: datetime = None, - pipeline: Workflow = Workflow.BALSAMIC, + workflow: Workflow = Workflow.BALSAMIC, pipeline_version: str = "1.0", data_delivery: DataDelivery = DataDelivery.FASTQ_QC, uploading: bool = False, @@ -328,9 +325,9 @@ def add_analysis( """Utility function to add an analysis for tests.""" if not case: - case = StoreHelpers.add_case(store, data_analysis=pipeline, data_delivery=data_delivery) + case = StoreHelpers.add_case(store, data_analysis=workflow, data_delivery=data_delivery) - analysis = store.add_analysis(pipeline=pipeline, version=pipeline_version, case_id=case.id) + analysis = store.add_analysis(workflow=workflow, version=pipeline_version, case_id=case.id) analysis.started_at = started_at or datetime.now() if completed_at: @@ -345,8 +342,8 @@ def add_analysis( analysis.upload_started_at = upload_started or datetime.now() if config_path: analysis.config_path = config_path - if pipeline: - analysis.pipeline = str(pipeline) + if workflow: + analysis.pipeline = str(workflow) analysis.limitations = "A limitation" analysis.case = case @@ -583,10 +580,10 @@ def ensure_case_from_dict( StoreHelpers.add_analysis( store, - pipeline=Workflow.MIP_DNA, case=case, - completed_at=completed_at or datetime.now(), started_at=started_at or datetime.now(), + completed_at=completed_at or datetime.now(), + workflow=Workflow.MIP_DNA, ) return case diff --git a/tests/utils/test_dispatcher.py b/tests/utils/test_dispatcher.py index 1839146380..5d4a17be9b 100644 --- a/tests/utils/test_dispatcher.py +++ b/tests/utils/test_dispatcher.py @@ -169,28 +169,28 @@ def test_dispatcher_on_other_functions( helpers: StoreHelpers, timestamp_now: datetime, timestamp_yesterday: datetime, - pipeline: Workflow = Workflow.MIP_DNA, + workflow: Workflow = Workflow.MIP_DNA, case_internal_id: str = "test_case", ): """Test that the dispatcher can be used to call functions in the status db""" # GIVEN a database with a case and an analysis case = helpers.add_case(store, internal_id=case_internal_id) - helpers.add_analysis(store, case=case, started_at=timestamp_yesterday, pipeline=pipeline) - helpers.add_analysis(store, case=case, started_at=timestamp_now, pipeline=Workflow.FLUFFY) - helpers.add_analysis(store, case=case, started_at=timestamp_yesterday, pipeline=Workflow.FLUFFY) + helpers.add_analysis(store, case=case, started_at=timestamp_yesterday, workflow=workflow) + helpers.add_analysis(store, case=case, started_at=timestamp_now, workflow=Workflow.FLUFFY) + helpers.add_analysis(store, case=case, started_at=timestamp_yesterday, workflow=Workflow.FLUFFY) # WHEN calling the dispatcher with the to get analyses function_dispatcher: Dispatcher = Dispatcher( functions=[ store.get_analyses_started_at_before, - store.get_analyses_for_case_and_pipeline_started_at_before, - store.get_analyses_for_pipeline_started_at_before, + store.get_analyses_for_case_and_workflow_started_at_before, + store.get_analyses_for_workflow_started_at_before, store.get_analyses_for_case_started_at_before, ], input_dict={ "case_internal_id": case_internal_id, - "pipeline": pipeline, + "workflow": workflow, "started_at_before": timestamp_now, }, ) @@ -200,5 +200,5 @@ def test_dispatcher_on_other_functions( for analysis in analyses: assert analysis assert analysis.case.internal_id == case_internal_id - assert analysis.pipeline == pipeline + assert analysis.pipeline == workflow assert analysis.started_at < timestamp_now