From cccee5efacf4e82ebbaa775813fd1e38c1790c2a Mon Sep 17 00:00:00 2001 From: Sebastian Allard Date: Tue, 7 Nov 2023 12:01:07 +0100 Subject: [PATCH] Rename Family to Case (#2655)(patch) --- .../20750539a335_add_ticket_to_families.py | 6 +- ...968d39ac35f_changes_in_delivery_options.py | 6 +- ...ix_sars_cov_2_data_analysis_to_database.py | 8 +- .../versions/7e344b9438bf_petname_avatar.py | 4 +- ...a5065b4_add_taxprofiler_analysis_option.py | 4 +- ...72b_add_raredisease_to_analysis_options.py | 6 +- ...998be2e367cf_fix_mip_on_fastq_wgs_cases.py | 28 +++---- .../e9df15a35de4_fix_tumour_not_to_maf.py | 24 +++--- .../fab30255b84f_move_synopsis_to_case.py | 8 +- cg/apps/downsample/downsample.py | 6 +- cg/cli/add.py | 6 +- cg/cli/compress/fastq.py | 6 +- cg/cli/compress/helpers.py | 14 ++-- cg/cli/delete/case.py | 6 +- cg/cli/delete/cases.py | 4 +- cg/cli/delete/observations.py | 4 +- cg/cli/deliver/base.py | 8 +- cg/cli/generate/report/base.py | 4 +- cg/cli/generate/report/utils.py | 12 +-- cg/cli/get.py | 14 ++-- cg/cli/set/case.py | 20 ++--- cg/cli/set/cases.py | 8 +- cg/cli/upload/base.py | 4 +- cg/cli/upload/clinical_delivery.py | 6 +- cg/cli/upload/coverage.py | 4 +- cg/cli/upload/delivery_report.py | 4 +- cg/cli/upload/genotype.py | 4 +- cg/cli/upload/gens.py | 4 +- cg/cli/upload/observations/observations.py | 4 +- cg/cli/upload/observations/utils.py | 14 ++-- cg/cli/upload/scout.py | 8 +- cg/cli/workflow/fastq/base.py | 4 +- cg/meta/deliver.py | 6 +- cg/meta/deliver_ticket.py | 12 +-- .../observations/balsamic_observations_api.py | 8 +- .../observations/mip_dna_observations_api.py | 6 +- cg/meta/observations/observations_api.py | 14 ++-- cg/meta/orders/case_submitter.py | 20 ++--- cg/meta/orders/fastq_submitter.py | 6 +- cg/meta/orders/metagenome_submitter.py | 4 +- cg/meta/orders/microbial_submitter.py | 6 +- cg/meta/orders/pool_submitter.py | 4 +- cg/meta/report/balsamic.py | 6 +- cg/meta/report/mip_dna.py | 6 +- cg/meta/report/report_api.py | 28 +++---- cg/meta/report/rnafusion.py | 4 +- cg/meta/rsync/rsync_api.py | 10 +-- cg/meta/upload/balsamic/balsamic.py | 4 +- cg/meta/upload/fohm/fohm.py | 6 +- cg/meta/upload/gt.py | 10 +-- cg/meta/upload/mip/mip_dna.py | 4 +- cg/meta/upload/mip/mip_rna.py | 4 +- cg/meta/upload/nipt/nipt.py | 6 +- cg/meta/upload/rnafusion/rnafusion.py | 4 +- cg/meta/upload/scout/mip_config_builder.py | 4 +- cg/meta/upload/scout/uploadscoutapi.py | 12 +-- cg/meta/upload/upload_api.py | 6 +- cg/meta/workflow/analysis.py | 24 +++--- cg/meta/workflow/balsamic.py | 8 +- cg/meta/workflow/balsamic_pon.py | 4 +- cg/meta/workflow/fluffy.py | 6 +- cg/meta/workflow/microsalt.py | 18 ++--- cg/meta/workflow/mip.py | 10 +-- cg/meta/workflow/mip_dna.py | 4 +- cg/meta/workflow/mip_rna.py | 4 +- cg/meta/workflow/mutant.py | 8 +- cg/meta/workflow/prepare_fastq.py | 12 +-- cg/meta/workflow/rnafusion.py | 6 +- cg/meta/workflow/taxprofiler.py | 4 +- cg/models/downsample/downsample_data.py | 14 ++-- cg/models/orders/sample_base.py | 4 +- cg/models/orders/samples.py | 4 +- cg/server/admin.py | 8 +- cg/server/api.py | 10 +-- cg/server/app.py | 4 +- cg/store/api/add.py | 10 +-- cg/store/api/base.py | 35 ++++----- cg/store/api/delete.py | 4 +- cg/store/api/find_business_data.py | 70 ++++++++--------- cg/store/api/status.py | 20 ++--- cg/store/filters/status_analysis_filters.py | 4 +- cg/store/filters/status_case_filters.py | 66 ++++++++-------- .../filters/status_case_sample_filters.py | 4 +- cg/store/filters/status_flow_cell_filters.py | 6 +- cg/store/models.py | 6 +- tests/cli/add/test_cli_add_family.py | 14 ++-- tests/cli/compress/test_cli_compress_fastq.py | 18 ++--- tests/cli/delete/test_cli_delete_case.py | 24 +++--- tests/cli/get/test_cli_get_case.py | 4 +- tests/cli/get/test_cli_get_sample.py | 6 +- tests/cli/set/test_cli_set_case.py | 16 ++-- tests/cli/set/test_cli_set_cases.py | 4 +- tests/cli/upload/test_cli_scout.py | 6 +- tests/cli/upload/test_cli_upload.py | 4 +- .../upload/test_cli_upload_observations.py | 14 ++-- tests/cli/workflow/conftest.py | 8 +- tests/cli/workflow/fastq/test_fastq_base.py | 6 +- tests/cli/workflow/mip/conftest.py | 4 +- tests/cli/workflow/mip/test_cli_mip_base.py | 12 +-- tests/conftest.py | 8 +- tests/meta/deliver/conftest.py | 4 +- tests/meta/deliver/test_delivery_api.py | 8 +- tests/meta/demultiplex/conftest.py | 6 +- .../test_meta_upload_observations.py | 30 ++++---- tests/meta/orders/test_meta_orders_api.py | 6 +- tests/meta/orders/test_meta_orders_status.py | 32 ++++---- tests/meta/report/conftest.py | 6 +- tests/meta/report/test_balsamic_api.py | 4 +- tests/meta/report/test_report_api.py | 30 ++++---- tests/meta/report/test_rnafusion_api.py | 4 +- tests/meta/rsync/conftest.py | 6 +- tests/meta/rsync/test_rsync.py | 12 +-- tests/meta/upload/balsamic/test_balsamic.py | 8 +- tests/meta/upload/conftest.py | 10 +-- tests/meta/upload/scout/conftest.py | 4 +- .../scout/test_meta_upload_scoutapi_rna.py | 16 ++-- .../meta/upload/test_meta_upload_coverage.py | 4 +- tests/meta/upload/test_upload_api.py | 4 +- tests/meta/workflow/conftest.py | 6 +- tests/meta/workflow/test_analysis.py | 26 +++---- tests/meta/workflow/test_microsalt.py | 12 +-- tests/meta/workflow/test_prepare_fastq_api.py | 6 +- tests/mocks/store_model.py | 6 +- .../store/api/delete/test_store_api_delete.py | 8 +- .../store/api/find/test_find_business_data.py | 22 +++--- .../api/find/test_find_business_data_case.py | 12 +-- .../status/test_store_api_status_analysis.py | 38 +++++----- .../api/status/test_store_api_status_cases.py | 4 +- tests/store/conftest.py | 6 +- .../filters/test_status_analyses_filters.py | 12 +-- .../filters/test_status_cases_filters.py | 76 +++++++++---------- .../filters/test_status_flow_cell_filters.py | 6 +- tests/store/test_delivery.py | 4 +- tests/store_helpers.py | 32 ++++---- 134 files changed, 722 insertions(+), 735 deletions(-) diff --git a/alembic/versions/20750539a335_add_ticket_to_families.py b/alembic/versions/20750539a335_add_ticket_to_families.py index 8ec04f2102..7c86d4ba9a 100644 --- a/alembic/versions/20750539a335_add_ticket_to_families.py +++ b/alembic/versions/20750539a335_add_ticket_to_families.py @@ -23,7 +23,7 @@ Base = declarative_base() -class Family(Base): +class Case(Base): __tablename__ = "family" id = sa.Column(sa.types.Integer, primary_key=True) @@ -37,7 +37,7 @@ class FamilySample(Base): family_id = sa.Column(sa.ForeignKey("family.id", ondelete="CASCADE"), nullable=False) sample_id = sa.Column(sa.ForeignKey("sample.id", ondelete="CASCADE"), nullable=False) - family = sa.orm.relationship("Family", backref="links") + family = sa.orm.relationship("Case", backref="links") sample = sa.orm.relationship("Sample", foreign_keys=[sample_id], backref="links") @@ -60,7 +60,7 @@ def upgrade(): op.add_column("family", sa.Column("tickets", type_=mysql.VARCHAR(128), nullable=True)) bind = op.get_bind() session = sa.orm.Session(bind=bind) - for family in session.query(Family): + for family in session.query(Case): if len(family.links) == 0: continue family.tickets = sorted( diff --git a/alembic/versions/2968d39ac35f_changes_in_delivery_options.py b/alembic/versions/2968d39ac35f_changes_in_delivery_options.py index b4ff5545b7..c92d02eefe 100644 --- a/alembic/versions/2968d39ac35f_changes_in_delivery_options.py +++ b/alembic/versions/2968d39ac35f_changes_in_delivery_options.py @@ -53,7 +53,7 @@ } -class Family(Base): +class Case(Base): __tablename__ = "family" id = Column(types.Integer, primary_key=True) data_delivery = Column(types.VARCHAR(64)) @@ -64,7 +64,7 @@ def upgrade(): op.alter_column("family", "data_delivery", type_=types.VARCHAR(64)) bind = op.get_bind() session = sa.orm.Session(bind=bind) - for case in session.query(Family): + for case in session.query(Case): if case.data_delivery in removed_options: case.data_delivery = update_map[case.data_delivery] @@ -74,7 +74,7 @@ def upgrade(): def downgrade(): bind = op.get_bind() session = sa.orm.Session(bind=bind) - for case in session.query(Family): + for case in session.query(Case): if case.data_delivery == "": case.data_delivery = None if case.data_delivery in added_options: diff --git a/alembic/versions/432379a1adfa_fix_sars_cov_2_data_analysis_to_database.py b/alembic/versions/432379a1adfa_fix_sars_cov_2_data_analysis_to_database.py index 8baabe1071..91f421d147 100644 --- a/alembic/versions/432379a1adfa_fix_sars_cov_2_data_analysis_to_database.py +++ b/alembic/versions/432379a1adfa_fix_sars_cov_2_data_analysis_to_database.py @@ -22,7 +22,7 @@ depends_on = None -class Family(Base): +class Case(Base): __tablename__ = "family" id = sa.Column(sa.types.Integer, primary_key=True) @@ -52,9 +52,9 @@ def upgrade(): op.alter_column("analysis", "pipeline", type_=new_enum) for family in ( - session.query(Family) - .filter(Family.data_delivery == str(DataDelivery.FASTQ)) - .filter(Family.data_analysis == "") + session.query(Case) + .filter(Case.data_delivery == str(DataDelivery.FASTQ)) + .filter(Case.data_analysis == "") ): print(f"Altering family: {str(family)}") family.data_analysis = str(Pipeline.SARS_COV_2) diff --git a/alembic/versions/7e344b9438bf_petname_avatar.py b/alembic/versions/7e344b9438bf_petname_avatar.py index 61512b9805..8da6de214b 100644 --- a/alembic/versions/7e344b9438bf_petname_avatar.py +++ b/alembic/versions/7e344b9438bf_petname_avatar.py @@ -22,7 +22,7 @@ Base = declarative_base() -class Family(Base): +class Case(Base): __tablename__ = "family" id = sa.Column(sa.types.Integer, primary_key=True) @@ -36,7 +36,7 @@ def __str__(self) -> str: def find_family_by_avatar_url(avatar_url, session): - return session.query(Family).filter_by(avatar_url=avatar_url).first() + return session.query(Case).filter_by(avatar_url=avatar_url).first() def upgrade(): diff --git a/alembic/versions/9008aa5065b4_add_taxprofiler_analysis_option.py b/alembic/versions/9008aa5065b4_add_taxprofiler_analysis_option.py index 473831c4ce..5da52a3de9 100644 --- a/alembic/versions/9008aa5065b4_add_taxprofiler_analysis_option.py +++ b/alembic/versions/9008aa5065b4_add_taxprofiler_analysis_option.py @@ -48,7 +48,7 @@ class Analysis(Base): pipeline = sa.Column(sa.types.Enum(*list(Pipeline))) -class Family(Base): +class Case(Base): __tablename__ = "family" id = sa.Column(sa.types.Integer, primary_key=True) data_analysis = sa.Column(sa.types.Enum(*list(Pipeline))) @@ -64,6 +64,6 @@ def downgrade(): session = sa.orm.Session(bind=bind) for analysis in session.query(Analysis).filter(Analysis.pipeline == "taxprofiler"): analysis.pipeline = "fastq" - for family in session.query(Family).filter(Family.data_analysis == "taxprofiler"): + for family in session.query(Case).filter(Case.data_analysis == "taxprofiler"): family.data_analysis = "fastq" session.commit() diff --git a/alembic/versions/9073c61bc72b_add_raredisease_to_analysis_options.py b/alembic/versions/9073c61bc72b_add_raredisease_to_analysis_options.py index 71b19edc3d..9dd2974b2f 100644 --- a/alembic/versions/9073c61bc72b_add_raredisease_to_analysis_options.py +++ b/alembic/versions/9073c61bc72b_add_raredisease_to_analysis_options.py @@ -49,7 +49,7 @@ class Analysis(Base): pipeline = sa.Column(sa.types.Enum(*list(Pipeline))) -class Family(Base): +class Case(Base): __tablename__ = "family" id = sa.Column(sa.types.Integer, primary_key=True) data_analysis = sa.Column(sa.types.Enum(*list(Pipeline))) @@ -68,8 +68,8 @@ def downgrade(): f"Changing pipeline for Analysis {Analysis.family.internal_id}, {Analysis.completed_at} to mip-dna" ) analysis.pipeline = "mip-dna" - for family in session.query(Family).filter(Family.data_analysis == "raredisease"): - print(f"Changing data_analysis for Family {family.internal_id} to mip-dna") + for family in session.query(Case).filter(Case.data_analysis == "raredisease"): + print(f"Changing data_analysis for Case {family.internal_id} to mip-dna") family.data_analysis = "mip-dna" op.alter_column("family", "data_analysis", type_=old_analysis_enum) op.alter_column("analysis", "pipeline", type_=old_analysis_enum) diff --git a/alembic/versions/998be2e367cf_fix_mip_on_fastq_wgs_cases.py b/alembic/versions/998be2e367cf_fix_mip_on_fastq_wgs_cases.py index b47ab5e0a8..e59e517b10 100644 --- a/alembic/versions/998be2e367cf_fix_mip_on_fastq_wgs_cases.py +++ b/alembic/versions/998be2e367cf_fix_mip_on_fastq_wgs_cases.py @@ -29,7 +29,7 @@ class Customer(Base): id = sa.Column(sa.types.Integer, primary_key=True) -class Family(Base): +class Case(Base): __tablename__ = "family" id = sa.Column(sa.types.Integer, primary_key=True) @@ -63,7 +63,7 @@ class FamilySample(Base): mother_id = sa.Column(sa.ForeignKey("sample.id")) father_id = sa.Column(sa.ForeignKey("sample.id")) - family = orm.relationship("Family", backref="links") + family = orm.relationship("Case", backref="links") sample = orm.relationship("Sample", foreign_keys=[sample_id], backref="links") mother = orm.relationship("Sample", foreign_keys=[mother_id], backref="mother_links") father = orm.relationship("Sample", foreign_keys=[father_id], backref="father_links") @@ -107,12 +107,12 @@ def upgrade(): count = 0 # change records that should have been run with MIP for MAF for family in ( - session.query(Family) - .filter(Family.customer_id == 1) - .filter(Family.data_delivery == DataDelivery.FASTQ) - .filter(Family.data_analysis == Pipeline.FASTQ) - .filter(Family.priority == "research") - .filter(Family.ordered_at >= datetime(year=2021, month=2, day=2)) + session.query(Case) + .filter(Case.customer_id == 1) + .filter(Case.data_delivery == DataDelivery.FASTQ) + .filter(Case.data_analysis == Pipeline.FASTQ) + .filter(Case.priority == "research") + .filter(Case.ordered_at >= datetime(year=2021, month=2, day=2)) ): if len(family.links) > 1: print(f"skipping case that has more than one link: {family}") @@ -139,12 +139,12 @@ def downgrade(): count = 0 for family in ( - session.query(Family) - .filter(Family.customer_id == 1) - .filter(Family.data_delivery == DataDelivery.FASTQ) - .filter(Family.data_analysis == Pipeline.MIP_DNA) - .filter(Family.priority == "research") - .filter(Family.ordered_at >= datetime(year=2021, month=2, day=2)) + session.query(Case) + .filter(Case.customer_id == 1) + .filter(Case.data_delivery == DataDelivery.FASTQ) + .filter(Case.data_analysis == Pipeline.MIP_DNA) + .filter(Case.priority == "research") + .filter(Case.ordered_at >= datetime(year=2021, month=2, day=2)) ): if len(family.links) > 1: print(f"skipping case that has more than one link: {family}") diff --git a/alembic/versions/e9df15a35de4_fix_tumour_not_to_maf.py b/alembic/versions/e9df15a35de4_fix_tumour_not_to_maf.py index 84f1a3126d..4e83923ae2 100644 --- a/alembic/versions/e9df15a35de4_fix_tumour_not_to_maf.py +++ b/alembic/versions/e9df15a35de4_fix_tumour_not_to_maf.py @@ -29,7 +29,7 @@ class Customer(Base): id = sa.Column(sa.types.Integer, primary_key=True) -class Family(Base): +class Case(Base): __tablename__ = "family" id = sa.Column(sa.types.Integer, primary_key=True) @@ -63,7 +63,7 @@ class FamilySample(Base): mother_id = sa.Column(sa.ForeignKey("sample.id")) father_id = sa.Column(sa.ForeignKey("sample.id")) - family = orm.relationship("Family", backref="links") + family = orm.relationship("Case", backref="links") sample = orm.relationship("Sample", foreign_keys=[sample_id], backref="links") mother = orm.relationship("Sample", foreign_keys=[mother_id], backref="mother_links") father = orm.relationship("Sample", foreign_keys=[father_id], backref="father_links") @@ -108,11 +108,11 @@ def upgrade(): count = 0 # change records that should is tumour and should not be sent to MAF for family in ( - session.query(Family) - .filter(Family.customer_id == 1) - .filter(Family.data_delivery == DataDelivery.FASTQ) - .filter(Family.data_analysis == Pipeline.MIP_DNA) - .filter(Family.priority == "research") + session.query(Case) + .filter(Case.customer_id == 1) + .filter(Case.data_delivery == DataDelivery.FASTQ) + .filter(Case.data_analysis == Pipeline.MIP_DNA) + .filter(Case.priority == "research") ): if len(family.links) > 1: print(f"skipping case that has more than one link: {family}") @@ -142,11 +142,11 @@ def downgrade(): count = 0 for family in ( - session.query(Family) - .filter(Family.customer_id == 1) - .filter(Family.data_delivery == DataDelivery.FASTQ) - .filter(Family.data_analysis == Pipeline.FASTQ) - .filter(Family.priority == "research") + session.query(Case) + .filter(Case.customer_id == 1) + .filter(Case.data_delivery == DataDelivery.FASTQ) + .filter(Case.data_analysis == Pipeline.FASTQ) + .filter(Case.priority == "research") ): if len(family.links) > 1: print(f"skipping case that has more than one link: {family}") diff --git a/alembic/versions/fab30255b84f_move_synopsis_to_case.py b/alembic/versions/fab30255b84f_move_synopsis_to_case.py index 298b8d0591..fd576aaafc 100644 --- a/alembic/versions/fab30255b84f_move_synopsis_to_case.py +++ b/alembic/versions/fab30255b84f_move_synopsis_to_case.py @@ -22,7 +22,7 @@ depends_on = None -class Family(Base): +class Case(Base): __tablename__ = "family" id = sa.Column(sa.types.Integer, primary_key=True) @@ -62,7 +62,7 @@ class FamilySample(Base): mother_id = sa.Column(sa.ForeignKey("sample.id")) father_id = sa.Column(sa.ForeignKey("sample.id")) - family = orm.relationship("Family", backref="links") + family = orm.relationship("Case", backref="links") sample = orm.relationship("Sample", foreign_keys=[sample_id], backref="links") mother = orm.relationship("Sample", foreign_keys=[mother_id], backref="mother_links") father = orm.relationship("Sample", foreign_keys=[father_id], backref="father_links") @@ -122,10 +122,10 @@ def downgrade(): op.add_column("sample", sa.Column("_cohorts", sa.TEXT)) # copy data from family._synopsis to sample._synopsis - for family in session.query(Family).filter(Family._synopsis.isnot(None)): + for family in session.query(Case).filter(Case._synopsis.isnot(None)): for link in family.links: link.sample._synopsis = family._synopsis - for family in session.query(Family).filter(Family._cohorts.isnot(None)): + for family in session.query(Case).filter(Case._cohorts.isnot(None)): for link in family.links: link.sample._cohorts = family._cohorts session.commit() diff --git a/cg/apps/downsample/downsample.py b/cg/apps/downsample/downsample.py index 1268facfa0..2c865e1faf 100644 --- a/cg/apps/downsample/downsample.py +++ b/cg/apps/downsample/downsample.py @@ -8,7 +8,7 @@ from cg.meta.workflow.downsample.downsample import DownsampleWorkflow from cg.models.cg_config import CGConfig from cg.models.downsample.downsample_data import DownsampleData -from cg.store.models import Family, FamilySample, Sample +from cg.store.models import Case, FamilySample, Sample from cg.utils.calculations import multiply_by_million LOG = logging.getLogger(__name__) @@ -67,7 +67,7 @@ def store_downsampled_case(self, downsample_data: DownsampleData) -> None: """ Add a down sampled case entry to StatusDB. """ - downsampled_case: Family = downsample_data.downsampled_case + downsampled_case: Case = downsample_data.downsampled_case if self.status_db.case_with_name_exists(case_name=downsampled_case.name): LOG.info(f"Case with name {downsampled_case.name} already exists in StatusDB.") return @@ -77,7 +77,7 @@ def store_downsampled_case(self, downsample_data: DownsampleData) -> None: LOG.info(f"New down sampled case created: {downsampled_case.internal_id}") def _link_downsampled_sample_to_case( - self, downsample_data: DownsampleData, sample: Sample, case: Family + self, downsample_data: DownsampleData, sample: Sample, case: Case ) -> None: """Create a link between sample and case in statusDB.""" sample_case_link: FamilySample = self.status_db.relate_sample( diff --git a/cg/cli/add.py b/cg/cli/add.py index 02a6048991..8598cb8270 100644 --- a/cg/cli/add.py +++ b/cg/cli/add.py @@ -13,7 +13,7 @@ ApplicationVersion, Collaboration, Customer, - Family, + Case, FamilySample, Panel, Sample, @@ -264,7 +264,7 @@ def add_case( LOG.error(f"{panel_abbreviation}: panel not found") raise click.Abort - new_case: Family = status_db.add_case( + new_case: Case = status_db.add_case( data_analysis=data_analysis, data_delivery=data_delivery, name=name, @@ -298,7 +298,7 @@ def link_sample_to_case( status_db: Store = context.status_db mother: Optional[Sample] = None father: Optional[Sample] = None - case_obj: Family = status_db.get_case_by_internal_id(internal_id=case_id) + case_obj: Case = status_db.get_case_by_internal_id(internal_id=case_id) if case_obj is None: LOG.error("%s: family not found", case_id) raise click.Abort diff --git a/cg/cli/compress/fastq.py b/cg/cli/compress/fastq.py index 9e676f2811..5d530c134f 100644 --- a/cg/cli/compress/fastq.py +++ b/cg/cli/compress/fastq.py @@ -17,7 +17,7 @@ from cg.meta.compress import CompressAPI from cg.models.cg_config import CGConfig from cg.store import Store -from cg.store.models import Family, Sample +from cg.store.models import Case, Sample LOG = logging.getLogger(__name__) @@ -51,7 +51,7 @@ def fastq_cmd( LOG.info("Running compress FASTQ") compress_api: CompressAPI = context.meta_apis["compress_api"] store: Store = context.status_db - cases: list[Family] = get_cases_to_process(case_id=case_id, days_back=days_back, store=store) + cases: list[Case] = get_cases_to_process(case_id=case_id, days_back=days_back, store=store) if not cases: LOG.info("No cases to compress") return None @@ -84,7 +84,7 @@ def clean_fastq(context: CGConfig, case_id: Optional[str], days_back: int, dry_r store: Store = context.status_db update_compress_api(compress_api, dry_run=dry_run) - cases: list[Family] = get_cases_to_process(case_id=case_id, days_back=days_back, store=store) + cases: list[Case] = get_cases_to_process(case_id=case_id, days_back=days_back, store=store) if not cases: return diff --git a/cg/cli/compress/helpers.py b/cg/cli/compress/helpers.py index dc55d903d9..3056659a87 100644 --- a/cg/cli/compress/helpers.py +++ b/cg/cli/compress/helpers.py @@ -15,19 +15,17 @@ from cg.meta.compress import CompressAPI from cg.meta.compress.files import get_spring_paths from cg.store import Store -from cg.store.models import Family +from cg.store.models import Case from cg.utils.date import get_date_days_ago LOG = logging.getLogger(__name__) -def get_cases_to_process( - days_back: int, store: Store, case_id: Optional[str] = None -) -> Optional[list[Family]]: +def get_cases_to_process(days_back: int, store: Store, case_id: Optional[str] = None) -> list[Case]: """Return cases to process.""" - cases: list[Family] = [] + cases: list[Case] = [] if case_id: - case: Family = store.get_case_by_internal_id(case_id) + case: Case = store.get_case_by_internal_id(case_id) if not case: LOG.warning(f"Could not find case {case_id}") return @@ -35,7 +33,7 @@ def get_cases_to_process( cases.append(case) else: date_threshold: dt.datetime = get_date_days_ago(days_ago=days_back) - cases: list[Family] = store.get_cases_to_compress(date_threshold=date_threshold) + cases: list[Case] = store.get_cases_to_compress(date_threshold=date_threshold) return cases @@ -125,7 +123,7 @@ def get_true_dir(dir_path: Path) -> Optional[Path]: def compress_sample_fastqs_in_cases( compress_api: CompressAPI, - cases: list[Family], + cases: list[Case], dry_run: bool, number_of_conversions: int, hours: int = None, diff --git a/cg/cli/delete/case.py b/cg/cli/delete/case.py index 68d13ef75b..f205f5df2a 100644 --- a/cg/cli/delete/case.py +++ b/cg/cli/delete/case.py @@ -8,7 +8,7 @@ from cg.cli.get import get_case as print_case from cg.constants.constants import DRY_RUN, SKIP_CONFIRMATION from cg.store import Store -from cg.store.models import Family, Sample +from cg.store.models import Case, Sample LOG = logging.getLogger(__name__) @@ -29,7 +29,7 @@ def delete_case(context: click.Context, case_id: str, dry_run: bool, yes: bool): sample. """ status_db: Store = context.obj.status_db - case: Family = status_db.get_case_by_internal_id(internal_id=case_id) + case: Case = status_db.get_case_by_internal_id(internal_id=case_id) if not case: LOG.error(f"Could not find case {case_id}") raise click.Abort @@ -58,7 +58,7 @@ def delete_case(context: click.Context, case_id: str, dry_run: bool, yes: bool): status_db.session.commit() -def _delete_links_and_samples(case_obj: Family, dry_run: bool, status_db: Store, yes: bool): +def _delete_links_and_samples(case_obj: Case, dry_run: bool, status_db: Store, yes: bool): """Delete all links from a case to samples""" samples_to_delete: list[Sample] = [] for case_link in case_obj.links: diff --git a/cg/cli/delete/cases.py b/cg/cli/delete/cases.py index 8d362a7e56..ae30ccfe29 100644 --- a/cg/cli/delete/cases.py +++ b/cg/cli/delete/cases.py @@ -4,7 +4,7 @@ from cg.cli.delete.case import delete_case from cg.store import Store -from cg.store.models import Family, Sample +from cg.store.models import Case, Sample CONFIRM = "Continue?" @@ -17,7 +17,7 @@ def _get_samples_by_identifiers(identifiers: click.Tuple([str, str]), store: Sto return store.get_samples_by_any_id(**identifier_args) -def _get_cases(identifiers: click.Tuple([str, str]), store: Store) -> [Family]: +def _get_cases(identifiers: click.Tuple([str, str]), store: Store) -> [Case]: """Get cases that have samples that match identifiers if given""" samples_by_id = _get_samples_by_identifiers(identifiers, store) _cases = set() diff --git a/cg/cli/delete/observations.py b/cg/cli/delete/observations.py index 24c4e3b04e..9d6c3738c4 100644 --- a/cg/cli/delete/observations.py +++ b/cg/cli/delete/observations.py @@ -17,7 +17,7 @@ from cg.meta.observations.mip_dna_observations_api import MipDNAObservationsAPI from cg.models.cg_config import CGConfig from cg.store import Store -from cg.store.models import Family +from cg.store.models import Case LOG = logging.getLogger(__name__) @@ -30,7 +30,7 @@ def delete_observations(context: CGConfig, case_id: str, dry_run: bool, yes: bool): """Delete a case from Loqusdb and reset the Loqusdb IDs in StatusDB.""" - case: Family = get_observations_case(context, case_id, upload=False) + case: Case = get_observations_case(context, case_id, upload=False) observations_api: Union[MipDNAObservationsAPI, BalsamicObservationsAPI] = get_observations_api( context, case ) diff --git a/cg/cli/deliver/base.py b/cg/cli/deliver/base.py index e7d088e288..ee8611cf5d 100644 --- a/cg/cli/deliver/base.py +++ b/cg/cli/deliver/base.py @@ -12,7 +12,7 @@ from cg.meta.rsync.rsync_api import RsyncAPI from cg.models.cg_config import CGConfig from cg.store import Store -from cg.store.models import Family +from cg.store.models import Case LOG = logging.getLogger(__name__) @@ -95,15 +95,15 @@ def deliver_analysis( ignore_missing_bundles=ignore_missing_bundles, ) deliver_api.set_dry_run(dry_run) - cases: list[Family] = [] + cases: list[Case] = [] if case_id: - case_obj: Family = status_db.get_case_by_internal_id(internal_id=case_id) + case_obj: Case = status_db.get_case_by_internal_id(internal_id=case_id) if not case_obj: LOG.warning("Could not find case %s", case_id) return cases.append(case_obj) else: - cases: list[Family] = status_db.get_cases_by_ticket_id(ticket_id=ticket) + cases: list[Case] = status_db.get_cases_by_ticket_id(ticket_id=ticket) if not cases: LOG.warning("Could not find cases for ticket %s", ticket) return diff --git a/cg/cli/generate/report/base.py b/cg/cli/generate/report/base.py index 9c21a5108b..10b1ae7a75 100644 --- a/cg/cli/generate/report/base.py +++ b/cg/cli/generate/report/base.py @@ -24,7 +24,7 @@ from cg.constants import EXIT_FAIL, EXIT_SUCCESS, Pipeline from cg.exc import CgError from cg.meta.report.report_api import ReportAPI -from cg.store.models import Family +from cg.store.models import Case LOG = logging.getLogger(__name__) @@ -44,7 +44,7 @@ def generate_delivery_report( ) -> None: """Creates a delivery report for the provided case.""" click.echo(click.style("--------------- DELIVERY REPORT ---------------")) - case: Family = get_report_case(context, case_id) + case: Case = get_report_case(context, case_id) report_api: ReportAPI = get_report_api(context, case) analysis_date: datetime = get_report_analysis_started(case, report_api, analysis_started_at) diff --git a/cg/cli/generate/report/utils.py b/cg/cli/generate/report/utils.py index 2192d5f2be..f29e6cc3f9 100644 --- a/cg/cli/generate/report/utils.py +++ b/cg/cli/generate/report/utils.py @@ -19,12 +19,12 @@ from cg.meta.workflow.balsamic_umi import BalsamicUmiAnalysisAPI from cg.meta.workflow.mip_dna import MipDNAAnalysisAPI from cg.meta.workflow.rnafusion import RnafusionAnalysisAPI -from cg.store.models import Family +from cg.store.models import Case LOG = logging.getLogger(__name__) -def get_report_case(context: click.Context, case_id: str) -> Family: +def get_report_case(context: click.Context, case_id: str) -> Case: """Extracts a case object for delivery report generation.""" # Default report API (MIP DNA report API) report_api: ReportAPI = ( @@ -32,14 +32,14 @@ def get_report_case(context: click.Context, case_id: str) -> Family: if context.obj.meta_apis.get("report_api") else MipDNAReportAPI(config=context.obj, analysis_api=MipDNAAnalysisAPI(config=context.obj)) ) - case: Family = report_api.status_db.get_case_by_internal_id(internal_id=case_id) + case: Case = report_api.status_db.get_case_by_internal_id(internal_id=case_id) # Missing or not valid internal case ID if not case_id or not case: LOG.warning("Invalid case ID. Retrieving available cases.") pipeline: Pipeline = ( report_api.analysis_api.pipeline if context.obj.meta_apis.get("report_api") else None ) - cases_without_delivery_report: list[Family] = ( + cases_without_delivery_report: list[Case] = ( report_api.get_cases_without_delivery_report(pipeline=pipeline) if not context.obj.meta_apis.get("upload_api") else report_api.get_cases_without_uploaded_delivery_report(pipeline=pipeline) @@ -67,7 +67,7 @@ def get_report_case(context: click.Context, case_id: str) -> Family: return case -def get_report_api(context: click.Context, case: Family) -> ReportAPI: +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") @@ -96,7 +96,7 @@ def get_report_api_pipeline(context: click.Context, pipeline: Pipeline) -> Repor def get_report_analysis_started( - case: Family, report_api: ReportAPI, analysis_started_at: Optional[str] + case: Case, report_api: ReportAPI, analysis_started_at: Optional[str] ) -> datetime: """Resolves and returns a valid analysis date.""" if not analysis_started_at: diff --git a/cg/cli/get.py b/cg/cli/get.py index 37605fa0b7..b65ba91cfd 100644 --- a/cg/cli/get.py +++ b/cg/cli/get.py @@ -7,11 +7,11 @@ from cg.models.cg_config import CGConfig from cg.store import Store -from cg.store.models import Customer, Family, Flowcell, Sample +from cg.store.models import Customer, Case, Flowcell, Sample LOG = logging.getLogger(__name__) ANALYSIS_HEADERS = ["Analysis Date", "Pipeline", "Version"] -FAMILY_HEADERS = ["Family", "Name", "Customer", "Priority", "Panels", "Action"] +FAMILY_HEADERS = ["Case", "Name", "Customer", "Priority", "Panels", "Action"] FLOW_CELL_HEADERS = ["Flowcell", "Type", "Sequencer", "Date", "Archived?", "Status"] LINK_HEADERS = ["Sample", "Mother", "Father"] SAMPLE_HEADERS = ["Sample", "Name", "Customer", "Application", "State", "Priority", "External?"] @@ -77,7 +77,7 @@ def get_sample(context: click.Context, cases: bool, hide_flow_cell: bool, sample def get_analysis(context: CGConfig, case_id: str): """Get information about case analysis.""" status_db: Store = context.status_db - case: Family = status_db.get_case_by_internal_id(internal_id=case_id) + case: Case = status_db.get_case_by_internal_id(internal_id=case_id) if case is None: LOG.error(f"{case_id}: case doesn't exist") raise click.Abort @@ -98,7 +98,7 @@ def get_analysis(context: CGConfig, case_id: str): def get_case_relations(context: CGConfig, case_id: str): """Get information about case relations.""" status_db: Store = context.status_db - case: Family = status_db.get_case_by_internal_id(internal_id=case_id) + case: Case = status_db.get_case_by_internal_id(internal_id=case_id) if case is None: LOG.error(f"{case_id}: case doesn't exist") raise click.Abort @@ -133,18 +133,18 @@ def get_case( ): """Get information about a case.""" status_db: Store = context.obj.status_db - status_db_cases: list[Family] = [] + status_db_cases: list[Case] = [] if name: customer: Customer = status_db.get_customer_by_internal_id(customer_internal_id=customer_id) if not customer: LOG.error(f"{customer_id}: customer not found") raise click.Abort - status_db_cases: Iterable[Family] = status_db.get_cases_by_customer_and_case_name_search( + status_db_cases: Iterable[Case] = status_db.get_cases_by_customer_and_case_name_search( customer=customer, case_name_search=case_ids[-1] ) else: for case_id in case_ids: - existing_case: Family = status_db.get_case_by_internal_id(internal_id=case_id) + existing_case: Case = status_db.get_case_by_internal_id(internal_id=case_id) if not existing_case: LOG.error(f"{case_id}: case doesn't exist") raise click.Abort diff --git a/cg/cli/set/case.py b/cg/cli/set/case.py index 750d31962e..bc9376fda9 100644 --- a/cg/cli/set/case.py +++ b/cg/cli/set/case.py @@ -7,7 +7,7 @@ from cg.constants import CASE_ACTIONS, DataDelivery, Pipeline, Priority from cg.models.cg_config import CGConfig from cg.store import Store -from cg.store.models import Customer, Family, Panel +from cg.store.models import Customer, Case, Panel from cg.utils.click.EnumChoice import EnumChoice LOG = logging.getLogger(__name__) @@ -59,7 +59,7 @@ def set_case( abort_on_empty_options(options=options) status_db: Store = context.status_db - case: Family = get_case(case_id=case_id, status_db=status_db) + case: Case = get_case(case_id=case_id, status_db=status_db) if action: update_action(case=case, action=action) @@ -88,8 +88,8 @@ def abort_on_empty_options(options: list[str]) -> None: raise click.Abort -def get_case(case_id: str, status_db: Store) -> Family: - case: Family = status_db.get_case_by_internal_id(internal_id=case_id) +def get_case(case_id: str, status_db: Store) -> Case: + case: Case = status_db.get_case_by_internal_id(internal_id=case_id) if case is None: LOG.error(f"Can't find case {case_id}") @@ -98,13 +98,13 @@ def get_case(case_id: str, status_db: Store) -> Family: return case -def update_action(case: Family, action: str) -> None: +def update_action(case: Case, action: str) -> None: """Update case action.""" LOG.info(f"Update action: {case.action or 'NA'} -> {action}") case.action = action -def update_customer(case: Family, customer_id: str, status_db: Store) -> None: +def update_customer(case: Case, customer_id: str, status_db: Store) -> None: customer_obj: Customer = status_db.get_customer_by_internal_id(customer_internal_id=customer_id) if customer_obj is None: @@ -115,17 +115,17 @@ def update_customer(case: Family, customer_id: str, status_db: Store) -> None: case.customer = customer_obj -def update_data_analysis(case: Family, data_analysis: Pipeline) -> None: +def update_data_analysis(case: Case, data_analysis: Pipeline) -> None: LOG.info(f"Update data_analysis: {case.data_analysis or 'NA'} -> {data_analysis}") case.data_analysis = data_analysis -def update_data_delivery(case: Family, data_delivery: DataDelivery) -> None: +def update_data_delivery(case: Case, data_delivery: DataDelivery) -> None: LOG.info(f"Update data_delivery: {case.data_delivery or 'NA'} -> {data_delivery}") case.data_delivery = data_delivery -def update_panels(case: Family, panel_abbreviations: list[str], status_db: Store) -> None: +def update_panels(case: Case, panel_abbreviations: list[str], status_db: Store) -> None: for panel_abbreviation in panel_abbreviations: panel: Panel = status_db.get_panel_by_abbreviation(abbreviation=panel_abbreviation) if panel is None: @@ -135,7 +135,7 @@ def update_panels(case: Family, panel_abbreviations: list[str], status_db: Store case.panels = panel_abbreviations -def update_priority(case: Family, priority: Priority) -> None: +def update_priority(case: Case, priority: Priority) -> None: """Update case priority.""" LOG.info(f"Update priority: {case.priority.name} -> {priority.name}") case.priority = priority diff --git a/cg/cli/set/cases.py b/cg/cli/set/cases.py index 9550ae63cc..69ee73c23c 100644 --- a/cg/cli/set/cases.py +++ b/cg/cli/set/cases.py @@ -6,7 +6,7 @@ from cg.cli.set.case import set_case from cg.constants import CASE_ACTIONS, Priority from cg.store import Store -from cg.store.models import Family, Sample +from cg.store.models import Case, Sample from cg.utils.click.EnumChoice import EnumChoice CONFIRM = "Continue?" @@ -20,10 +20,10 @@ def _get_samples_by_identifiers(identifiers: click.Tuple([str, str]), store: Sto return list(store.get_samples_by_any_id(**identifier_args)) -def _get_cases(identifiers: click.Tuple([str, str]), store: Store) -> list[Family]: +def _get_cases(identifiers: click.Tuple([str, str]), store: Store) -> list[Case]: """Get cases that have samples that match identifiers if given""" samples_by_id: list[Sample] = _get_samples_by_identifiers(identifiers, store) - cases: set[Family] = set() + cases: set[Case] = set() for sample in samples_by_id: for link in sample.links: cases.add(link.family) @@ -58,7 +58,7 @@ def set_cases( ): """Set values on many families at the same time""" store: Store = context.obj.status_db - cases_to_alter: list[Family] = _get_cases(identifiers, store) + cases_to_alter: list[Case] = _get_cases(identifiers, store) if not cases_to_alter: LOG.error("No cases to alter!") diff --git a/cg/cli/upload/base.py b/cg/cli/upload/base.py index 77ca95ff9d..16717defa4 100644 --- a/cg/cli/upload/base.py +++ b/cg/cli/upload/base.py @@ -39,7 +39,7 @@ from cg.meta.upload.upload_api import UploadAPI from cg.models.cg_config import CGConfig from cg.store import Store -from cg.store.models import Family +from cg.store.models import Case from cg.utils.click.EnumChoice import EnumChoice LOG = logging.getLogger(__name__) @@ -67,7 +67,7 @@ def upload(context: click.Context, case_id: Optional[str], restart: bool): elif case_id: # Provided case ID without a subcommand: upload everything try: upload_api.analysis_api.status_db.verify_case_exists(case_internal_id=case_id) - case: Family = upload_api.status_db.get_case_by_internal_id(internal_id=case_id) + case: Case = upload_api.status_db.get_case_by_internal_id(internal_id=case_id) upload_api.verify_analysis_upload(case_obj=case, restart=restart) except AnalysisAlreadyUploadedError: # Analysis being uploaded or it has been already uploaded diff --git a/cg/cli/upload/clinical_delivery.py b/cg/cli/upload/clinical_delivery.py index ec3759044d..e44d573a3c 100644 --- a/cg/cli/upload/clinical_delivery.py +++ b/cg/cli/upload/clinical_delivery.py @@ -14,7 +14,7 @@ from cg.meta.deliver import DeliverAPI from cg.meta.rsync import RsyncAPI from cg.store import Store -from cg.store.models import Family +from cg.store.models import Case LOG = logging.getLogger(__name__) @@ -29,7 +29,7 @@ def upload_clinical_delivery(context: click.Context, case_id: str, dry_run: bool click.echo(click.style("----------------- Clinical-delivery -----------------")) - case: Family = context.obj.status_db.get_case_by_internal_id(internal_id=case_id) + case: Case = context.obj.status_db.get_case_by_internal_id(internal_id=case_id) delivery_types: set[str] = case.get_delivery_arguments() is_sample_delivery: bool is_case_delivery: bool @@ -105,7 +105,7 @@ def auto_fastq(context: click.Context, dry_run: bool): f"Upload to clinical-delivery for {analysis_obj.family.internal_id} has already started, skipping" ) continue - case: Family = analysis_obj.family + case: Case = analysis_obj.family LOG.info(f"Uploading family: {case.internal_id}") analysis_obj.upload_started_at = dt.datetime.now() try: diff --git a/cg/cli/upload/coverage.py b/cg/cli/upload/coverage.py index 99215e3b23..ef32f65f3e 100644 --- a/cg/cli/upload/coverage.py +++ b/cg/cli/upload/coverage.py @@ -5,7 +5,7 @@ from cg.meta.upload.coverage import UploadCoverageApi from cg.models.cg_config import CGConfig from cg.store import Store -from cg.store.models import Family +from cg.store.models import Case from .utils import suggest_cases_to_upload @@ -30,7 +30,7 @@ def upload_coverage(context: CGConfig, re_upload, family_id): suggest_cases_to_upload(status_db=status_db) raise click.Abort - case_obj: Family = status_db.get_case_by_internal_id(internal_id=family_id) + case_obj: Case = status_db.get_case_by_internal_id(internal_id=family_id) upload_coverage_api = UploadCoverageApi( status_api=status_db, hk_api=context.housekeeper_api, diff --git a/cg/cli/upload/delivery_report.py b/cg/cli/upload/delivery_report.py index 1c7b8e71da..4effc89347 100644 --- a/cg/cli/upload/delivery_report.py +++ b/cg/cli/upload/delivery_report.py @@ -8,7 +8,7 @@ from cg.cli.generate.report.options import ARGUMENT_CASE_ID from cg.cli.generate.report.utils import get_report_api, get_report_case from cg.meta.report.report_api import ReportAPI -from cg.store.models import Family +from cg.store.models import Case LOG = logging.getLogger(__name__) @@ -27,7 +27,7 @@ def upload_delivery_report_to_scout( ) -> None: """Fetches a delivery report from Housekeeper and uploads it to Scout.""" click.echo(click.style("--------------- DELIVERY REPORT UPLOAD ---------------")) - case: Family = get_report_case(context, case_id) + case: Case = get_report_case(context, case_id) report_api: ReportAPI = get_report_api(context, case) version: Version = report_api.housekeeper_api.last_version(case_id) delivery_report: Optional[str] = report_api.get_delivery_report_from_hk( diff --git a/cg/cli/upload/genotype.py b/cg/cli/upload/genotype.py index facb5a1bf6..8549022b0f 100644 --- a/cg/cli/upload/genotype.py +++ b/cg/cli/upload/genotype.py @@ -9,7 +9,7 @@ from cg.meta.upload.gt import UploadGenotypesAPI from cg.models.cg_config import CGConfig from cg.store import Store -from cg.store.models import Family +from cg.store.models import Case from .utils import suggest_cases_to_upload @@ -37,7 +37,7 @@ def upload_genotypes(context: CGConfig, re_upload: bool, family_id: Optional[str if not family_id: suggest_cases_to_upload(status_db=status_db) raise click.Abort - case_obj: Family = status_db.get_case_by_internal_id(internal_id=family_id) + case_obj: Case = status_db.get_case_by_internal_id(internal_id=family_id) upload_genotypes_api = UploadGenotypesAPI(hk_api=housekeeper_api, gt_api=genotype_api) results: dict = upload_genotypes_api.data(case_obj.analyses[0]) diff --git a/cg/cli/upload/gens.py b/cg/cli/upload/gens.py index 8153a3cfcf..1af0dd1b79 100644 --- a/cg/cli/upload/gens.py +++ b/cg/cli/upload/gens.py @@ -13,7 +13,7 @@ from cg.constants.housekeeper_tags import GensAnalysisTag from cg.models.cg_config import CGConfig from cg.store import Store -from cg.store.models import Family +from cg.store.models import Case LOG = logging.getLogger(__name__) @@ -37,7 +37,7 @@ def upload_to_gens(context: CGConfig, case_id: Optional[str], dry_run: bool): suggest_cases_to_upload(status_db=status_db) raise click.Abort - family: Family = status_db.get_case_by_internal_id(internal_id=case_id) + family: Case = status_db.get_case_by_internal_id(internal_id=case_id) for sample in family.samples: hk_coverage: File = housekeeper_api.get_file_from_latest_version( diff --git a/cg/cli/upload/observations/observations.py b/cg/cli/upload/observations/observations.py index 59d128a2e4..fcc1c2a504 100644 --- a/cg/cli/upload/observations/observations.py +++ b/cg/cli/upload/observations/observations.py @@ -24,7 +24,7 @@ from cg.meta.observations.mip_dna_observations_api import MipDNAObservationsAPI from cg.models.cg_config import CGConfig from cg.store import Store -from cg.store.models import Family +from cg.store.models import Case LOG = logging.getLogger(__name__) @@ -39,7 +39,7 @@ def upload_observations_to_loqusdb(context: CGConfig, case_id: Optional[str], dr click.echo(click.style("----------------- OBSERVATIONS -----------------")) with contextlib.suppress(LoqusdbError): - case: Family = get_observations_case_to_upload(context, case_id) + case: Case = get_observations_case_to_upload(context, case_id) observations_api: Union[ MipDNAObservationsAPI, BalsamicObservationsAPI ] = get_observations_api(context, case) diff --git a/cg/cli/upload/observations/utils.py b/cg/cli/upload/observations/utils.py index 0501c8b723..9c6d86018a 100644 --- a/cg/cli/upload/observations/utils.py +++ b/cg/cli/upload/observations/utils.py @@ -13,15 +13,15 @@ from cg.meta.observations.mip_dna_observations_api import MipDNAObservationsAPI from cg.models.cg_config import CGConfig from cg.store import Store -from cg.store.models import Family +from cg.store.models import Case LOG = logging.getLogger(__name__) -def get_observations_case(context: CGConfig, case_id: str, upload: bool) -> Family: +def get_observations_case(context: CGConfig, case_id: str, upload: bool) -> Case: """Return a verified Loqusdb case.""" status_db: Store = context.status_db - case: Family = status_db.get_case_by_internal_id(internal_id=case_id) + 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: LOG.error("Invalid case ID. Retrieving available cases for Loqusdb actions.") cases_to_process: Query = ( @@ -38,9 +38,9 @@ def get_observations_case(context: CGConfig, case_id: str, upload: bool) -> Fami return case -def get_observations_case_to_upload(context: CGConfig, case_id: str) -> Family: +def get_observations_case_to_upload(context: CGConfig, case_id: str) -> Case: """Return a verified case ready to be uploaded to Loqusdb.""" - case: Family = get_observations_case(context, case_id, upload=True) + case: Case = get_observations_case(context, case_id, upload=True) if not case.customer.loqus_upload: LOG.error( f"Customer {case.customer.internal_id} is not whitelisted for upload to Loqusdb. Canceling upload for " @@ -51,7 +51,7 @@ def get_observations_case_to_upload(context: CGConfig, case_id: str) -> Family: def get_observations_api( - context: CGConfig, case: Family + context: CGConfig, case: Case ) -> Union[MipDNAObservationsAPI, BalsamicObservationsAPI]: """Return an observations API given a specific case object.""" observations_apis = { @@ -61,7 +61,7 @@ def get_observations_api( return observations_apis[case.data_analysis] -def get_sequencing_method(case: Family) -> SequencingMethod: +def get_sequencing_method(case: Case) -> SequencingMethod: """Returns the sequencing method for the given case object.""" analysis_types = [ link.sample.application_version.application.analysis_type for link in case.links diff --git a/cg/cli/upload/scout.py b/cg/cli/upload/scout.py index e871701826..c973d2dd55 100644 --- a/cg/cli/upload/scout.py +++ b/cg/cli/upload/scout.py @@ -23,7 +23,7 @@ from cg.models.cg_config import CGConfig from cg.models.scout.scout_load_config import ScoutLoadConfig from cg.store import Store -from cg.store.models import Family +from cg.store.models import Case LOG = logging.getLogger(__name__) @@ -66,7 +66,7 @@ def create_scout_load_config(context: CGConfig, case_id: str, print_console: boo status_db: Store = context.status_db LOG.info("Fetching family object") - case_obj: Family = status_db.get_case_by_internal_id(internal_id=case_id) + case_obj: Case = status_db.get_case_by_internal_id(internal_id=case_id) if not case_obj.analyses: LOG.warning("Could not find analyses for %s", case_id) @@ -214,7 +214,7 @@ def upload_multiqc_to_scout(context: CGConfig, case_id: str, dry_run: bool) -> N scout_upload_api: UploadScoutAPI = context.meta_apis["upload_api"].scout_upload_api status_db: Store = context.status_db - case: Family = status_db.get_case_by_internal_id(internal_id=case_id) + 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 ) @@ -234,7 +234,7 @@ def upload_multiqc_to_scout(context: CGConfig, case_id: str, dry_run: bool) -> N ) -def get_upload_api(case: Family, cg_config: CGConfig) -> UploadAPI: +def get_upload_api(case: Case, cg_config: CGConfig) -> UploadAPI: """Return the upload API based on the data analysis type""" analysis_apis: dict[Pipeline, UploadAPI] = { diff --git a/cg/cli/workflow/fastq/base.py b/cg/cli/workflow/fastq/base.py index e54d5bf4c3..c5bd63255d 100644 --- a/cg/cli/workflow/fastq/base.py +++ b/cg/cli/workflow/fastq/base.py @@ -7,7 +7,7 @@ from cg.constants.constants import DRY_RUN, Pipeline from cg.meta.workflow.analysis import AnalysisAPI from cg.store import Store -from cg.store.models import Analysis, Family +from cg.store.models import Analysis, Case LOG = logging.getLogger(__name__) @@ -27,7 +27,7 @@ def store_fastq_analysis(context: click.Context, case_id: str, dry_run: bool = F """Creates an analysis object in status-db for the given fast case""" LOG.info("Creating an analysis for case %s", case_id) status_db: Store = context.obj.status_db - case_obj: Family = status_db.get_case_by_internal_id(internal_id=case_id) + case_obj: Case = status_db.get_case_by_internal_id(internal_id=case_id) new_analysis: Analysis = status_db.add_analysis( pipeline=Pipeline.FASTQ, completed_at=dt.datetime.now(), diff --git a/cg/meta/deliver.py b/cg/meta/deliver.py index 8b23a1faf9..8f44181cd0 100644 --- a/cg/meta/deliver.py +++ b/cg/meta/deliver.py @@ -13,7 +13,7 @@ from cg.constants.constants import DataDelivery from cg.exc import MissingFilesError from cg.store import Store -from cg.store.models import Family, FamilySample, Sample +from cg.store.models import Case, FamilySample, Sample LOG = logging.getLogger(__name__) @@ -61,7 +61,7 @@ def set_dry_run(self, dry_run: bool) -> None: LOG.info(f"Set dry run to {dry_run}") self.dry_run = dry_run - def deliver_files(self, case_obj: Family): + def deliver_files(self, case_obj: Case): """Deliver all files for a case. If there are sample tags deliver all files for the samples as well. @@ -283,7 +283,7 @@ def _set_customer_id(self, customer_id: str) -> None: LOG.info(f"Setting customer_id to {customer_id}") self.customer_id = customer_id - def set_customer_id(self, case_obj: Family) -> None: + def set_customer_id(self, case_obj: Case) -> None: """Set the customer_id for this upload""" self._set_customer_id(case_obj.customer.internal_id) diff --git a/cg/meta/deliver_ticket.py b/cg/meta/deliver_ticket.py index 559f63a9c7..182943efb6 100644 --- a/cg/meta/deliver_ticket.py +++ b/cg/meta/deliver_ticket.py @@ -11,7 +11,7 @@ from cg.exc import CgError from cg.meta.meta import MetaAPI from cg.models.cg_config import CGConfig -from cg.store.models import Family, Sample +from cg.store.models import Case, Sample LOG = logging.getLogger(__name__) PREFIX_TO_CONCATENATE = ["MWG", "MWL", "MWM", "MWR", "MWX"] @@ -22,11 +22,11 @@ def __init__(self, config: CGConfig): super().__init__(config) self.delivery_path: Path = Path(config.delivery_path) - def get_all_cases_from_ticket(self, ticket: str) -> list[Family]: + def get_all_cases_from_ticket(self, ticket: str) -> list[Case]: return self.status_db.get_cases_by_ticket_id(ticket_id=ticket) def get_inbox_path(self, ticket: str) -> Path: - cases: list[Family] = self.get_all_cases_from_ticket(ticket=ticket) + cases: list[Case] = self.get_all_cases_from_ticket(ticket=ticket) if not cases: raise CgError( f"The customer id was not identified since no cases for ticket {ticket} was found" @@ -44,7 +44,7 @@ def check_if_upload_is_needed(self, ticket: str) -> bool: return True def generate_date_tag(self, ticket: str) -> datetime.datetime: - cases: list[Family] = self.get_all_cases_from_ticket(ticket=ticket) + cases: list[Case] = self.get_all_cases_from_ticket(ticket=ticket) return cases[0].ordered_at def generate_output_filename( @@ -91,7 +91,7 @@ def remove_files(self, reads: list[Path]) -> None: def get_samples_from_ticket(self, ticket: str) -> list: all_samples = [] - cases: list[Family] = self.get_all_cases_from_ticket(ticket=ticket) + cases: list[Case] = self.get_all_cases_from_ticket(ticket=ticket) for case in cases: for link_obj in case.links: all_samples.append(link_obj.sample.name) @@ -166,7 +166,7 @@ def get_app_tag(self, samples: list) -> str: return app_tag def check_if_concatenation_is_needed(self, ticket: str) -> bool: - cases: list[Family] = self.get_all_cases_from_ticket(ticket=ticket) + cases: list[Case] = self.get_all_cases_from_ticket(ticket=ticket) case_id = cases[0].internal_id case_obj = self.status_db.get_case_by_internal_id(internal_id=case_id) samples: list[Sample] = [link.sample for link in case_obj.links] diff --git a/cg/meta/observations/balsamic_observations_api.py b/cg/meta/observations/balsamic_observations_api.py index 28aba3c757..dd6d0d55f8 100644 --- a/cg/meta/observations/balsamic_observations_api.py +++ b/cg/meta/observations/balsamic_observations_api.py @@ -22,7 +22,7 @@ from cg.meta.observations.observations_api import ObservationsAPI from cg.models.cg_config import CGConfig from cg.models.observations.input_files import BalsamicObservationsInputFiles -from cg.store.models import Family +from cg.store.models import Case from cg.utils.dict import get_full_path_dictionary LOG = logging.getLogger(__name__) @@ -37,7 +37,7 @@ def __init__(self, config: CGConfig, sequencing_method: SequencingMethod): self.loqusdb_somatic_api: LoqusdbAPI = self.get_loqusdb_api(LoqusdbInstance.SOMATIC) self.loqusdb_tumor_api: LoqusdbAPI = self.get_loqusdb_api(LoqusdbInstance.TUMOR) - def load_observations(self, case: Family, input_files: BalsamicObservationsInputFiles) -> None: + def load_observations(self, case: Case, input_files: BalsamicObservationsInputFiles) -> None: """Load observation counts to Loqusdb for a Balsamic case.""" if self.sequencing_method not in LOQUSDB_BALSAMIC_SEQUENCING_METHODS: LOG.error( @@ -66,7 +66,7 @@ def load_observations(self, case: Family, input_files: BalsamicObservationsInput self.update_statusdb_loqusdb_id(samples=case.samples, loqusdb_id=loqusdb_id) def load_cancer_observations( - self, case: Family, input_files: BalsamicObservationsInputFiles, loqusdb_api: LoqusdbAPI + self, case: Case, input_files: BalsamicObservationsInputFiles, loqusdb_api: LoqusdbAPI ) -> None: """Load cancer observations to a specific Loqusdb API.""" is_somatic_db: bool = "somatic" in str(loqusdb_api.config_path) @@ -113,7 +113,7 @@ def extract_observations_files_from_hk( } return BalsamicObservationsInputFiles(**get_full_path_dictionary(input_files)) - def delete_case(self, case: Family) -> None: + def delete_case(self, case: Case) -> None: """Delete cancer case observations from Loqusdb.""" loqusdb_apis: list[LoqusdbAPI] = [self.loqusdb_somatic_api, self.loqusdb_tumor_api] for loqusdb_api in loqusdb_apis: diff --git a/cg/meta/observations/mip_dna_observations_api.py b/cg/meta/observations/mip_dna_observations_api.py index c32b81b6df..91d65ffa15 100644 --- a/cg/meta/observations/mip_dna_observations_api.py +++ b/cg/meta/observations/mip_dna_observations_api.py @@ -22,7 +22,7 @@ from cg.meta.observations.observations_api import ObservationsAPI from cg.models.cg_config import CGConfig from cg.models.observations.input_files import MipDNAObservationsInputFiles -from cg.store.models import Family +from cg.store.models import Case from cg.utils.dict import get_full_path_dictionary LOG = logging.getLogger(__name__) @@ -50,7 +50,7 @@ def get_loqusdb_instance(self) -> LoqusdbInstance: } return loqusdb_instances[self.sequencing_method] - def load_observations(self, case: Family, input_files: MipDNAObservationsInputFiles) -> None: + def load_observations(self, case: Case, input_files: MipDNAObservationsInputFiles) -> None: """Load observation counts to Loqusdb for a MIP-DNA case.""" if case.tumour_samples: LOG.error(f"Case {case.internal_id} has tumour samples. Cancelling upload.") @@ -103,7 +103,7 @@ def extract_observations_files_from_hk( } return MipDNAObservationsInputFiles(**get_full_path_dictionary(input_files)) - def delete_case(self, case: Family) -> None: + def delete_case(self, case: Case) -> None: """Delete rare disease case observations from Loqusdb.""" if not self.loqusdb_api.get_case(case.internal_id): LOG.error( diff --git a/cg/meta/observations/observations_api.py b/cg/meta/observations/observations_api.py index 88a673ec56..dc00847d96 100644 --- a/cg/meta/observations/observations_api.py +++ b/cg/meta/observations/observations_api.py @@ -21,7 +21,7 @@ MipDNAObservationsInputFiles, ) from cg.store import Store -from cg.store.models import Analysis, Customer, Family +from cg.store.models import Analysis, Customer, Case LOG = logging.getLogger(__name__) @@ -37,7 +37,7 @@ def __init__(self, config: CGConfig): self.loqusdb_somatic_config: CommonAppConfig = config.loqusdb_somatic self.loqusdb_tumor_config: CommonAppConfig = config.loqusdb_tumor - def upload(self, case: Family) -> None: + def upload(self, case: Case) -> None: """Upload observations to Loqusdb.""" self.check_customer_loqusdb_permissions(case.customer) input_files: Union[ @@ -46,7 +46,7 @@ def upload(self, case: Family) -> None: self.load_observations(case=case, input_files=input_files) def get_observations_input_files( - self, case: Family + self, case: Case ) -> Union[MipDNAObservationsInputFiles, BalsamicObservationsInputFiles]: """Fetch input files from a case to upload to Loqusdb.""" analysis: Analysis = case.analyses[0] @@ -80,7 +80,7 @@ def get_loqusdb_api(self, loqusdb_instance: LoqusdbInstance) -> LoqusdbAPI: @staticmethod def is_duplicate( - case: Family, + case: Case, loqusdb_api: LoqusdbAPI, profile_vcf_path: Optional[Path], profile_threshold: Optional[float], @@ -96,7 +96,7 @@ def is_duplicate( ) return bool(loqusdb_case or duplicate or case.loqusdb_uploaded_samples) - def update_statusdb_loqusdb_id(self, samples: list[Family], loqusdb_id: Optional[str]) -> None: + def update_statusdb_loqusdb_id(self, samples: list[Case], loqusdb_id: Optional[str]) -> None: """Update Loqusdb ID field in StatusDB for each of the provided samples.""" for sample in samples: sample.loqusdb_id = loqusdb_id @@ -117,7 +117,7 @@ def get_loqusdb_customers(self) -> Union[LoqusdbMipCustomers, LoqusdbBalsamicCus def load_observations( self, - case: Family, + case: Case, input_files: Union[MipDNAObservationsInputFiles, BalsamicObservationsInputFiles], ) -> None: """Load observation counts to Loqusdb.""" @@ -129,6 +129,6 @@ def extract_observations_files_from_hk( """Extract observations files given a housekeeper version.""" raise NotImplementedError - def delete_case(self, case: Family) -> None: + def delete_case(self, case: Case) -> None: """Delete case observations from Loqusdb.""" raise NotImplementedError diff --git a/cg/meta/orders/case_submitter.py b/cg/meta/orders/case_submitter.py index 1a12ae0d17..065ecb953d 100644 --- a/cg/meta/orders/case_submitter.py +++ b/cg/meta/orders/case_submitter.py @@ -9,7 +9,7 @@ from cg.meta.orders.submitter import Submitter from cg.models.orders.order import OrderIn from cg.models.orders.samples import Of1508Sample, OrderInSample -from cg.store.models import ApplicationVersion, Customer, Family, FamilySample, Sample +from cg.store.models import ApplicationVersion, Customer, Case, FamilySample, Sample LOG = logging.getLogger(__name__) @@ -122,7 +122,7 @@ def _process_case_samples(self, order: OrderIn) -> dict: if lims_map: self._fill_in_sample_ids(samples=samples, lims_map=lims_map) - new_cases: list[Family] = self.store_items_in_status( + new_cases: list[Case] = self.store_items_in_status( customer_id=status_data["customer"], order=status_data["order"], ordered=project_data["date"] if project_data else dt.datetime.now(), @@ -220,24 +220,24 @@ def order_to_status(order: OrderIn) -> dict: def store_items_in_status( self, customer_id: str, order: str, ordered: dt.datetime, ticket_id: str, items: list[dict] - ) -> list[Family]: + ) -> list[Case]: """Store cases, samples and their relationship in the Status database.""" customer: Customer = self.status.get_customer_by_internal_id( customer_internal_id=customer_id ) - new_cases: list[Family] = [] + new_cases: list[Case] = [] for case in items: - status_db_case: Family = self.status.get_case_by_internal_id( + status_db_case: Case = self.status.get_case_by_internal_id( internal_id=case["internal_id"] ) if not status_db_case: - new_case: Family = self._create_case( + new_case: Case = self._create_case( case=case, customer_obj=customer, ticket=ticket_id ) new_cases.append(new_case) self._update_case_panel(panels=case["panels"], case=new_case) - status_db_case: Family = new_case + status_db_case: Case = new_case else: self._append_ticket(ticket_id=ticket_id, case=status_db_case) self._update_action(action=CaseActions.ANALYZE, case=status_db_case) @@ -289,17 +289,17 @@ def store_items_in_status( return new_cases @staticmethod - def _update_case_panel(panels: list[str], case: Family) -> None: + def _update_case_panel(panels: list[str], case: Case) -> None: """Update case panels.""" case.panels = panels @staticmethod - def _append_ticket(ticket_id: str, case: Family) -> None: + def _append_ticket(ticket_id: str, case: Case) -> None: """Add a ticket to the case.""" case.tickets = f"{case.tickets},{ticket_id}" @staticmethod - def _update_action(action: str, case: Family) -> None: + def _update_action(action: str, case: Case) -> None: """Update action of a case.""" case.action = action diff --git a/cg/meta/orders/fastq_submitter.py b/cg/meta/orders/fastq_submitter.py index 1b6a8d3cce..f00c45b549 100644 --- a/cg/meta/orders/fastq_submitter.py +++ b/cg/meta/orders/fastq_submitter.py @@ -9,7 +9,7 @@ from cg.meta.orders.submitter import Submitter from cg.models.orders.order import OrderIn from cg.models.orders.sample_base import StatusEnum -from cg.store.models import ApplicationVersion, Customer, Family, FamilySample, Sample +from cg.store.models import ApplicationVersion, Customer, Case, FamilySample, Sample class FastqSubmitter(Submitter): @@ -57,7 +57,7 @@ def order_to_status(order: OrderIn) -> dict: def create_maf_case(self, sample_obj: Sample) -> None: """Add a MAF case to the Status database.""" - case: Family = self.status.add_case( + case: Case = self.status.add_case( data_analysis=Pipeline(Pipeline.MIP_DNA), data_delivery=DataDelivery(DataDelivery.NO_DELIVERY), name="_".join([sample_obj.name, "MAF"]), @@ -83,7 +83,7 @@ def store_items_in_status( if not customer: raise OrderError(f"Unknown customer: {customer_id}") new_samples = [] - case: Family = self.status.get_case_by_name_and_customer( + case: Case = self.status.get_case_by_name_and_customer( customer=customer, case_name=ticket_id ) submitted_case: dict = items[0] diff --git a/cg/meta/orders/metagenome_submitter.py b/cg/meta/orders/metagenome_submitter.py index 4cd5fd1f8c..8e57026539 100644 --- a/cg/meta/orders/metagenome_submitter.py +++ b/cg/meta/orders/metagenome_submitter.py @@ -8,7 +8,7 @@ from cg.models.orders.order import OrderIn from cg.models.orders.sample_base import StatusEnum from cg.models.orders.samples import MetagenomeSample -from cg.store.models import ApplicationVersion, Customer, Family, FamilySample, Sample +from cg.store.models import ApplicationVersion, Customer, Case, FamilySample, Sample class MetagenomeSubmitter(Submitter): @@ -88,7 +88,7 @@ def store_items_in_status( if customer is None: raise OrderError(f"unknown customer: {customer_id}") new_samples = [] - case: Family = self.status.get_case_by_name_and_customer( + case: Case = self.status.get_case_by_name_and_customer( customer=customer, case_name=str(ticket_id) ) case_dict: dict = items[0] diff --git a/cg/meta/orders/microbial_submitter.py b/cg/meta/orders/microbial_submitter.py index d91cb84ce2..54b7563c5c 100644 --- a/cg/meta/orders/microbial_submitter.py +++ b/cg/meta/orders/microbial_submitter.py @@ -9,7 +9,7 @@ from cg.store.models import ( ApplicationVersion, Customer, - Family, + Case, FamilySample, Organism, Sample, @@ -90,12 +90,12 @@ def store_items_in_status( with self.status.session.no_autoflush: for sample_data in items: - case: Family = self.status.get_case_by_name_and_customer( + case: Case = self.status.get_case_by_name_and_customer( customer=customer, case_name=ticket_id ) if not case: - case: Family = self.status.add_case( + case: Case = self.status.add_case( data_analysis=data_analysis, data_delivery=data_delivery, name=ticket_id, diff --git a/cg/meta/orders/pool_submitter.py b/cg/meta/orders/pool_submitter.py index 2a81bc5a53..a8ebdf49cf 100644 --- a/cg/meta/orders/pool_submitter.py +++ b/cg/meta/orders/pool_submitter.py @@ -11,7 +11,7 @@ from cg.store.models import ( ApplicationVersion, Customer, - Family, + Case, FamilySample, Pool, Sample, @@ -126,7 +126,7 @@ def store_items_in_status( ) priority: str = pool["priority"] case_name: str = self.create_case_name(ticket=ticket_id, pool_name=pool["name"]) - case: Family = self.status.get_case_by_name_and_customer( + case: Case = self.status.get_case_by_name_and_customer( customer=customer, case_name=case_name ) if not case: diff --git a/cg/meta/report/balsamic.py b/cg/meta/report/balsamic.py index 30a2dcd5f8..3c3856dc3c 100644 --- a/cg/meta/report/balsamic.py +++ b/cg/meta/report/balsamic.py @@ -37,7 +37,7 @@ ) from cg.models.report.report import CaseModel from cg.models.report.sample import SampleModel -from cg.store.models import Bed, BedVersion, Family, Sample +from cg.store.models import Bed, BedVersion, Case, Sample LOG = logging.getLogger(__name__) @@ -50,7 +50,7 @@ def __init__(self, config: CGConfig, analysis_api: BalsamicAnalysisAPI): self.analysis_api: BalsamicAnalysisAPI = analysis_api def get_sample_metadata( - self, case: Family, sample: Sample, analysis_metadata: BalsamicAnalysis + self, case: Case, sample: Sample, analysis_metadata: BalsamicAnalysis ) -> Union[BalsamicTargetedSampleMetadataModel, BalsamicWGSSampleMetadataModel]: """Return the sample metadata to include in the report.""" sample_metrics: dict[str, BalsamicQCMetrics] = analysis_metadata.sample_metrics[ @@ -115,7 +115,7 @@ def get_wgs_percent_duplication(sample_metrics: BalsamicWGSQCMetrics): else None ) - def get_data_analysis_type(self, case: Family) -> Optional[str]: + def get_data_analysis_type(self, case: Case) -> Optional[str]: """Retrieves the data analysis type carried out.""" return self.analysis_api.get_bundle_deliverables_type(case_id=case.internal_id) diff --git a/cg/meta/report/mip_dna.py b/cg/meta/report/mip_dna.py index 2dd5194ad0..a3aeeb8ba0 100644 --- a/cg/meta/report/mip_dna.py +++ b/cg/meta/report/mip_dna.py @@ -26,7 +26,7 @@ from cg.models.report.metadata import MipDNASampleMetadataModel from cg.models.report.report import CaseModel from cg.models.report.sample import SampleModel -from cg.store.models import Family, Sample +from cg.store.models import Case, Sample LOG = logging.getLogger(__name__) @@ -39,7 +39,7 @@ def __init__(self, config: CGConfig, analysis_api: MipDNAAnalysisAPI): self.analysis_api: MipDNAAnalysisAPI = analysis_api def get_sample_metadata( - self, case: Family, sample: Sample, analysis_metadata: MipAnalysis + self, case: Case, sample: Sample, analysis_metadata: MipAnalysis ) -> MipDNASampleMetadataModel: """Fetches the MIP DNA sample metadata to include in the report.""" parsed_metrics = get_sample_id_metric( @@ -56,7 +56,7 @@ def get_sample_metadata( duplicates=parsed_metrics.duplicate_reads, ) - def get_sample_coverage(self, sample: Sample, case: Family) -> dict: + def get_sample_coverage(self, sample: Sample, case: Case) -> dict: """Calculates coverage values for a specific sample.""" genes = self.get_genes_from_scout(panels=case.panels) sample_coverage = self.chanjo_api.sample_coverage( diff --git a/cg/meta/report/report_api.py b/cg/meta/report/report_api.py index 27ce157544..fa161bf683 100644 --- a/cg/meta/report/report_api.py +++ b/cg/meta/report/report_api.py @@ -32,7 +32,7 @@ Analysis, Application, ApplicationLimitations, - Family, + Case, FamilySample, Sample, ) @@ -108,14 +108,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: Pipeline) -> list[Family]: + def get_cases_without_delivery_report(self, pipeline: Pipeline) -> list[Case]: """Returns a list of cases that has been stored and need a delivery report.""" - stored_cases: list[Family] = [] + stored_cases: list[Case] = [] analyses: Query = self.status_db.analyses_to_delivery_report(pipeline=pipeline)[ :MAX_ITEMS_TO_RETRIEVE ] for analysis_obj in analyses: - case: Family = analysis_obj.family + case: Case = analysis_obj.family 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 @@ -129,14 +129,14 @@ def get_cases_without_delivery_report(self, pipeline: Pipeline) -> list[Family]: ) return stored_cases - def get_cases_without_uploaded_delivery_report(self, pipeline: Pipeline) -> list[Family]: + def get_cases_without_uploaded_delivery_report(self, pipeline: Pipeline) -> 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)[ :MAX_ITEMS_TO_RETRIEVE ] return [analysis_obj.family for analysis_obj in analyses] - def update_delivery_report_date(self, case: Family, analysis_date: datetime) -> None: + def update_delivery_report_date(self, case: Case, analysis_date: datetime) -> None: """Updates the date when 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 @@ -146,7 +146,7 @@ def update_delivery_report_date(self, case: Family, analysis_date: datetime) -> def get_report_data(self, case_id: str, analysis_date: datetime) -> ReportModel: """Fetches all the data needed to generate a delivery report.""" - case: Family = self.status_db.get_case_by_internal_id(internal_id=case_id) + case: Case = self.status_db.get_case_by_internal_id(internal_id=case_id) analysis: Analysis = self.status_db.get_analysis_by_case_entry_id_and_started_at( case_entry_id=case.id, started_at_date=analysis_date ) @@ -184,7 +184,7 @@ def validate_report_fields( return report_data @staticmethod - def get_customer_data(case: Family) -> CustomerModel: + def get_customer_data(case: Case) -> CustomerModel: """Returns customer validated attributes retrieved from status DB.""" return CustomerModel( name=case.customer.name, @@ -206,7 +206,7 @@ def get_report_version(analysis: Analysis) -> int: def get_case_data( self, - case: Family, + case: Case, analysis: Analysis, analysis_metadata: AnalysisModel, ) -> CaseModel: @@ -225,7 +225,7 @@ def get_case_data( applications=unique_applications, ) - def get_samples_data(self, case: Family, analysis_metadata: AnalysisModel) -> list[SampleModel]: + def get_samples_data(self, case: Case, analysis_metadata: AnalysisModel) -> list[SampleModel]: """Extracts all the samples associated to a specific case and their attributes.""" samples = list() case_samples: list[FamilySample] = self.status_db.get_case_samples_by_case_id( @@ -315,7 +315,7 @@ def get_sample_methods_data(self, sample_id: str) -> MethodsModel: def get_case_analysis_data( self, - case: Family, + case: Case, analysis: Analysis, analysis_metadata: AnalysisModel, ) -> DataAnalysisModel: @@ -332,7 +332,7 @@ def get_case_analysis_data( scout_files=self.get_scout_uploaded_files(case=case), ) - def get_scout_uploaded_files(self, case: Family) -> ScoutReportFiles: + def get_scout_uploaded_files(self, case: Case) -> ScoutReportFiles: """Extracts the files that will be uploaded to Scout.""" return ScoutReportFiles( snv_vcf=self.get_scout_uploaded_file_from_hk( @@ -361,14 +361,14 @@ def get_sample_timestamp_data(sample: Sample) -> TimestampModel: def get_sample_metadata( self, - case: Family, + case: Case, sample: Sample, analysis_metadata: AnalysisModel, ) -> SampleMetadataModel: """Return the sample metadata to include in the report.""" raise NotImplementedError - def get_data_analysis_type(self, case: Family) -> Optional[str]: + def get_data_analysis_type(self, case: Case) -> Optional[str]: """Retrieves the data analysis type carried out.""" case_sample: Sample = self.status_db.get_case_samples_by_case_id( case_internal_id=case.internal_id diff --git a/cg/meta/report/rnafusion.py b/cg/meta/report/rnafusion.py index 8baf426034..c81d80f7fa 100644 --- a/cg/meta/report/rnafusion.py +++ b/cg/meta/report/rnafusion.py @@ -23,7 +23,7 @@ from cg.models.report.report import CaseModel from cg.models.report.sample import SampleModel from cg.models.rnafusion.rnafusion import RnafusionAnalysis, RnafusionQCMetrics -from cg.store.models import Family, Sample +from cg.store.models import Case, Sample class RnafusionReportAPI(ReportAPI): @@ -34,7 +34,7 @@ def __init__(self, config: CGConfig, analysis_api: RnafusionAnalysisAPI): self.analysis_api: RnafusionAnalysisAPI = analysis_api def get_sample_metadata( - self, case: Family, sample: Sample, analysis_metadata: RnafusionAnalysis + self, case: Case, sample: Sample, analysis_metadata: RnafusionAnalysis ) -> RnafusionSampleMetadataModel: """Return the sample metadata to include in the report.""" sample_metrics: RnafusionQCMetrics = analysis_metadata.sample_metrics[sample.internal_id] diff --git a/cg/meta/rsync/rsync_api.py b/cg/meta/rsync/rsync_api.py index e79030a603..a052eee219 100644 --- a/cg/meta/rsync/rsync_api.py +++ b/cg/meta/rsync/rsync_api.py @@ -18,7 +18,7 @@ from cg.meta.rsync.sbatch import COVID_RSYNC, ERROR_RSYNC_FUNCTION, RSYNC_COMMAND from cg.models.cg_config import CGConfig from cg.models.slurm.sbatch import Sbatch -from cg.store.models import Family +from cg.store.models import Case LOG = logging.getLogger(__name__) @@ -103,7 +103,7 @@ def set_log_dir(self, folder_prefix: str) -> None: LOG.info(f"Setting log dir to: {self.base_path / folder_name}") self.log_dir: Path = self.base_path / folder_name - def get_all_cases_from_ticket(self, ticket: str) -> list[Family]: + def get_all_cases_from_ticket(self, ticket: str) -> list[Case]: return self.status_db.get_cases_by_ticket_id(ticket_id=ticket) def get_source_and_destination_paths( @@ -139,7 +139,7 @@ def add_to_trailblazer_api( ticket=ticket, ) - def format_covid_report_path(self, case: Family, ticket: str) -> str: + def format_covid_report_path(self, case: Case, ticket: str) -> str: """Return a formatted of covid report path.""" covid_report_options: list[str] = glob.glob( self.covid_report_path % (case.internal_id, ticket) @@ -183,7 +183,7 @@ def get_folders_to_deliver( def slurm_rsync_single_case( self, - case: Family, + case: Case, dry_run: bool, sample_files_present: bool = False, case_files_present: bool = False, @@ -222,7 +222,7 @@ def run_rsync_on_slurm(self, ticket: str, dry_run: bool) -> int: """Runs rsync of a whole ticket folder to the delivery server.""" self.set_log_dir(folder_prefix=ticket) self.create_log_dir(dry_run=dry_run) - cases: list[Family] = self.get_all_cases_from_ticket(ticket=ticket) + cases: list[Case] = self.get_all_cases_from_ticket(ticket=ticket) if not cases: LOG.warning(f"Could not find any cases for ticket {ticket}") raise CgError() diff --git a/cg/meta/upload/balsamic/balsamic.py b/cg/meta/upload/balsamic/balsamic.py index 466e5cc0a2..955966dff6 100644 --- a/cg/meta/upload/balsamic/balsamic.py +++ b/cg/meta/upload/balsamic/balsamic.py @@ -15,7 +15,7 @@ from cg.meta.upload.upload_api import UploadAPI from cg.meta.workflow.balsamic import BalsamicAnalysisAPI from cg.models.cg_config import CGConfig -from cg.store.models import Analysis, Family +from cg.store.models import Analysis, Case LOG = logging.getLogger(__name__) @@ -27,7 +27,7 @@ def __init__(self, config: CGConfig): self.analysis_api: BalsamicAnalysisAPI = BalsamicAnalysisAPI(config) super().__init__(config=config, analysis_api=self.analysis_api) - def upload(self, ctx: click.Context, case: Family, restart: bool) -> None: + def upload(self, ctx: click.Context, case: Case, restart: bool) -> None: """Uploads BALSAMIC analysis data and files.""" analysis: Analysis = case.analyses[0] self.update_upload_started_at(analysis=analysis) diff --git a/cg/meta/upload/fohm/fohm.py b/cg/meta/upload/fohm/fohm.py index 7001dc7fa6..3c3aad7491 100644 --- a/cg/meta/upload/fohm/fohm.py +++ b/cg/meta/upload/fohm/fohm.py @@ -17,7 +17,7 @@ from cg.models.cg_config import CGConfig from cg.models.email import EmailInfo from cg.store import Store -from cg.store.models import Family, Sample +from cg.store.models import Case, Sample from cg.utils.email import send_mail LOG = logging.getLogger(__name__) @@ -281,7 +281,7 @@ def update_upload_started_at(self, case_id: str) -> None: """Update timestamp for cases which started being processed as batch""" if self._dry_run: return - case_obj: Family = self.status_db.get_case_by_internal_id(internal_id=case_id) + case_obj: Case = self.status_db.get_case_by_internal_id(internal_id=case_id) case_obj.analyses[0].upload_started_at = dt.datetime.now() self.status_db.session.commit() @@ -289,6 +289,6 @@ def update_uploaded_at(self, case_id: str) -> None: """Update timestamp for cases which uploaded successfully""" if self._dry_run: return - case_obj: Family = self.status_db.get_case_by_internal_id(internal_id=case_id) + case_obj: Case = self.status_db.get_case_by_internal_id(internal_id=case_id) case_obj.analyses[0].uploaded_at = dt.datetime.now() self.status_db.session.commit() diff --git a/cg/meta/upload/gt.py b/cg/meta/upload/gt.py index fe28f83a21..f6440c6cc8 100644 --- a/cg/meta/upload/gt.py +++ b/cg/meta/upload/gt.py @@ -9,7 +9,7 @@ from cg.constants.subject import Gender from cg.io.controller import ReadFile from cg.models.mip.mip_metrics_deliverables import MIPMetricsDeliverables -from cg.store.models import Analysis, Family, Sample +from cg.store.models import Analysis, Case, Sample LOG = logging.getLogger(__name__) @@ -55,9 +55,7 @@ def data(self, analysis_obj: Analysis) -> dict: raise ValueError(f"Pipeline {analysis_obj.pipeline} does not support Genotype upload") return data - def _get_samples_sex_mip( - self, case_obj: Family, hk_version: housekeeper_models.Version - ) -> dict: + def _get_samples_sex_mip(self, case_obj: Case, hk_version: housekeeper_models.Version) -> dict: qc_metrics_file = self.get_qcmetrics_file(hk_version) analysis_sexes = self.analysis_sex(qc_metrics_file) samples_sex = {} @@ -69,7 +67,7 @@ def _get_samples_sex_mip( } return samples_sex - def _get_samples_sex_balsamic(self, case_obj: Family) -> dict: + def _get_samples_sex_balsamic(self, case_obj: Case) -> dict: samples_sex = {} for link_obj in case_obj.links: if link_obj.sample.is_tumour: @@ -126,7 +124,7 @@ def _get_genotype_files(self, version_id: int) -> list: return self.hk.files(version=version_id, tags=["genotype"]).all() @staticmethod - def is_suitable_for_genotype_upload(case_obj: Family) -> bool: + def is_suitable_for_genotype_upload(case_obj: Case) -> bool: """Check if a cancer case is contains WGS and normal sample.""" samples: list[Sample] = case_obj.samples diff --git a/cg/meta/upload/mip/mip_dna.py b/cg/meta/upload/mip/mip_dna.py index 2920ef36a1..e7b167706c 100644 --- a/cg/meta/upload/mip/mip_dna.py +++ b/cg/meta/upload/mip/mip_dna.py @@ -16,7 +16,7 @@ from cg.meta.upload.upload_api import UploadAPI from cg.meta.workflow.mip_dna import MipDNAAnalysisAPI from cg.models.cg_config import CGConfig -from cg.store.models import Analysis, Family +from cg.store.models import Analysis, Case LOG = logging.getLogger(__name__) @@ -28,7 +28,7 @@ def __init__(self, config: CGConfig): self.analysis_api: MipDNAAnalysisAPI = MipDNAAnalysisAPI(config) super().__init__(config=config, analysis_api=self.analysis_api) - def upload(self, ctx: click.Context, case: Family, restart: bool) -> None: + def upload(self, ctx: click.Context, case: Case, restart: bool) -> None: """Uploads MIP-DNA analysis data and files.""" analysis: Analysis = case.analyses[0] self.update_upload_started_at(analysis=analysis) diff --git a/cg/meta/upload/mip/mip_rna.py b/cg/meta/upload/mip/mip_rna.py index aca18d9cac..969b4247f2 100644 --- a/cg/meta/upload/mip/mip_rna.py +++ b/cg/meta/upload/mip/mip_rna.py @@ -10,7 +10,7 @@ from cg.meta.upload.upload_api import UploadAPI from cg.meta.workflow.mip_rna import MipRNAAnalysisAPI from cg.models.cg_config import CGConfig -from cg.store.models import Analysis, Family +from cg.store.models import Analysis, Case LOG = logging.getLogger(__name__) @@ -22,7 +22,7 @@ def __init__(self, config: CGConfig): self.analysis_api: MipRNAAnalysisAPI = MipRNAAnalysisAPI(config) super().__init__(config=config, analysis_api=self.analysis_api) - def upload(self, ctx: click.Context, case: Family, restart: bool) -> None: + def upload(self, ctx: click.Context, case: Case, restart: bool) -> None: """Uploads MIP-RNA analysis data and files.""" analysis: Analysis = case.analyses[0] self.update_upload_started_at(analysis=analysis) diff --git a/cg/meta/upload/nipt/nipt.py b/cg/meta/upload/nipt/nipt.py index 8ea30cacf8..770e44b617 100644 --- a/cg/meta/upload/nipt/nipt.py +++ b/cg/meta/upload/nipt/nipt.py @@ -16,7 +16,7 @@ from cg.meta.upload.nipt.models import FlowCellQ30AndReads, StatinaUploadFiles from cg.models.cg_config import CGConfig from cg.store import Store -from cg.store.models import Analysis, Family, Flowcell +from cg.store.models import Analysis, Case, Flowcell LOG = logging.getLogger(__name__) @@ -131,7 +131,7 @@ def upload_to_ftp_server(self, results_file: Path) -> None: def update_analysis_uploaded_at_date(self, case_id: str) -> Analysis: """Updates analysis_uploaded_at for the uploaded analysis""" - case_obj: Family = self.status_db.get_case_by_internal_id(internal_id=case_id) + case_obj: Case = self.status_db.get_case_by_internal_id(internal_id=case_id) analysis_obj: Analysis = case_obj.analyses[0] if not self.dry_run: @@ -146,7 +146,7 @@ def update_analysis_uploaded_at_date(self, case_id: str) -> Analysis: def update_analysis_upload_started_date(self, case_id: str) -> Analysis: """Updates analysis_upload_started_at for the uploaded analysis""" - case_obj: Family = self.status_db.get_case_by_internal_id(internal_id=case_id) + case_obj: Case = self.status_db.get_case_by_internal_id(internal_id=case_id) analysis_obj: Analysis = case_obj.analyses[0] if not self.dry_run: diff --git a/cg/meta/upload/rnafusion/rnafusion.py b/cg/meta/upload/rnafusion/rnafusion.py index b67552be9c..13c237f7dc 100644 --- a/cg/meta/upload/rnafusion/rnafusion.py +++ b/cg/meta/upload/rnafusion/rnafusion.py @@ -11,7 +11,7 @@ from cg.meta.upload.upload_api import UploadAPI from cg.meta.workflow.rnafusion import RnafusionAnalysisAPI from cg.models.cg_config import CGConfig -from cg.store.models import Analysis, Family +from cg.store.models import Analysis, Case LOG = logging.getLogger(__name__) @@ -23,7 +23,7 @@ def __init__(self, config: CGConfig): self.analysis_api: RnafusionAnalysisAPI = RnafusionAnalysisAPI(config) super().__init__(config=config, analysis_api=self.analysis_api) - def upload(self, ctx: click.Context, case: Family, restart: bool) -> None: + def upload(self, ctx: click.Context, case: Case, restart: bool) -> None: """Upload Rnafusion analysis data and files.""" analysis: Analysis = case.analyses[0] self.update_upload_started_at(analysis=analysis) diff --git a/cg/meta/upload/scout/mip_config_builder.py b/cg/meta/upload/scout/mip_config_builder.py index 79ecf65b13..95da088ad3 100644 --- a/cg/meta/upload/scout/mip_config_builder.py +++ b/cg/meta/upload/scout/mip_config_builder.py @@ -18,7 +18,7 @@ ScoutLoadConfig, ScoutMipIndividual, ) -from cg.store.models import Analysis, Family, FamilySample +from cg.store.models import Analysis, Case, FamilySample LOG = logging.getLogger(__name__) @@ -186,7 +186,7 @@ def is_family_case(load_config: ScoutLoadConfig) -> bool: def is_multi_sample_case(load_config: ScoutLoadConfig) -> bool: return len(load_config.samples) > 1 - def run_madeline(self, family_obj: Family) -> Path: + def run_madeline(self, family_obj: Case) -> Path: """Generate a madeline file for an analysis. Use customer sample names""" samples = [ { diff --git a/cg/meta/upload/scout/uploadscoutapi.py b/cg/meta/upload/scout/uploadscoutapi.py index 70509197da..30d58addc4 100644 --- a/cg/meta/upload/scout/uploadscoutapi.py +++ b/cg/meta/upload/scout/uploadscoutapi.py @@ -24,7 +24,7 @@ from cg.meta.workflow.analysis import AnalysisAPI from cg.models.scout.scout_load_config import ScoutLoadConfig from cg.store import Store -from cg.store.models import Analysis, Customer, Family, Sample +from cg.store.models import Analysis, Customer, Case, Sample LOG = logging.getLogger(__name__) @@ -164,7 +164,7 @@ def get_rna_coverage_bigwig(self, case_id: str, sample_id: str) -> Optional[File def get_unique_dna_cases_related_to_rna_case(self, case_id: str) -> set[str]: """Return a set of unique DNA cases related to an RNA case.""" - case: Family = self.status_db.get_case_by_internal_id(case_id) + case: Case = self.status_db.get_case_by_internal_id(case_id) rna_dna_collections: list[RNADNACollection] = self.create_rna_dna_collections(case) unique_dna_cases_related_to_rna_case: set[str] = set() for rna_dna_collection in rna_dna_collections: @@ -289,7 +289,7 @@ def upload_splice_junctions_bed_to_scout(self, dry_run: bool, case_id: str) -> N """Upload splice_junctions_bed file for a case to Scout.""" status_db: Store = self.status_db - rna_case: Family = status_db.get_case_by_internal_id(case_id) + rna_case: Case = status_db.get_case_by_internal_id(case_id) rna_dna_collections: list[RNADNACollection] = self.create_rna_dna_collections(rna_case) for rna_dna_collection in rna_dna_collections: @@ -383,7 +383,7 @@ def get_config_builder(self, analysis, hk_version) -> ScoutConfigBuilder: return config_builders[analysis.pipeline] - def create_rna_dna_collections(self, rna_case: Family) -> list[RNADNACollection]: + def create_rna_dna_collections(self, rna_case: Case) -> list[RNADNACollection]: return [self.create_rna_dna_collection(link.sample) for link in rna_case.links] def create_rna_dna_collection(self, rna_sample: Sample) -> RNADNACollection: @@ -426,7 +426,7 @@ def _dna_cases_related_to_dna_sample( self, dna_sample: Sample, collaborators: set[Customer] ) -> list[str]: """Maps a list of uploaded DNA cases linked to DNA sample.""" - potential_cases_related_to_dna_sample: list[Family] = [ + potential_cases_related_to_dna_sample: list[Case] = [ dna_sample_family_relation.family for dna_sample_family_relation in dna_sample.links ] return self.filter_cases_related_to_dna_sample( @@ -435,7 +435,7 @@ def _dna_cases_related_to_dna_sample( @staticmethod def filter_cases_related_to_dna_sample( - list_of_dna_cases: list[Family], collaborators: set[Customer] + 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.""" diff --git a/cg/meta/upload/upload_api.py b/cg/meta/upload/upload_api.py index dfb36ded8b..3da2e0b775 100644 --- a/cg/meta/upload/upload_api.py +++ b/cg/meta/upload/upload_api.py @@ -10,7 +10,7 @@ from cg.meta.upload.scout.uploadscoutapi import UploadScoutAPI from cg.meta.workflow.analysis import AnalysisAPI from cg.models.cg_config import CGConfig -from cg.store.models import Analysis, Family +from cg.store.models import Analysis, Case LOG = logging.getLogger(__name__) @@ -30,7 +30,7 @@ def __init__(self, config: CGConfig, analysis_api: AnalysisAPI): status_db=config.status_db, ) - def upload(self, ctx: click.Context, case: Family, restart: bool) -> None: + def upload(self, ctx: click.Context, case: Case, restart: bool) -> None: """Uploads pipeline specific analysis data and files""" raise NotImplementedError @@ -52,7 +52,7 @@ def update_uploaded_at(self, analysis: Analysis) -> None: ) @staticmethod - def verify_analysis_upload(case_obj: Family, restart: bool) -> None: + def verify_analysis_upload(case_obj: Case, restart: bool) -> None: """Verifies the state of an analysis upload in StatusDB""" if not case_obj.data_delivery: diff --git a/cg/meta/workflow/analysis.py b/cg/meta/workflow/analysis.py index 740fcf701b..d4e267e765 100644 --- a/cg/meta/workflow/analysis.py +++ b/cg/meta/workflow/analysis.py @@ -18,7 +18,7 @@ from cg.meta.workflow.fastq import FastqHandler from cg.models.analysis import AnalysisModel from cg.models.cg_config import CGConfig -from cg.store.models import Analysis, BedVersion, Family, FamilySample, Sample +from cg.store.models import Analysis, BedVersion, Case, FamilySample, Sample LOG = logging.getLogger(__name__) @@ -80,7 +80,7 @@ def verify_case_path_exists(self, case_id: str) -> None: def get_priority_for_case(self, case_id: str) -> int: """Get priority from the status db case priority""" - case_obj: Family = self.status_db.get_case_by_internal_id(internal_id=case_id) + case_obj: Case = self.status_db.get_case_by_internal_id(internal_id=case_id) return case_obj.priority.value or Priority.research def get_slurm_qos_for_case(self, case_id: str) -> str: @@ -163,10 +163,10 @@ def upload_bundle_statusdb(self, case_id: str, dry_run: bool = False) -> None: """Storing analysis bundle in StatusDB for CASE_ID""" LOG.info(f"Storing analysis in StatusDB for {case_id}") - case_obj: Family = self.status_db.get_case_by_internal_id(internal_id=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) - new_analysis: Family = self.status_db.add_analysis( + new_analysis: Case = self.status_db.add_analysis( pipeline=self.pipeline, version=pipeline_version, started_at=analysis_start, @@ -237,7 +237,7 @@ def set_statusdb_action( LOG.info(f"Dry-run: Action {action} would be set for case {case_id}") return if action in [None, *CASE_ACTIONS]: - case_obj: Family = self.status_db.get_case_by_internal_id(internal_id=case_id) + case_obj: Case = self.status_db.get_case_by_internal_id(internal_id=case_id) case_obj.action = action self.status_db.session.commit() LOG.info("Action %s set for case %s", action, case_id) @@ -252,12 +252,12 @@ def get_analyses_to_clean(self, before: dt.datetime) -> list[Analysis]: ) return analyses_to_clean - def get_cases_to_analyze(self) -> list[Family]: + def get_cases_to_analyze(self) -> list[Case]: return self.status_db.cases_to_analyze( pipeline=self.pipeline, threshold=self.use_read_count_threshold ) - def get_cases_to_store(self) -> list[Family]: + def get_cases_to_store(self) -> list[Case]: """Return cases where analysis finished successfully, and is ready to be stored in Housekeeper.""" return [ @@ -266,7 +266,7 @@ def get_cases_to_store(self) -> list[Family]: if self.trailblazer_api.is_latest_analysis_completed(case_id=case.internal_id) ] - def get_cases_to_qc(self) -> list[Family]: + def get_cases_to_qc(self) -> list[Case]: """Return cases where analysis finished successfully, and is ready for QC metrics checks.""" return [ @@ -275,7 +275,7 @@ def get_cases_to_qc(self) -> list[Family]: if self.trailblazer_api.is_latest_analysis_qc(case_id=case.internal_id) ] - def get_sample_fastq_destination_dir(self, case: Family, sample: Sample): + def get_sample_fastq_destination_dir(self, case: Case, sample: Sample): """Return the path to the FASTQ destination directory.""" raise NotImplementedError @@ -288,7 +288,7 @@ def gather_file_metadata_for_sample(self, sample_obj: Sample) -> list[dict]: ] def link_fastq_files_for_sample( - self, case_obj: Family, sample_obj: Sample, concatenate: bool = False + self, case_obj: Case, sample_obj: Sample, concatenate: bool = False ) -> None: """ Link FASTQ files for a sample to working directory. @@ -333,7 +333,7 @@ def link_fastq_files_for_sample( def get_target_bed_from_lims(self, case_id: str) -> Optional[str]: """Get target bed filename from LIMS.""" - case: Family = self.status_db.get_case_by_internal_id(internal_id=case_id) + case: Case = self.status_db.get_case_by_internal_id(internal_id=case_id) sample: Sample = case.links[0].sample if sample.from_sample: sample: Sample = self.status_db.get_sample_by_internal_id( @@ -378,7 +378,7 @@ def decompress_case(self, case_id: str, dry_run: bool) -> None: if not decompression_possible: self.decompression_running(case_id=case_id) return - case_obj: Family = self.status_db.get_case_by_internal_id(internal_id=case_id) + case_obj: Case = self.status_db.get_case_by_internal_id(internal_id=case_id) link: FamilySample any_decompression_started = False for link in case_obj.links: diff --git a/cg/meta/workflow/balsamic.py b/cg/meta/workflow/balsamic.py index 12a41b7522..5e4c6b449c 100644 --- a/cg/meta/workflow/balsamic.py +++ b/cg/meta/workflow/balsamic.py @@ -25,7 +25,7 @@ BalsamicWGSQCMetrics, ) from cg.models.cg_config import CGConfig -from cg.store.models import Family, FamilySample, Sample +from cg.store.models import Case, FamilySample, Sample from cg.utils import Process from cg.utils.utils import build_command_from_dict, get_string_from_list_by_pattern @@ -83,8 +83,8 @@ def get_case_path(self, case_id: str) -> Path: """Returns a path where the Balsamic case for the case_id should be located""" return Path(self.root_dir, case_id) - def get_cases_to_analyze(self) -> list[Family]: - cases_query: list[Family] = self.status_db.cases_to_analyze( + 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 ) cases_to_analyze = [] @@ -143,7 +143,7 @@ def get_bundle_deliverables_type(self, case_id: str) -> str: LOG.info("Found analysis type %s", analysis_type) return analysis_type - def get_sample_fastq_destination_dir(self, case: Family, sample: Sample = None) -> Path: + def get_sample_fastq_destination_dir(self, case: Case, sample: Sample = None) -> Path: """Return the path to the FASTQ destination directory.""" return Path(self.get_case_path(case.internal_id), FileFormat.FASTQ) diff --git a/cg/meta/workflow/balsamic_pon.py b/cg/meta/workflow/balsamic_pon.py index c1db687089..93d825e613 100644 --- a/cg/meta/workflow/balsamic_pon.py +++ b/cg/meta/workflow/balsamic_pon.py @@ -8,7 +8,7 @@ from cg.exc import BalsamicStartError from cg.meta.workflow.balsamic import BalsamicAnalysisAPI from cg.models.cg_config import CGConfig -from cg.store.models import Family +from cg.store.models import Case from cg.utils.utils import build_command_from_dict LOG = logging.getLogger(__name__) @@ -35,7 +35,7 @@ def config_case( dry_run: bool = False, ) -> None: """Creates a config file for BALSAMIC PON analysis.""" - case: Family = self.status_db.get_case_by_internal_id(internal_id=case_id) + case: Case = self.status_db.get_case_by_internal_id(internal_id=case_id) sample_parameters: dict = self.get_sample_params(case_id=case_id, panel_bed=panel_bed) if not sample_parameters: LOG.error(f"{case_id} has no samples tagged for Balsamic PON analysis") diff --git a/cg/meta/workflow/fluffy.py b/cg/meta/workflow/fluffy.py index ea4c51583c..adc6c81919 100644 --- a/cg/meta/workflow/fluffy.py +++ b/cg/meta/workflow/fluffy.py @@ -17,7 +17,7 @@ from cg.io.controller import WriteFile from cg.meta.workflow.analysis import AnalysisAPI from cg.models.cg_config import CGConfig -from cg.store.models import Family, Flowcell, Sample +from cg.store.models import Case, Flowcell, Sample from cg.utils import Process LOG = logging.getLogger(__name__) @@ -145,7 +145,7 @@ def link_fastq_files(self, case_id: str, dry_run: bool = False) -> None: """ Links fastq files from Housekeeper to case working directory """ - case_obj: Family = self.status_db.get_case_by_internal_id(internal_id=case_id) + case_obj: Case = self.status_db.get_case_by_internal_id(internal_id=case_id) latest_flow_cell = self.status_db.get_latest_flow_cell_on_case(family_id=case_id) workdir_path = self.get_workdir_path(case_id=case_id) if workdir_path.exists() and not dry_run: @@ -257,7 +257,7 @@ def run_fluffy( ] self.process.run_command(command_args, dry_run=dry_run) - def get_cases_to_store(self) -> list[Family]: + def get_cases_to_store(self) -> list[Case]: """Return cases where analysis finished successfully, and is ready to be stored in Housekeeper.""" return [ diff --git a/cg/meta/workflow/microsalt.py b/cg/meta/workflow/microsalt.py index 5b5c7c6b57..4fa854f7e3 100644 --- a/cg/meta/workflow/microsalt.py +++ b/cg/meta/workflow/microsalt.py @@ -24,7 +24,7 @@ from cg.meta.workflow.fastq import MicrosaltFastqHandler from cg.models.cg_config import CGConfig from cg.models.orders.sample_base import ControlEnum -from cg.store.models import Family, Sample +from cg.store.models import Case, Sample from cg.utils import Process LOG = logging.getLogger(__name__) @@ -62,7 +62,7 @@ def process(self) -> Process: def get_case_path(self, case_id: str) -> list[Path]: """Returns all paths associated with the case or single sample analysis.""" - case_obj: Family = self.status_db.get_case_by_internal_id(internal_id=case_id) + case_obj: Case = self.status_db.get_case_by_internal_id(internal_id=case_id) lims_project: str = self.get_project(case_obj.links[0].sample.internal_id) lims_project_dir_path: Path = Path(self.root_dir, "results", lims_project) @@ -122,7 +122,7 @@ def get_config_path(self, filename: str) -> Path: def get_trailblazer_config_path(self, case_id: str) -> Path: """Get trailblazer config path.""" - case_obj: Family = self.status_db.get_case_by_internal_id(internal_id=case_id) + case_obj: Case = self.status_db.get_case_by_internal_id(internal_id=case_id) sample_obj: Sample = case_obj.links[0].sample project_id: str = self.get_project(sample_obj.internal_id) return Path( @@ -132,7 +132,7 @@ def get_trailblazer_config_path(self, case_id: str) -> Path: def get_deliverables_file_path(self, case_id: str) -> Path: """Returns a path where the microSALT deliverables file for the order_id should be located""" - case_obj: Family = self.status_db.get_case_by_internal_id(internal_id=case_id) + case_obj: Case = self.status_db.get_case_by_internal_id(internal_id=case_id) order_id: str = case_obj.name deliverables_file_path = Path( self.root_dir, @@ -145,13 +145,13 @@ def get_deliverables_file_path(self, case_id: str) -> Path: LOG.info("Found deliverables file %s", deliverables_file_path) return deliverables_file_path - def get_sample_fastq_destination_dir(self, case: Family, sample: Sample) -> Path: + def get_sample_fastq_destination_dir(self, case: Case, sample: Sample) -> Path: return Path(self.get_case_fastq_path(case_id=case.internal_id), sample.internal_id) def link_fastq_files( self, case_id: str, sample_id: Optional[str], dry_run: bool = False ) -> None: - case_obj: Family = self.status_db.get_case_by_internal_id(internal_id=case_id) + case_obj: Case = self.status_db.get_case_by_internal_id(internal_id=case_id) samples: list[Sample] = self.get_samples(case_id=case_id, sample_id=sample_id) for sample_obj in samples: self.link_fastq_files_for_sample(case_obj=case_obj, sample_obj=sample_obj) @@ -163,7 +163,7 @@ def get_samples(self, case_id: str, sample_id: Optional[str] = None) -> list[Sam if sample_id: return [self.status_db.get_sample_by_internal_id(internal_id=sample_id)] - case_obj: Family = self.status_db.get_case_by_internal_id(internal_id=case_id) + case_obj: Case = self.status_db.get_case_by_internal_id(internal_id=case_id) return [link.sample for link in case_obj.links] def get_lims_comment(self, sample_id: str) -> str: @@ -256,7 +256,7 @@ def resolve_case_sample_id( def get_case_id_from_ticket(self, unique_id: str) -> tuple[str, None]: """If ticked is provided as argument, finds the corresponding case_id and returns it. Since sample_id is not specified, nothing is returned as sample_id""" - case: Family = self.status_db.get_case_by_name(name=unique_id) + case: Case = self.status_db.get_case_by_name(name=unique_id) if not case: LOG.error("No case found for ticket number: %s", unique_id) raise click.Abort @@ -277,7 +277,7 @@ def get_case_id_from_sample(self, unique_id: str) -> tuple[str, str]: def get_case_id_from_case(self, unique_id: str) -> tuple[str, None]: """If case_id is specified, validates the presence of case_id in database and returns it""" - case_obj: Family = self.status_db.get_case_by_internal_id(internal_id=unique_id) + case_obj: Case = self.status_db.get_case_by_internal_id(internal_id=unique_id) if not case_obj: LOG.error("No case found with the id: %s", unique_id) raise click.Abort diff --git a/cg/meta/workflow/mip.py b/cg/meta/workflow/mip.py index 754f82c482..eb55a8bc4e 100644 --- a/cg/meta/workflow/mip.py +++ b/cg/meta/workflow/mip.py @@ -23,7 +23,7 @@ from cg.models.mip.mip_config import MipBaseConfig from cg.models.mip.mip_metrics_deliverables import MIPMetricsDeliverables from cg.models.mip.mip_sample_info import MipBaseSampleInfo -from cg.store.models import BedVersion, Family, FamilySample, Sample +from cg.store.models import BedVersion, Case, FamilySample, Sample CLI_OPTIONS = { "config": {"option": "--config_file"}, @@ -104,7 +104,7 @@ def pedigree_config(self, case_id: str, panel_bed: str = None) -> dict: """ # Validate and reformat to MIP pedigree config format - case_obj: Family = self.status_db.get_case_by_internal_id(internal_id=case_id) + case_obj: Case = self.status_db.get_case_by_internal_id(internal_id=case_id) return ConfigHandler.make_pedigree_config( data={ "case": case_obj.internal_id, @@ -138,7 +138,7 @@ def get_sample_data(link_obj: FamilySample) -> dict[str, Union[str, int]]: "expected_coverage": link_obj.sample.application_version.application.min_sequencing_depth, } - def get_sample_fastq_destination_dir(self, case: Family, sample: Sample) -> Path: + def get_sample_fastq_destination_dir(self, case: Case, sample: Sample) -> Path: """Return the path to the FASTQ destination directory.""" return Path( self.root, @@ -286,9 +286,9 @@ def get_skip_evaluation_flag(self, case_id: str, skip_evaluation: bool) -> bool: return True return False - def get_cases_to_analyze(self) -> list[Family]: + def get_cases_to_analyze(self) -> list[Case]: """Return cases to analyze.""" - cases_query: list[Family] = self.status_db.cases_to_analyze( + cases_query: list[Case] = self.status_db.cases_to_analyze( pipeline=self.pipeline, threshold=self.use_read_count_threshold ) cases_to_analyze = [] diff --git a/cg/meta/workflow/mip_dna.py b/cg/meta/workflow/mip_dna.py index 718c125d7b..25c8ea33af 100644 --- a/cg/meta/workflow/mip_dna.py +++ b/cg/meta/workflow/mip_dna.py @@ -6,7 +6,7 @@ from cg.constants.pedigree import Pedigree from cg.meta.workflow.mip import MipAnalysisAPI from cg.models.cg_config import CGConfig -from cg.store.models import Family, FamilySample +from cg.store.models import Case, FamilySample from cg.utils import Process @@ -68,6 +68,6 @@ def config_sample( def panel(self, case_id: str, genome_build: str = GENOME_BUILD_37) -> list[str]: """Create the aggregated gene panel file""" - case_obj: Family = self.status_db.get_case_by_internal_id(internal_id=case_id) + case_obj: Case = self.status_db.get_case_by_internal_id(internal_id=case_id) all_panels = self.convert_panels(case_obj.customer.internal_id, case_obj.panels) return self.scout_api.export_panels(build=genome_build, panels=all_panels) diff --git a/cg/meta/workflow/mip_rna.py b/cg/meta/workflow/mip_rna.py index bbd488d06f..75d6b73b2b 100644 --- a/cg/meta/workflow/mip_rna.py +++ b/cg/meta/workflow/mip_rna.py @@ -5,7 +5,7 @@ from cg.constants.pedigree import Pedigree from cg.meta.workflow.mip import MipAnalysisAPI from cg.models.cg_config import CGConfig -from cg.store.models import Family +from cg.store.models import Case from cg.utils import Process @@ -60,6 +60,6 @@ def config_sample( def panel(self, case_id: str, genome_build: str = GENOME_BUILD_38) -> list[str]: """Create the aggregated gene panel file""" - case_obj: Family = self.status_db.get_case_by_internal_id(internal_id=case_id) + case_obj: Case = self.status_db.get_case_by_internal_id(internal_id=case_id) all_panels = self.convert_panels(case_obj.customer.internal_id, case_obj.panels) return self.scout_api.export_panels(build=genome_build, panels=all_panels) diff --git a/cg/meta/workflow/mutant.py b/cg/meta/workflow/mutant.py index dcf0343ece..e31a340df7 100644 --- a/cg/meta/workflow/mutant.py +++ b/cg/meta/workflow/mutant.py @@ -10,7 +10,7 @@ from cg.meta.workflow.fastq import MutantFastqHandler from cg.models.cg_config import CGConfig from cg.models.workflow.mutant import MutantSampleConfig -from cg.store.models import Application, Family, Sample +from cg.store.models import Application, Case, Sample from cg.utils import Process LOG = logging.getLogger(__name__) @@ -62,7 +62,7 @@ def get_trailblazer_config_path(self, case_id: str) -> Path: def _is_nanopore(self, application: Application) -> bool: return application.tag[3:6] == "ONT" - def get_sample_fastq_destination_dir(self, case: Family, sample: Sample) -> Path: + def get_sample_fastq_destination_dir(self, case: Case, sample: Sample) -> Path: """Return the path to the FASTQ destination directory.""" application: str = sample.application_version.application if self._is_nanopore(application=application): @@ -186,7 +186,7 @@ def run_analysis(self, case_id: str, dry_run: bool, config_artic: str = None) -> dry_run=dry_run, ) - def get_cases_to_store(self) -> list[Family]: + def get_cases_to_store(self) -> list[Case]: """Return cases where analysis has a deliverables file, and is ready to be stored in Housekeeper.""" return [ @@ -204,7 +204,7 @@ def get_metadata_for_nanopore_sample(self, sample_obj: Sample) -> list[dict]: ] def link_nanopore_fastq_for_sample( - self, case_obj: Family, sample_obj: Sample, concatenate: bool = False + self, case_obj: Case, sample_obj: Sample, concatenate: bool = False ) -> None: """ Link FASTQ files for a nanopore sample to working directory. diff --git a/cg/meta/workflow/prepare_fastq.py b/cg/meta/workflow/prepare_fastq.py index 6665a03b8a..f6943e1211 100644 --- a/cg/meta/workflow/prepare_fastq.py +++ b/cg/meta/workflow/prepare_fastq.py @@ -12,7 +12,7 @@ from cg.meta.compress.compress import CompressAPI from cg.models import CompressionData from cg.store import Store -from cg.store.models import Family, Sample +from cg.store.models import Case, Sample LOG = logging.getLogger(__name__) @@ -26,7 +26,7 @@ def __init__(self, store: Store, compress_api: CompressAPI): def get_compression_objects(self, case_id: str) -> list[CompressionData]: """Return a list of compression objects""" - case: Family = self.store.get_case_by_internal_id(internal_id=case_id) + case: Case = self.store.get_case_by_internal_id(internal_id=case_id) compression_objects = [] for link in case.links: sample: Sample = link.sample @@ -59,7 +59,7 @@ def is_sample_decompression_needed(self, sample_id: str) -> bool: ) @staticmethod - def _should_skip_sample(case: Family, sample: Sample): + def _should_skip_sample(case: Case, sample: Sample): """ For some pipelines, we want to start a partial analysis disregarding the samples with no reads. This method returns true if we should skip the sample. @@ -95,12 +95,12 @@ def can_at_least_one_sample_be_decompressed(self, case_id: str) -> bool: def add_decompressed_fastq_files_to_housekeeper(self, case_id: str) -> None: """Adds decompressed FASTQ files to Housekeeper for a case, if there are any.""" - case: Family = self.store.get_case_by_internal_id(internal_id=case_id) + case: Case = self.store.get_case_by_internal_id(internal_id=case_id) for link in case.links: sample: Sample = link.sample self.add_decompressed_sample(sample=sample, case=case) - def add_decompressed_sample(self, sample: Sample, case: Family) -> None: + def add_decompressed_sample(self, sample: Sample, case: Case) -> None: """Adds decompressed FASTQ files to Housekeeper for a sample, if there are any.""" sample_id = sample.internal_id if self._should_skip_sample(case=case, sample=sample): @@ -115,7 +115,7 @@ def add_decompressed_sample(self, sample: Sample, case: Family) -> None: ) def add_decompressed_spring_object( - self, compression: CompressionData, fastq_files: dict[Path, File], sample: Family + self, compression: CompressionData, fastq_files: dict[Path, File], sample: Case ) -> None: """Adds decompressed FASTQ files to Housekeeper related to a single spring file.""" result = True diff --git a/cg/meta/workflow/rnafusion.py b/cg/meta/workflow/rnafusion.py index 7bef589e77..fcf1afeab7 100644 --- a/cg/meta/workflow/rnafusion.py +++ b/cg/meta/workflow/rnafusion.py @@ -25,7 +25,7 @@ RnafusionParameters, RnafusionSampleSheetEntry, ) -from cg.store.models import Family, Sample +from cg.store.models import Case, Sample LOG = logging.getLogger(__name__) @@ -90,7 +90,7 @@ def get_sample_sheet_content_per_sample( def get_sample_sheet_content(self, case_id: str, strandedness: Strandedness) -> list[list[Any]]: """Returns content for sample sheet.""" - case: Family = self.status_db.get_case_by_internal_id(internal_id=case_id) + case: Case = self.status_db.get_case_by_internal_id(internal_id=case_id) if len(case.links) != 1: raise NotImplementedError( "Case objects are assumed to be related to a single sample (one link)" @@ -162,7 +162,7 @@ def get_multiqc_json_path(self, case_id: str) -> Path: def get_multiqc_json_metrics(self, case_id: str) -> list[MetricsBase]: """Get a multiqc_data.json file and returns metrics and values formatted.""" - case: Family = self.status_db.get_case_by_internal_id(internal_id=case_id) + case: Case = self.status_db.get_case_by_internal_id(internal_id=case_id) sample_id: str = case.links[0].sample.internal_id multiqc_json: MultiqcDataJson = MultiqcDataJson( **read_json(file_path=self.get_multiqc_json_path(case_id=case_id)) diff --git a/cg/meta/workflow/taxprofiler.py b/cg/meta/workflow/taxprofiler.py index 4e83b418d5..79d2c53d15 100644 --- a/cg/meta/workflow/taxprofiler.py +++ b/cg/meta/workflow/taxprofiler.py @@ -12,7 +12,7 @@ TaxprofilerParameters, TaxprofilerSampleSheetEntry, ) -from cg.store.models import Family, Sample +from cg.store.models import Case, Sample LOG = logging.getLogger(__name__) @@ -70,7 +70,7 @@ def get_sample_sheet_content( fasta: str = "", ) -> list[list[Any]]: """Write sample sheet for Taxprofiler analysis in case folder.""" - case: Family = self.status_db.get_case_by_internal_id(internal_id=case_id) + case: Case = self.status_db.get_case_by_internal_id(internal_id=case_id) sample_sheet_content = [] LOG.info(f"Samples linked to case {case_id}: {len(case.links)}") LOG.debug("Getting sample sheet information") diff --git a/cg/models/downsample/downsample_data.py b/cg/models/downsample/downsample_data.py index f154bfc341..25a87a531b 100644 --- a/cg/models/downsample/downsample_data.py +++ b/cg/models/downsample/downsample_data.py @@ -5,7 +5,7 @@ from cg.apps.housekeeper.hk import HousekeeperAPI from cg.constants import Priority from cg.store import Store -from cg.store.models import ApplicationVersion, Family, Sample +from cg.store.models import ApplicationVersion, Case, Sample from cg.utils.calculations import multiply_by_million LOG = logging.getLogger(__name__) @@ -31,10 +31,10 @@ def __init__( self.out_dir: Path = out_dir self.case_name: str = case_name self.original_sample: Sample = self.get_sample_to_downsample() - self.original_case: Family = self.get_case_to_downsample() + self.original_case: Case = self.get_case_to_downsample() self.validate_enough_reads_to_downsample() self.downsampled_sample: Sample = self._generate_statusdb_downsampled_sample_record() - self.downsampled_case: Family = self._generate_statusdb_downsampled_case() + self.downsampled_case: Case = self._generate_statusdb_downsampled_case() LOG.info(f"Downsample Data checks completed for {self.sample_id}") @property @@ -62,12 +62,12 @@ def get_sample_to_downsample(self) -> Sample: raise ValueError(f"Sample {self.sample_id} not found in StatusDB.") return sample - def get_case_to_downsample(self) -> Family: + def get_case_to_downsample(self) -> Case: """ Check if a case exists in StatusDB. Raises: ValueError """ - case: Family = self.status_db.get_case_by_internal_id(self.case_id) + case: Case = self.status_db.get_case_by_internal_id(self.case_id) if not case: raise ValueError(f"Case {self.case_id} not found in StatusDB.") return case @@ -97,11 +97,11 @@ def _generate_statusdb_downsampled_sample_record( def _generate_statusdb_downsampled_case( self, - ) -> Family: + ) -> Case: """Generate a case for the downsampled samples. The new case uses existing case data.""" if self.status_db.case_with_name_exists(case_name=self.downsampled_case_name): return self.status_db.get_case_by_name(self.downsampled_case_name) - downsampled_case: Family = self.status_db.add_case( + downsampled_case: Case = self.status_db.add_case( data_analysis=self.original_case.data_analysis, data_delivery=self.original_case.data_delivery, name=self.downsampled_case_name, diff --git a/cg/models/orders/sample_base.py b/cg/models/orders/sample_base.py index a1ba0c39f6..d53a08c8db 100644 --- a/cg/models/orders/sample_base.py +++ b/cg/models/orders/sample_base.py @@ -6,7 +6,7 @@ from cg.constants import DataDelivery, Pipeline from cg.models.orders.validators.sample_base_validators import snake_case -from cg.store.models import Application, Customer, Family, Pool, Sample +from cg.store.models import Application, Customer, Case, Pool, Sample class ControlEnum(StrEnum): @@ -70,7 +70,7 @@ class OrderSample(BaseModel): constr( pattern=NAME_PATTERN, min_length=2, - max_length=Family.name.property.columns[0].type.length, + max_length=Case.name.property.columns[0].type.length, ) ] = None father: Optional[ diff --git a/cg/models/orders/samples.py b/cg/models/orders/samples.py index dad7532435..e31b555579 100644 --- a/cg/models/orders/samples.py +++ b/cg/models/orders/samples.py @@ -13,7 +13,7 @@ SexEnum, StatusEnum, ) -from cg.store.models import Application, Family, Organism, Panel, Pool, Sample +from cg.store.models import Application, Case, Organism, Panel, Pool, Sample class OptionalIntValidator: @@ -69,7 +69,7 @@ class Of1508Sample(OrderInSample): family_name: constr( regex=NAME_PATTERN, min_length=2, - max_length=Family.name.property.columns[0].type.length, + max_length=Case.name.property.columns[0].type.length, ) case_internal_id: Optional[ constr(max_length=Sample.internal_id.property.columns[0].type.length) diff --git a/cg/server/admin.py b/cg/server/admin.py index 80b6382d67..486e4cab1c 100644 --- a/cg/server/admin.py +++ b/cg/server/admin.py @@ -243,8 +243,8 @@ class CollaborationView(BaseView): column_searchable_list = ["internal_id", "name"] -class FamilyView(BaseView): - """Admin view for Model.Family""" +class CaseView(BaseView): + """Admin view for Model.Case""" column_default_sort = ("created_at", True) column_editable_list = ["action", "comment"] @@ -392,7 +392,7 @@ class AnalysisView(BaseView): column_default_sort = ("created_at", True) column_editable_list = ["is_primary"] column_filters = ["pipeline", "pipeline_version", "is_primary"] - column_formatters = {"family": FamilyView.view_family_link} + column_formatters = {"family": CaseView.view_family_link} column_searchable_list = [ "family.internal_id", "family.name", @@ -570,7 +570,7 @@ class FamilySampleView(BaseView): column_editable_list = ["status"] column_filters = ["status"] column_formatters = { - "family": FamilyView.view_family_link, + "family": CaseView.view_family_link, "sample": SampleView.view_sample_link, } column_searchable_list = ["family.internal_id", "family.name", "sample.internal_id"] diff --git a/cg/server/api.py b/cg/server/api.py index c2b54e4c64..dc64983304 100644 --- a/cg/server/api.py +++ b/cg/server/api.py @@ -32,7 +32,7 @@ Application, ApplicationLimitations, Customer, - Family, + Case, Flowcell, Pool, Sample, @@ -169,7 +169,7 @@ def get_cases(): action: str = request.args.get("action") customers: list[Customer] = _get_current_customers() - cases: list[Family] = _get_cases(enquiry=enquiry, action=action, customers=customers) + cases: list[Case] = _get_cases(enquiry=enquiry, action=action, customers=customers) nr_cases: int = len(cases) cases_with_links: list[dict] = [case.to_dict(links=True) for case in cases] @@ -183,7 +183,7 @@ def _get_current_customers() -> Optional[list[Customer]]: def _get_cases( enquiry: Optional[str], action: Optional[str], customers: Optional[list[Customer]] -) -> list[Family]: +) -> list[Case]: """Get cases based on the provided filters.""" return db.get_cases_by_customers_action_and_case_search( case_search=enquiry, @@ -195,7 +195,7 @@ def _get_cases( @BLUEPRINT.route("/cases/") def parse_case(case_id): """Return a case with links.""" - case: Family = db.get_case_by_internal_id(internal_id=case_id) + case: Case = db.get_case_by_internal_id(internal_id=case_id) if case is None: return abort(http.HTTPStatus.NOT_FOUND) if not g.current_user.is_admin and (case.customer not in g.current_user.customers): @@ -226,7 +226,7 @@ def parse_families_in_collaboration(): @BLUEPRINT.route("/families_in_collaboration/") def parse_family_in_collaboration(family_id): """Return a family with links.""" - case: Family = db.get_case_by_internal_id(internal_id=family_id) + case: Case = db.get_case_by_internal_id(internal_id=family_id) customer: Customer = db.get_customer_by_internal_id( customer_internal_id=request.args.get("customer") ) diff --git a/cg/server/app.py b/cg/server/app.py index 0bf60fd259..fd31f2ef06 100644 --- a/cg/server/app.py +++ b/cg/server/app.py @@ -19,7 +19,7 @@ Collaboration, Customer, Delivery, - Family, + Case, FamilySample, Flowcell, Invoice, @@ -121,7 +121,7 @@ def _register_admin_views(): ) # Business data views - ext.admin.add_view(admin.FamilyView(Family, ext.db.session)) + ext.admin.add_view(admin.CaseView(Case, ext.db.session)) ext.admin.add_view(admin.FamilySampleView(FamilySample, ext.db.session)) ext.admin.add_view(admin.SampleView(Sample, ext.db.session)) ext.admin.add_view(admin.PoolView(Pool, ext.db.session)) diff --git a/cg/store/api/add.py b/cg/store/api/add.py index e57cb077ff..1ac965de60 100644 --- a/cg/store/api/add.py +++ b/cg/store/api/add.py @@ -16,7 +16,7 @@ Collaboration, Customer, Delivery, - Family, + Case, FamilySample, Flowcell, Invoice, @@ -201,8 +201,8 @@ def add_case( cohorts: Optional[list[str]] = None, priority: Optional[Priority] = Priority.standard, synopsis: Optional[str] = None, - ) -> Family: - """Build a new Family record.""" + ) -> Case: + """Build a new Case record.""" # generate a unique case id while True: @@ -212,7 +212,7 @@ def add_case( else: LOG.debug(f"{internal_id} already used - trying another id") - return Family( + return Case( cohorts=cohorts, data_analysis=str(data_analysis), data_delivery=str(data_delivery), @@ -226,7 +226,7 @@ def add_case( def relate_sample( self, - family: Family, + family: Case, sample: Sample, status: str, mother: Sample = None, diff --git a/cg/store/api/base.py b/cg/store/api/base.py index 317288cd57..1a2eb8d9c5 100644 --- a/cg/store/api/base.py +++ b/cg/store/api/base.py @@ -14,7 +14,7 @@ ApplicationLimitations, ApplicationVersion, Customer, - Family, + Case, FamilySample, Flowcell, ) @@ -37,9 +37,9 @@ def _get_query(self, table: Type[ModelBase]) -> Query: def _get_outer_join_cases_with_analyses_query(self) -> Query: """Return a query for all cases in the database with an analysis.""" return ( - self._get_query(table=Family) + self._get_query(table=Case) .outerjoin(Analysis) - .join(Family.links) + .join(Case.links) .join(FamilySample.sample) .join(ApplicationVersion) .join(Application) @@ -48,10 +48,10 @@ def _get_outer_join_cases_with_analyses_query(self) -> Query: def _get_join_cases_with_samples_query(self) -> Query: """Return a join query for all cases in the database with samples.""" return ( - self._get_query(table=Family) - .join(Family.links) + self._get_query(table=Case) + .join(Case.links) .join(FamilySample.sample) - .join(Family.customer) + .join(Case.customer) ) def _get_join_analysis_case_query(self) -> Query: @@ -66,7 +66,7 @@ def _get_join_case_sample_query(self) -> Query: def _get_join_case_and_sample_query(self) -> Query: """Return join case sample query.""" - return self._get_query(table=Family).join(Family.links).join(FamilySample.sample) + return self._get_query(table=Case).join(Case.links).join(FamilySample.sample) def _get_join_sample_and_customer_query(self) -> Query: """Return join sample and customer query.""" @@ -78,7 +78,7 @@ def _get_join_flow_cell_sample_links_query(self) -> Query: def _get_join_sample_family_query(self) -> Query: """Return a join sample case relationship query.""" - return self._get_query(table=Sample).join(Family.links).join(FamilySample.sample) + return self._get_query(table=Sample).join(Case.links).join(FamilySample.sample) def _get_join_sample_application_version_query(self) -> Query: """Return join sample to application version query.""" @@ -90,18 +90,13 @@ def _get_join_sample_application_version_query(self) -> Query: def _get_join_analysis_sample_family_query(self) -> Query: """Return join analysis to sample to case query.""" - return ( - self._get_query(table=Analysis) - .join(Family) - .join(Family.links) - .join(FamilySample.sample) - ) + return self._get_query(table=Analysis).join(Case).join(Case.links).join(FamilySample.sample) def _get_subquery_with_latest_case_analysis_date(self) -> Query: """Return a subquery with the case internal id and the date of its latest analysis.""" case_and_date: Query = ( self._get_join_analysis_case_query() - .group_by(Family.id) + .group_by(Case.id) .with_entities(Analysis.family_id, func.max(Analysis.started_at).label("started_at")) .subquery() ) @@ -131,7 +126,7 @@ def _get_filtered_case_query( priority: str, sample_id: str, ) -> Query: - cases_query: Query = self._get_query(table=Family) + cases_query: Query = self._get_query(table=Case) filter_functions: list[Callable] = [] filter_case_order_date = None @@ -163,7 +158,7 @@ def _get_filtered_case_query( # customer filters customer_filters: list[Callable] = [] if customer_id or exclude_customer_id: - cases_query = cases_query.join(Family.customer) + cases_query = cases_query.join(Case.customer) if customer_id: customer_filters.append(CustomerFilter.FILTER_BY_INTERNAL_ID) @@ -180,18 +175,18 @@ def _get_filtered_case_query( # sample filters if sample_id: - cases_query = cases_query.join(Family.links).join(FamilySample.sample) + cases_query = cases_query.join(Case.links).join(FamilySample.sample) cases_query = apply_sample_filter( samples=cases_query, filter_functions=[SampleFilter.FILTER_BY_INTERNAL_ID_PATTERN], internal_id_pattern=sample_id, ) else: - cases_query = cases_query.outerjoin(Family.links).outerjoin(FamilySample.sample) + cases_query = cases_query.outerjoin(Case.links).outerjoin(FamilySample.sample) # other joins cases_query = ( - cases_query.outerjoin(Family.analyses) + cases_query.outerjoin(Case.analyses) .outerjoin(Sample.invoice) .outerjoin(Sample.flowcells) ) diff --git a/cg/store/api/delete.py b/cg/store/api/delete.py index f502adf3c5..1f7a317a1d 100644 --- a/cg/store/api/delete.py +++ b/cg/store/api/delete.py @@ -8,7 +8,7 @@ FlowCellFilter, apply_flow_cell_filter, ) -from cg.store.models import Family, Flowcell, Sample, SampleLaneSequencingMetrics +from cg.store.models import Case, Flowcell, Sample, SampleLaneSequencingMetrics class DeleteDataHandler(BaseHandler): @@ -40,7 +40,7 @@ def delete_relationships_sample(self, sample: Sample) -> None: def delete_cases_without_samples(self, case_internal_ids: list[str]) -> None: """Delete any cases specified in case_ids without samples.""" for case_internal_id in case_internal_ids: - case: Family = self.get_case_by_internal_id(internal_id=case_internal_id) + case: Case = self.get_case_by_internal_id(internal_id=case_internal_id) if case and not case.links: self.session.delete(case) self.session.commit() diff --git a/cg/store/api/find_business_data.py b/cg/store/api/find_business_data.py index 7641e96e38..e311e53d9b 100644 --- a/cg/store/api/find_business_data.py +++ b/cg/store/api/find_business_data.py @@ -28,7 +28,7 @@ Application, ApplicationLimitations, Customer, - Family, + Case, FamilySample, Flowcell, Invoice, @@ -46,9 +46,9 @@ class FindBusinessDataHandler(BaseHandler): def __init__(self, session: Session): super().__init__(session=session) - def get_case_by_entry_id(self, entry_id: str) -> Family: + def get_case_by_entry_id(self, entry_id: str) -> Case: """Return a case by entry id.""" - cases_query: Query = self._get_query(table=Family) + cases_query: Query = self._get_query(table=Case) return apply_case_filter( cases=cases_query, filter_functions=[CaseFilter.FILTER_BY_ENTRY_ID], entry_id=entry_id ).first() @@ -59,7 +59,7 @@ def has_active_cases_for_sample(self, internal_id: str) -> bool: active_actions = ["analyze", "running"] for family_sample in sample.links: - case: Family = self.get_case_by_entry_id(entry_id=family_sample.family_id) + case: Case = self.get_case_by_entry_id(entry_id=family_sample.family_id) if case.action in active_actions: return True @@ -127,7 +127,7 @@ def get_analysis_by_case_entry_id_and_started_at( def get_cases_by_customer_and_case_name_search( self, customer: Customer, case_name_search: str - ) -> list[Family]: + ) -> list[Case]: """ Retrieve a list of cases filtered by a customer and matching names. @@ -136,7 +136,7 @@ def get_cases_by_customer_and_case_name_search( case_name_search (str): The case name search string to filter cases by. Returns: - list[Family]: A list of filtered cases sorted by creation time. + list[Case]: A list of filtered cases sorted by creation time. """ filter_functions: list[Callable] = [ CaseFilter.FILTER_BY_CUSTOMER_ENTRY_ID, @@ -145,7 +145,7 @@ def get_cases_by_customer_and_case_name_search( ] return apply_case_filter( - cases=self._get_query(table=Family), + cases=self._get_query(table=Case), filter_functions=filter_functions, customer_entry_id=customer.id, name_search=case_name_search, @@ -157,7 +157,7 @@ def get_cases_by_customers_action_and_case_search( action: Optional[str], case_search: Optional[str], limit: Optional[int] = 30, - ) -> list[Family]: + ) -> list[Case]: """ Retrieve a list of cases filtered by customers, action, and matching names or internal ids. @@ -168,7 +168,7 @@ def get_cases_by_customers_action_and_case_search( limit (Optional[int], default=30): The maximum number of cases to return. Returns: - list[Family]: A list of filtered cases sorted by creation time and limited by the specified number. + list[Case]: A list of filtered cases sorted by creation time and limited by the specified number. """ filter_functions: list[Callable] = [ CaseFilter.FILTER_BY_CUSTOMER_ENTRY_IDS, @@ -182,7 +182,7 @@ def get_cases_by_customers_action_and_case_search( ) filtered_cases: Query = apply_case_filter( - cases=self._get_query(table=Family), + cases=self._get_query(table=Case), filter_functions=filter_functions, customer_entry_ids=customer_entry_ids, action=action, @@ -196,7 +196,7 @@ def get_cases_by_customer_pipeline_and_case_search( pipeline: Optional[str], case_search: Optional[str], limit: Optional[int] = 30, - ) -> list[Family]: + ) -> list[Case]: """ Retrieve a list of cases filtered by customer, pipeline, and matching names or internal ids. @@ -207,7 +207,7 @@ def get_cases_by_customer_pipeline_and_case_search( limit (Optional[int], default=30): The maximum number of cases to return. Returns: - list[Family]: A list of filtered cases sorted by creation time and limited by the specified number. + list[Case]: A list of filtered cases sorted by creation time and limited by the specified number. """ filter_functions: list[Callable] = [ CaseFilter.FILTER_BY_CUSTOMER_ENTRY_ID, @@ -219,7 +219,7 @@ def get_cases_by_customer_pipeline_and_case_search( customer_entry_id: int = customer.id if customer else None filtered_cases: Query = apply_case_filter( - cases=self._get_query(table=Family), + cases=self._get_query(table=Case), filter_functions=filter_functions, customer_entry_id=customer_entry_id, case_search=case_search, @@ -227,9 +227,9 @@ def get_cases_by_customer_pipeline_and_case_search( ) return filtered_cases.limit(limit=limit).all() - def get_cases(self) -> list[Family]: + def get_cases(self) -> list[Case]: """Return all cases.""" - return self._get_query(table=Family).all() + return self._get_query(table=Case).all() def get_case_samples_by_case_id(self, case_internal_id: str) -> list[FamilySample]: """Return the case-sample links associated with a case.""" @@ -243,22 +243,22 @@ def filter_cases_with_samples(self, case_ids: list[str]) -> list[str]: """Return case id:s associated with samples.""" cases_with_samples = set() for case_id in case_ids: - case: Family = self.get_case_by_internal_id(internal_id=case_id) + case: Case = self.get_case_by_internal_id(internal_id=case_id) if case and case.links: cases_with_samples.add(case_id) return list(cases_with_samples) - def get_cases_by_ticket_id(self, ticket_id: str) -> list[Family]: + def get_cases_by_ticket_id(self, ticket_id: str) -> list[Case]: """Return cases associated with a given ticket id.""" return apply_case_filter( filter_functions=[CaseFilter.FILTER_BY_TICKET], ticket_id=ticket_id, - cases=self._get_query(table=Family), + cases=self._get_query(table=Case), ).all() def get_customer_id_from_ticket(self, ticket: str) -> str: """Returns the customer related to given ticket.""" - cases: list[Family] = self.get_cases_by_ticket_id(ticket_id=ticket) + cases: list[Case] = self.get_cases_by_ticket_id(ticket_id=ticket) if not cases: raise ValueError(f"No case found for ticket {ticket}") return cases[0].customer.internal_id @@ -283,7 +283,7 @@ def get_latest_flow_cell_on_case(self, family_id: str) -> Flowcell: flow_cells_on_case.sort(key=lambda flow_cell: flow_cell.sequenced_at) return flow_cells_on_case[-1] if flow_cells_on_case else None - def _is_case_found(self, case: Family, case_id: str) -> None: + def _is_case_found(self, case: Case, case_id: str) -> None: """Raise error if case is false.""" if not case: LOG.error(f"Could not find case {case_id}") @@ -292,30 +292,30 @@ def _is_case_found(self, case: Family, case_id: str) -> None: def get_samples_by_case_id(self, case_id: str) -> list[Sample]: """Get samples on a given case id.""" - case: Family = self.get_case_by_internal_id(internal_id=case_id) + case: Case = self.get_case_by_internal_id(internal_id=case_id) self._is_case_found(case=case, case_id=case_id) return case.samples if case else [] def get_sample_ids_by_case_id(self, case_id: str = None) -> Iterator[str]: """Return sample ids from case id.""" - case: Family = self.get_case_by_internal_id(internal_id=case_id) + case: Case = self.get_case_by_internal_id(internal_id=case_id) self._is_case_found(case=case, case_id=case_id) for link in case.links: yield link.sample.internal_id - def get_case_by_name_and_customer(self, customer: Customer, case_name: str) -> Family: + def get_case_by_name_and_customer(self, customer: Customer, case_name: str) -> Case: """Find a case by case name within a customer.""" return apply_case_filter( - cases=self._get_query(table=Family), + cases=self._get_query(table=Case), filter_functions=[CaseFilter.FILTER_BY_CUSTOMER_ENTRY_ID, CaseFilter.FILTER_BY_NAME], customer_entry_id=customer.id, name=case_name, ).first() - def get_case_by_name(self, name: str) -> Family: + def get_case_by_name(self, name: str) -> Case: """Get a case by name.""" return apply_case_filter( - cases=self._get_query(table=Family), + cases=self._get_query(table=Case), filter_functions=[CaseFilter.FILTER_BY_NAME], name=name, ).first() @@ -456,7 +456,7 @@ def get_flow_cell_by_name_pattern_and_status( filter_functions=filter_functions, ).all() - def get_flow_cells_by_case(self, case: Family) -> Optional[list[Flowcell]]: + def get_flow_cells_by_case(self, case: Case) -> Optional[list[Flowcell]]: """Return flow cells for case.""" return apply_flow_cell_filter( flow_cells=self._get_join_flow_cell_sample_links_query(), @@ -709,26 +709,26 @@ def get_samples_by_type(self, case_id: str, sample_type: SampleType) -> Optional def is_case_down_sampled(self, case_id: str) -> bool: """Returns True if all samples in a case are down sampled from another sample.""" - case: Family = self.get_case_by_internal_id(internal_id=case_id) + case: Case = self.get_case_by_internal_id(internal_id=case_id) return all(sample.from_sample is not None for sample in case.samples) def is_case_external(self, case_id: str) -> bool: """Returns True if all samples in a case have been sequenced externally.""" - case: Family = self.get_case_by_internal_id(internal_id=case_id) + case: Case = self.get_case_by_internal_id(internal_id=case_id) return all(sample.application_version.application.is_external for sample in case.samples) - def get_case_by_internal_id(self, internal_id: str) -> Family: + def get_case_by_internal_id(self, internal_id: str) -> Case: """Get case by internal id.""" return apply_case_filter( filter_functions=[CaseFilter.FILTER_BY_INTERNAL_ID], - cases=self._get_query(table=Family), + cases=self._get_query(table=Case), internal_id=internal_id, ).first() def verify_case_exists(self, case_internal_id: str) -> None: """Passes silently if case exists in Status DB, raises error if no case or case samples.""" - case: Family = self.get_case_by_internal_id(internal_id=case_internal_id) + case: Case = self.get_case_by_internal_id(internal_id=case_internal_id) if not case: LOG.error(f"Case {case_internal_id} could not be found in Status DB!") raise CgError @@ -737,18 +737,18 @@ 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: Pipeline) -> list[Family]: + def get_running_cases_in_pipeline(self, pipeline: Pipeline) -> 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=Family), + cases=self._get_query(table=Case), pipeline=pipeline, ).all() def get_not_analysed_cases_by_sample_internal_id( self, sample_internal_id: str, - ) -> list[Family]: + ) -> list[Case]: """Get not analysed cases by sample internal id.""" query: Query = self._get_join_case_and_sample_query() diff --git a/cg/store/api/status.py b/cg/store/api/status.py index 7d9c6376db..0ce0da02de 100644 --- a/cg/store/api/status.py +++ b/cg/store/api/status.py @@ -15,7 +15,7 @@ from cg.store.filters.status_flow_cell_filters import FlowCellFilter, apply_flow_cell_filter from cg.store.filters.status_pool_filters import PoolFilter, apply_pool_filter from cg.store.filters.status_sample_filters import SampleFilter, apply_sample_filter -from cg.store.models import Analysis, Customer, Family, Flowcell, Pool, Sample +from cg.store.models import Analysis, Customer, Case, Flowcell, Pool, Sample class StatusHandler(BaseHandler): @@ -89,7 +89,7 @@ def get_families_with_samples(self) -> Query: def cases_to_analyze( self, pipeline: Pipeline = None, threshold: bool = False, limit: int = None - ) -> list[Family]: + ) -> 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, @@ -102,7 +102,7 @@ def cases_to_analyze( pipeline=pipeline, ) - families: list[Query] = list(cases.order_by(Family.ordered_at)) + families: list[Query] = list(cases.order_by(Case.ordered_at)) families = [ case_obj for case_obj in families @@ -145,7 +145,7 @@ def cases( exclude_delivered: bool = False, exclude_delivery_reported: bool = False, exclude_invoiced: bool = False, - ) -> list[Family]: + ) -> list[Case]: """Fetch cases with and w/o analyses.""" case_q = self._get_filtered_case_query( case_action, @@ -195,7 +195,7 @@ def cases( def set_case_action(self, action: Literal[CASE_ACTIONS], case_internal_id: str) -> None: """Sets the action of provided cases to None or the given action.""" - case: Family = self.get_case_by_internal_id(internal_id=case_internal_id) + case: Case = self.get_case_by_internal_id(internal_id=case_internal_id) case.action = action self.session.commit() @@ -207,7 +207,7 @@ def add_sample_comment(self, sample: Sample, comment: str) -> None: sample.comment = comment self.session.commit() - def get_flow_cells_by_case(self, case: Family) -> list[Flowcell]: + def get_flow_cells_by_case(self, case: Case) -> list[Flowcell]: """Return flow cells for case.""" return apply_flow_cell_filter( flow_cells=self._get_join_flow_cell_sample_links_query(), @@ -215,7 +215,7 @@ def get_flow_cells_by_case(self, case: Family) -> list[Flowcell]: case=case, ).all() - def get_cases_to_compress(self, date_threshold: datetime) -> list[Family]: + def get_cases_to_compress(self, date_threshold: datetime) -> list[Case]: """Return all cases that are ready to be compressed by SPRING.""" case_filter_functions: list[CaseFilter] = [ CaseFilter.FILTER_HAS_INACTIVE_ANALYSIS, @@ -224,7 +224,7 @@ def get_cases_to_compress(self, date_threshold: datetime) -> list[Family]: ] return apply_case_filter( filter_functions=case_filter_functions, - cases=self._get_query(table=Family), + cases=self._get_query(table=Case), creation_date=date_threshold, ).all() @@ -354,7 +354,7 @@ def _should_be_skipped( skip_case = True return skip_case - def _calculate_case_data(self, case_obj: Family) -> SimpleNamespace: + def _calculate_case_data(self, case_obj: Case) -> SimpleNamespace: case_data = self._get_empty_case_data() case_data.data_analysis = case_obj.data_analysis @@ -519,7 +519,7 @@ def _calculate_case_data(self, case_obj: Family) -> SimpleNamespace: @staticmethod def _is_rerun( - case_obj: Family, + case_obj: Case, samples_received_at: datetime, samples_prepared_at: datetime, samples_sequenced_at: datetime, diff --git a/cg/store/filters/status_analysis_filters.py b/cg/store/filters/status_analysis_filters.py index 086da10fa7..fb00495c5b 100644 --- a/cg/store/filters/status_analysis_filters.py +++ b/cg/store/filters/status_analysis_filters.py @@ -6,7 +6,7 @@ from cg.constants import REPORT_SUPPORTED_PIPELINES from cg.constants.constants import VALID_DATA_IN_PRODUCTION, Pipeline -from cg.store.models import Analysis, Family +from cg.store.models import Analysis, Case def filter_valid_analyses_in_production(analyses: Query, **kwargs) -> Query: @@ -87,7 +87,7 @@ def filter_analyses_not_cleaned(analyses: Query, **kwargs) -> Query: def filter_analysis_case_action_is_none(analyses: Query, **kwargs) -> Query: """Return a query of analyses that do not have active cases.""" - return analyses.join(Family).filter(Family.action.is_(None)) + return analyses.join(Case).filter(Case.action.is_(None)) def apply_analysis_filter( diff --git a/cg/store/filters/status_case_filters.py b/cg/store/filters/status_case_filters.py index e17da0cd37..222e54d38a 100644 --- a/cg/store/filters/status_case_filters.py +++ b/cg/store/filters/status_case_filters.py @@ -12,12 +12,12 @@ LOQUSDB_MIP_SEQUENCING_METHODS, LOQUSDB_SUPPORTED_PIPELINES, ) -from cg.store.models import Analysis, Application, Customer, Family, Sample +from cg.store.models import Analysis, Application, Customer, Case, Sample def filter_cases_by_action(cases: Query, action: str, **kwargs) -> Query: """Filter cases with matching action.""" - return cases.filter(Family.action == action) if action else cases + return cases.filter(Case.action == action) if action else cases def filter_cases_by_case_search(cases: Query, case_search: str, **kwargs) -> Query: @@ -25,8 +25,8 @@ def filter_cases_by_case_search(cases: Query, case_search: str, **kwargs) -> Que return ( cases.filter( or_( - Family.internal_id.like(f"%{case_search}%"), - Family.name.like(f"%{case_search}%"), + Case.internal_id.like(f"%{case_search}%"), + Case.name.like(f"%{case_search}%"), ) ) if case_search @@ -36,54 +36,54 @@ def filter_cases_by_case_search(cases: Query, case_search: str, **kwargs) -> Que def filter_cases_by_customer_entry_id(cases: Query, customer_entry_id: int, **kwargs) -> Query: """Filter cases with matching customer id.""" - return cases.filter(Family.customer_id == customer_entry_id) + return cases.filter(Case.customer_id == customer_entry_id) def filter_cases_by_customer_entry_ids( cases: Query, customer_entry_ids: list[int], **kwargs ) -> Query: """Filter cases with matching customer ids.""" - return cases.filter(Family.customer_id.in_(customer_entry_ids)) if customer_entry_ids else cases + return cases.filter(Case.customer_id.in_(customer_entry_ids)) if customer_entry_ids else cases def filter_cases_by_entry_id(cases: Query, entry_id: int, **kwargs) -> Query: """Filter cases by entry id.""" - return cases.filter(Family.id == entry_id) + return cases.filter(Case.id == entry_id) def filter_case_by_internal_id(cases: Query, internal_id: str, **kwargs) -> Query: """Filter cases with matching internal id.""" - return cases.filter(Family.internal_id == internal_id) + return cases.filter(Case.internal_id == internal_id) def filter_cases_by_internal_id_search(cases: Query, internal_id_search: str, **kwargs) -> Query: """Filter cases with internal ids matching the search pattern.""" - return cases.filter(Family.internal_id.like(f"%{internal_id_search}%")) + return cases.filter(Case.internal_id.like(f"%{internal_id_search}%")) def filter_cases_by_name(cases: Query, name: str, **kwargs) -> Query: """Filter cases with matching name.""" - return cases.filter(Family.name == name) if name else cases + return cases.filter(Case.name == name) if name else cases def filter_cases_by_name_search(cases: Query, name_search: str, **kwargs) -> Query: """Filter cases with names matching the search pattern.""" - return cases.filter(Family.name.like(f"%{name_search}%")) + 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(Family.data_analysis.ilike(f"%{pipeline_search}%")) + return cases.filter(Case.data_analysis.ilike(f"%{pipeline_search}%")) def filter_cases_by_priority(cases: Query, priority: str, **kwargs) -> Query: """Filter cases with matching priority.""" - return cases.filter(Family.priority == priority) + return cases.filter(Case.priority == priority) def filter_cases_by_ticket_id(cases: Query, ticket_id: str, **kwargs) -> Query: """Filter cases with matching ticket id.""" - return cases.filter(Family.tickets.contains(ticket_id)) + return cases.filter(Case.tickets.contains(ticket_id)) def filter_cases_for_analysis(cases: Query, **kwargs) -> Query: @@ -94,14 +94,14 @@ def filter_cases_for_analysis(cases: Query, **kwargs) -> Query: """ return cases.filter( or_( - Family.action == CaseActions.ANALYZE, + Case.action == CaseActions.ANALYZE, and_( Application.is_external.isnot(True), - Family.action.is_(None), + Case.action.is_(None), Analysis.created_at.is_(None), ), and_( - Family.action.is_(None), + Case.action.is_(None), Analysis.created_at < Sample.last_sequenced_at, ), ) @@ -115,15 +115,15 @@ def filter_cases_has_sequence(cases: Query, **kwargs) -> Query: def filter_cases_not_analysed(cases: Query, **kwargs) -> Query: """Filter cases that have not been analysed and are not currently being analysed.""" - not_analyzed_condition = not_(Family.analyses.any(Analysis.completed_at.isnot(None))) - not_in_progress_condition = Family.action != CaseActions.ANALYZE + not_analyzed_condition = not_(Case.analyses.any(Analysis.completed_at.isnot(None))) + not_in_progress_condition = Case.action != CaseActions.ANALYZE return cases.filter(and_(not_analyzed_condition, not_in_progress_condition)) def filter_cases_with_pipeline(cases: Query, pipeline: Pipeline = None, **kwargs) -> Query: """Filter cases with pipeline.""" - return cases.filter(Family.data_analysis == pipeline) if pipeline else cases + return cases.filter(Case.data_analysis == pipeline) if pipeline else cases def filter_cases_with_loqusdb_supported_pipeline( @@ -131,9 +131,9 @@ def filter_cases_with_loqusdb_supported_pipeline( ) -> Query: """Filter Loqusdb related cases with pipeline.""" records: Query = ( - cases.filter(Family.data_analysis == pipeline) + cases.filter(Case.data_analysis == pipeline) if pipeline - else cases.filter(Family.data_analysis.in_(LOQUSDB_SUPPORTED_PIPELINES)) + else cases.filter(Case.data_analysis.in_(LOQUSDB_SUPPORTED_PIPELINES)) ) return records.filter(Customer.loqus_upload == True) @@ -155,49 +155,49 @@ def filter_cases_with_loqusdb_supported_sequencing_method( def filter_cases_with_scout_data_delivery(cases: Query, **kwargs) -> Query: """Filter cases containing Scout as a data delivery option.""" - return cases.filter(Family.data_delivery.contains(DataDelivery.SCOUT)) + return cases.filter(Case.data_delivery.contains(DataDelivery.SCOUT)) def filter_newer_cases_by_order_date(cases: Query, order_date: datetime, **kwargs) -> Query: """Filter cases newer than date.""" - cases: Query = cases.filter(Family.ordered_at > order_date) - return cases.order_by(Family.ordered_at.asc()) + cases: Query = cases.filter(Case.ordered_at > order_date) + return cases.order_by(Case.ordered_at.asc()) def filter_inactive_analysis_cases(cases: Query, **kwargs) -> Query: """Filter cases which are not set or on hold.""" return cases.filter( or_( - Family.action.is_(None), - Family.action == CaseActions.HOLD, + Case.action.is_(None), + Case.action == CaseActions.HOLD, ) ) def filter_older_cases_by_creation_date(cases: Query, creation_date: datetime, **kwargs) -> Query: """Filter older cases compared to date.""" - cases = cases.filter(Family.created_at < creation_date) - return cases.order_by(Family.created_at.asc()) + cases = cases.filter(Case.created_at < creation_date) + return cases.order_by(Case.created_at.asc()) def filter_report_supported_data_delivery_cases(cases: Query, **kwargs) -> Query: """Filter cases with a valid data delivery for delivery report generation.""" - return cases.filter(Family.data_delivery.in_(REPORT_SUPPORTED_DATA_DELIVERY)) + return cases.filter(Case.data_delivery.in_(REPORT_SUPPORTED_DATA_DELIVERY)) def filter_running_cases(cases: Query, **kwargs) -> Query: """Filter cases which are running.""" - return cases.filter(Family.action == CaseActions.RUNNING) + return cases.filter(Case.action == CaseActions.RUNNING) def filter_compressible_cases(cases: Query, **kwargs) -> Query: """Filter cases which are running.""" - return cases.filter(Family.is_compressible) + return cases.filter(Case.is_compressible) def order_cases_by_created_at(cases: Query, **kwargs) -> Query: """Order cases by created at.""" - return cases.order_by(Family.created_at.desc()) + return cases.order_by(Case.created_at.desc()) def apply_case_filter( diff --git a/cg/store/filters/status_case_sample_filters.py b/cg/store/filters/status_case_sample_filters.py index eb0764a177..6946e604bf 100644 --- a/cg/store/filters/status_case_sample_filters.py +++ b/cg/store/filters/status_case_sample_filters.py @@ -3,14 +3,14 @@ from sqlalchemy.orm import Query -from cg.store.models import Family, Sample +from cg.store.models import Case, Sample def get_samples_in_case_by_internal_id( case_samples: Query, case_internal_id: str, **kwargs ) -> Query: """Return samples associated with a case.""" - return case_samples.filter(Family.internal_id == case_internal_id) + return case_samples.filter(Case.internal_id == case_internal_id) def get_cases_with_sample_by_internal_id(case_samples: Query, sample_internal_id: str, **kwargs): diff --git a/cg/store/filters/status_flow_cell_filters.py b/cg/store/filters/status_flow_cell_filters.py index 70dc5087f4..7d741415a3 100644 --- a/cg/store/filters/status_flow_cell_filters.py +++ b/cg/store/filters/status_flow_cell_filters.py @@ -3,10 +3,10 @@ from sqlalchemy.orm import Query -from cg.store.models import Family, FamilySample, Flowcell +from cg.store.models import Case, FamilySample, Flowcell -def filter_flow_cells_by_case(case: Family, flow_cells: Query, **kwargs) -> Query: +def filter_flow_cells_by_case(case: Case, flow_cells: Query, **kwargs) -> Query: """Return flow cells by case id.""" return flow_cells.filter(FamilySample.family == case) @@ -31,7 +31,7 @@ def filter_flow_cells_with_statuses( def apply_flow_cell_filter( flow_cells: Query, filter_functions: list[Callable], - case: Optional[Family] = None, + case: Optional[Case] = None, flow_cell_name: Optional[str] = None, name_search: Optional[str] = None, flow_cell_statuses: Optional[list[str]] = None, diff --git a/cg/store/models.py b/cg/store/models.py index 9181440b41..ab8f797498 100644 --- a/cg/store/models.py +++ b/cg/store/models.py @@ -219,7 +219,7 @@ class Analysis(Model): family_id = Column(ForeignKey("family.id", ondelete="CASCADE"), nullable=False) uploaded_to_vogue_at = Column(types.DateTime, nullable=True) - family = orm.relationship("Family", back_populates="analyses") + family = orm.relationship("Case", back_populates="analyses") def __str__(self): return f"{self.family.internal_id} | {self.completed_at.date()}" @@ -376,7 +376,7 @@ def to_dict(self): return to_dict(model_instance=self) -class Family(Model, PriorityMixin): +class Case(Model, PriorityMixin): __tablename__ = "family" __table_args__ = (UniqueConstraint("customer_id", "name", name="_customer_name_uc"),) @@ -532,7 +532,7 @@ class FamilySample(Model): mother_id = Column(ForeignKey("sample.id")) father_id = Column(ForeignKey("sample.id")) - family = orm.relationship(Family, back_populates="links") + family = orm.relationship(Case, back_populates="links") sample = orm.relationship("Sample", foreign_keys=[sample_id], back_populates="links") mother = orm.relationship("Sample", foreign_keys=[mother_id], back_populates="mother_links") father = orm.relationship("Sample", foreign_keys=[father_id], back_populates="father_links") diff --git a/tests/cli/add/test_cli_add_family.py b/tests/cli/add/test_cli_add_family.py index 2fe91c7fe9..61a0594f55 100644 --- a/tests/cli/add/test_cli_add_family.py +++ b/tests/cli/add/test_cli_add_family.py @@ -6,7 +6,7 @@ from cg.constants import DataDelivery, Pipeline from cg.models.cg_config import CGConfig from cg.store import Store -from cg.store.models import Customer, Family, Panel +from cg.store.models import Customer, Case, Panel from tests.store_helpers import StoreHelpers CLI_OPTION_ANALYSIS = Pipeline.BALSAMIC_UMI @@ -47,7 +47,7 @@ def test_add_case_required( # THEN it should be added assert result.exit_code == 0 - case_query = disk_store._get_query(table=Family) + case_query = disk_store._get_query(table=Case) assert case_query.count() == 1 assert case_query.first().name == name assert case_query.first().panels == [panel_id] @@ -88,7 +88,7 @@ def test_add_case_bad_pipeline( # THEN it should not be added assert result.exit_code != 0 - assert disk_store._get_query(table=Family).count() == 0 + assert disk_store._get_query(table=Case).count() == 0 def test_add_case_bad_data_delivery( @@ -125,7 +125,7 @@ def test_add_case_bad_data_delivery( # THEN it should not be added assert result.exit_code != 0 - assert disk_store._get_query(table=Family).count() == 0 + assert disk_store._get_query(table=Case).count() == 0 def test_add_case_bad_customer(cli_runner: CliRunner, base_context: CGConfig, ticket_id: str): @@ -156,7 +156,7 @@ def test_add_case_bad_customer(cli_runner: CliRunner, base_context: CGConfig, ti # THEN it should complain about missing customer instead of adding a case assert result.exit_code == 1 - assert disk_store._get_query(table=Family).count() == 0 + assert disk_store._get_query(table=Case).count() == 0 def test_add_case_bad_panel( @@ -190,7 +190,7 @@ def test_add_case_bad_panel( # THEN it should complain about missing panel instead of adding a case assert result.exit_code == 1 - assert disk_store._get_query(table=Family).count() == 0 + assert disk_store._get_query(table=Case).count() == 0 def test_add_case_priority( @@ -229,7 +229,7 @@ def test_add_case_priority( # THEN it should be added assert result.exit_code == 0 - case_query = disk_store._get_query(table=Family) + case_query = disk_store._get_query(table=Case) assert case_query.count() == 1 assert case_query.first().priority_human == priority diff --git a/tests/cli/compress/test_cli_compress_fastq.py b/tests/cli/compress/test_cli_compress_fastq.py index e7fbd067fa..1d7ff57921 100644 --- a/tests/cli/compress/test_cli_compress_fastq.py +++ b/tests/cli/compress/test_cli_compress_fastq.py @@ -9,7 +9,7 @@ from cg.constants import Pipeline from cg.models.cg_config import CGConfig from cg.store import Store -from cg.store.models import Family +from cg.store.models import Case from tests.store_helpers import StoreHelpers MOCK_SET_MEM_ACCORDING_TO_READS_PATH: str = "cg.cli.compress.helpers.set_memory_according_to_reads" @@ -28,7 +28,7 @@ def test_get_cases_to_process( # GIVEN a context with a case that can be compressed - valid_compressable_case: Family = helpers.add_case( + valid_compressable_case: Case = helpers.add_case( store=status_db, name=case_id, internal_id=case_id, @@ -39,7 +39,7 @@ def test_get_cases_to_process( status_db.session.commit() # WHEN running the compress command - cases: list[Family] = get_cases_to_process(days_back=1, store=status_db) + cases: list[Case] = get_cases_to_process(days_back=1, store=status_db) # THEN assert cases are returned assert cases @@ -60,7 +60,7 @@ def test_get_cases_to_process_when_no_case( status_db: Store = populated_compress_context.status_db # WHEN running the compress command - cases: list[Family] = get_cases_to_process( + cases: list[Case] = get_cases_to_process( case_id=case_id_does_not_exist, days_back=1, store=status_db ) @@ -80,12 +80,12 @@ def test_incompressible_cases_are_not_processable( # GIVEN a store with a case that is marked as incompressible status_db: Store = populated_compress_context.status_db - incompressible_case: Family = helpers.add_case(store=status_db, internal_id="incompressible") + incompressible_case: Case = helpers.add_case(store=status_db, internal_id="incompressible") incompressible_case.created_at = dt.datetime.now() - dt.timedelta(days=1000) incompressible_case.is_compressible = False # WHEN retrieving the processable cases - processable_cases: list[Family] = get_cases_to_process(days_back=1, store=status_db) + processable_cases: list[Case] = get_cases_to_process(days_back=1, store=status_db) # THEN assert that the incompressible case is not processable assert incompressible_case not in processable_cases @@ -137,7 +137,7 @@ def test_compress_fastq_cli_case_id( # GIVEN a context with a case that can be compressed - valid_compressable_case: Family = helpers.add_case( + valid_compressable_case: Case = helpers.add_case( store=status_db, name=case_id, internal_id=case_id, @@ -178,7 +178,7 @@ def test_compress_fastq_cli_multiple_family( """Test to run the compress command with multiple families.""" caplog.set_level(logging.DEBUG) # GIVEN a database with multiple families - nr_cases = populated_multiple_compress_context.status_db._get_query(table=Family).count() + nr_cases = populated_multiple_compress_context.status_db._get_query(table=Case).count() assert nr_cases > 1 # GIVEN no adjusting according to readsa @@ -202,7 +202,7 @@ def test_compress_fastq_cli_multiple_set_limit( compress_context = populated_multiple_compress_context caplog.set_level(logging.DEBUG) # GIVEN a context with more families than the limit - nr_cases = compress_context.status_db._get_query(table=Family).count() + nr_cases = compress_context.status_db._get_query(table=Case).count() limit = 5 assert nr_cases > limit diff --git a/tests/cli/delete/test_cli_delete_case.py b/tests/cli/delete/test_cli_delete_case.py index 467c3887d7..fa9f271c5b 100644 --- a/tests/cli/delete/test_cli_delete_case.py +++ b/tests/cli/delete/test_cli_delete_case.py @@ -6,7 +6,7 @@ from cg.cli.delete.case import delete_case as delete_case_command from cg.models.cg_config import CGConfig from cg.store import Store -from cg.store.models import Family, FamilySample, Sample +from cg.store.models import Case, FamilySample, Sample from tests.store_helpers import StoreHelpers SUCCESS = 0 @@ -19,7 +19,7 @@ def test_delete_case_without_options( # GIVEN a database with a case base_store: Store = base_context.status_db helpers.add_case(base_store) - case_query = base_store._get_query(table=Family) + case_query = base_store._get_query(table=Case) assert case_query.count() == 1 # WHEN deleting a case @@ -55,7 +55,7 @@ def test_delete_case_without_links( result = cli_runner.invoke(delete_case_command, [case_id, "--yes"], obj=base_context) # THEN it should have been deleted assert result.exit_code == SUCCESS - assert base_store._get_query(table=Family).count() == 0 + assert base_store._get_query(table=Case).count() == 0 def test_delete_case_with_analysis( @@ -73,7 +73,7 @@ def test_delete_case_with_analysis( # THEN it should not have been deleted assert result.exit_code != SUCCESS - assert base_store._get_query(table=Family).count() == 1 + assert base_store._get_query(table=Case).count() == 1 def test_delete_case_with_dry_run( @@ -87,7 +87,7 @@ def test_delete_case_with_dry_run( sample = helpers.add_sample(base_store) helpers.add_relationship(store=base_store, case=case_obj, sample=sample) - case_query = base_store._get_query(table=Family) + case_query = base_store._get_query(table=Case) family_sample_query = base_store._get_query(table=FamilySample) sample_query = base_store._get_query(table=Sample) @@ -127,7 +127,7 @@ def test_delete_case_without_yes( # THEN it should not have been deleted assert result.exit_code != SUCCESS - case_query = base_store._get_query(table=Family) + case_query = base_store._get_query(table=Case) assert case_query.count() == 1 @@ -140,7 +140,7 @@ def test_delete_case_with_links(cli_runner: CliRunner, base_context: CGConfig, h sample = helpers.add_sample(base_store) helpers.add_relationship(store=base_store, case=case_obj, sample=sample) - case_query = base_store._get_query(table=Family) + case_query = base_store._get_query(table=Case) family_sample_query = base_store._get_query(table=FamilySample) sample_query = base_store._get_query(table=Sample) @@ -171,7 +171,7 @@ def test_delete_case_with_links_to_other_case( case_obj2 = helpers.add_case(base_store, "second_case_linked_to_sample") helpers.add_relationship(store=base_store, case=case_obj2, sample=sample) - case_query = base_store._get_query(table=Family) + case_query = base_store._get_query(table=Case) family_sample_query = base_store._get_query(table=FamilySample) sample_query = base_store._get_query(table=Sample) @@ -205,7 +205,7 @@ def test_delete_case_with_father_links( helpers.add_relationship( store=base_store, case=case_obj2, sample=sample_child, father=sample_father ) - case_query = base_store._get_query(table=Family) + case_query = base_store._get_query(table=Case) family_sample_query = base_store._get_query(table=FamilySample) sample_query = base_store._get_query(table=Sample) @@ -238,7 +238,7 @@ def test_delete_mother_case(cli_runner: CliRunner, base_context: CGConfig, helpe store=base_store, case=case_child, sample=sample_child, mother=sample_mother ) - case_query = base_store._get_query(table=Family) + case_query = base_store._get_query(table=Case) family_sample_query = base_store._get_query(table=FamilySample) sample_query = base_store._get_query(table=Sample) @@ -270,7 +270,7 @@ def test_delete_child_case(cli_runner: CliRunner, base_context: CGConfig, helper store=base_store, case=case_child, sample=sample_child, mother=sample_mother ) - case_query = base_store._get_query(table=Family) + case_query = base_store._get_query(table=Case) family_sample_query = base_store._get_query(table=FamilySample) sample_query = base_store._get_query(table=Sample) @@ -306,7 +306,7 @@ def test_delete_trio_case(cli_runner: CliRunner, base_context: CGConfig, helpers mother=sample_mother, father=sample_father, ) - case_query = base_store._get_query(table=Family) + case_query = base_store._get_query(table=Case) family_sample_query = base_store._get_query(table=FamilySample) sample_query = base_store._get_query(table=Sample) diff --git a/tests/cli/get/test_cli_get_case.py b/tests/cli/get/test_cli_get_case.py index 35f62a112a..a579295bbe 100644 --- a/tests/cli/get/test_cli_get_case.py +++ b/tests/cli/get/test_cli_get_case.py @@ -6,7 +6,7 @@ from cg.constants import EXIT_SUCCESS from cg.models.cg_config import CGConfig from cg.store import Store -from cg.store.models import Family +from cg.store.models import Case from tests.store_helpers import StoreHelpers @@ -26,7 +26,7 @@ def test_get_case_required( ): """Test to get a case using only the required argument.""" # GIVEN a database with a analysis - family: Family = helpers.add_case(disk_store) + family: Case = helpers.add_case(disk_store) # WHEN getting a analysis result = cli_runner.invoke(get, ["case", family.internal_id], obj=base_context) diff --git a/tests/cli/get/test_cli_get_sample.py b/tests/cli/get/test_cli_get_sample.py index 82a4641b8f..8cb90301a6 100644 --- a/tests/cli/get/test_cli_get_sample.py +++ b/tests/cli/get/test_cli_get_sample.py @@ -7,7 +7,7 @@ from cg.constants import EXIT_SUCCESS from cg.models.cg_config import CGConfig from cg.store import Store -from cg.store.models import Family, Flowcell, Sample +from cg.store.models import Case, Flowcell, Sample from tests.store_helpers import StoreHelpers @@ -145,7 +145,7 @@ def test_get_sample_no_cases_with_case( ): """Test that the --no-cases flag does not show case info""" # GIVEN a database with a sample with related samples - case: Family = helpers.add_case(disk_store) + case: Case = helpers.add_case(disk_store) sample: Sample = helpers.add_sample(disk_store) helpers.add_relationship(disk_store, sample=sample, case=case) @@ -178,7 +178,7 @@ def test_get_sample_cases_with_case( ): """Test that the --cases flag does show case info""" # GIVEN a database with a sample with related samples - case: Family = helpers.add_case(disk_store) + case: Case = helpers.add_case(disk_store) sample: Sample = helpers.add_sample(disk_store) helpers.add_relationship(disk_store, sample=sample, case=case) diff --git a/tests/cli/set/test_cli_set_case.py b/tests/cli/set/test_cli_set_case.py index aa134de8ae..0f499a70c5 100644 --- a/tests/cli/set/test_cli_set_case.py +++ b/tests/cli/set/test_cli_set_case.py @@ -5,7 +5,7 @@ from cg.constants import EXIT_SUCCESS, DataDelivery, Pipeline from cg.models.cg_config import CGConfig from cg.store import Store -from cg.store.models import Family +from cg.store.models import Case from tests.store_helpers import StoreHelpers @@ -18,7 +18,7 @@ def test_set_case_without_options( """Test to set a case using only the required arguments.""" # GIVEN a database with a case case_id: str = helpers.add_case(store=base_store).internal_id - assert base_store._get_query(table=Family).count() == 1 + assert base_store._get_query(table=Case).count() == 1 # WHEN setting a case result = cli_runner.invoke(set_case, [case_id], obj=base_context) @@ -53,7 +53,7 @@ def test_set_case_bad_panel( # THEN it should complain in missing panel instead of setting a value assert result.exit_code != EXIT_SUCCESS - assert panel_id not in base_store._get_query(table=Family).first().panels + assert panel_id not in base_store._get_query(table=Case).first().panels def test_set_case_panel( @@ -63,7 +63,7 @@ def test_set_case_panel( # GIVEN a database with a case and a panel not yet added to the case panel_id: str = helpers.ensure_panel(store=base_store, panel_abbreviation="a_panel").name case_id: str = helpers.add_case(store=base_store).internal_id - case_query = base_store._get_query(table=Family) + case_query = base_store._get_query(table=Case) assert panel_id not in case_query.first().panels @@ -82,7 +82,7 @@ def test_set_case_priority( # GIVEN a database with a case case_id: str = helpers.add_case(base_store).internal_id priority: str = "priority" - case_query = base_store._get_query(table=Family) + case_query = base_store._get_query(table=Case) assert case_query.first().priority_human != priority @@ -105,7 +105,7 @@ def test_set_case_customer( customer_id: str = helpers.ensure_customer( store=base_store, customer_id="a_customer" ).internal_id - case_to_alter: Family = helpers.add_case(store=base_store) + case_to_alter: Case = helpers.add_case(store=base_store) assert customer_id != case_to_alter.customer.internal_id # WHEN setting a customer of a case @@ -133,7 +133,7 @@ def test_set_case_bad_data_analysis( # THEN it should complain in invalid data_analysis instead of setting a value assert result.exit_code != EXIT_SUCCESS - assert str(data_analysis) != base_store._get_query(table=Family).first().data_analysis + assert str(data_analysis) != base_store._get_query(table=Case).first().data_analysis def test_set_case_data_analysis( @@ -173,7 +173,7 @@ def test_set_case_bad_data_delivery( # THEN it should complain in invalid data_delivery instead of setting a value assert result.exit_code != EXIT_SUCCESS - assert str(data_delivery) != base_store._get_query(table=Family).first().data_delivery + assert str(data_delivery) != base_store._get_query(table=Case).first().data_delivery def test_set_case_data_delivery( diff --git a/tests/cli/set/test_cli_set_cases.py b/tests/cli/set/test_cli_set_cases.py index 787013ce9d..ec5a171b09 100644 --- a/tests/cli/set/test_cli_set_cases.py +++ b/tests/cli/set/test_cli_set_cases.py @@ -8,7 +8,7 @@ from cg.cli.set.cases import set_cases from cg.models.cg_config import CGConfig from cg.store import Store -from cg.store.models import Family, Sample +from cg.store.models import Case, Sample from tests.store_helpers import StoreHelpers @@ -26,7 +26,7 @@ def test_set_cases_by_sample_identifiers( new_sample: Sample = helpers.add_sample(base_store) new_sample.original_ticket: str = ticket_id new_sample.order: str = "An order" - case: Family = helpers.add_case(base_store) + case: Case = helpers.add_case(base_store) helpers.add_relationship(base_store, sample=new_sample, case=case) identifier_value = getattr(new_sample, identifier_key) diff --git a/tests/cli/upload/test_cli_scout.py b/tests/cli/upload/test_cli_scout.py index a714965417..da97de9e02 100644 --- a/tests/cli/upload/test_cli_scout.py +++ b/tests/cli/upload/test_cli_scout.py @@ -10,7 +10,7 @@ from cg.meta.workflow.balsamic import BalsamicAnalysisAPI from cg.models.cg_config import CGConfig from cg.store import Store -from cg.store.models import Family +from cg.store.models import Case from tests.mocks.scout import MockScoutLoadConfig from tests.store_helpers import StoreHelpers @@ -20,7 +20,7 @@ def test_get_upload_api(cg_context: CGConfig, case_id: str, helpers: StoreHelper status_db: Store = cg_context.status_db # GIVEN a case with a balsamic analysis - case: Family = helpers.ensure_case( + case: Case = helpers.ensure_case( store=status_db, data_analysis=Pipeline.BALSAMIC, case_id=case_id ) helpers.add_analysis(store=status_db, pipeline=Pipeline.BALSAMIC, case=case) @@ -44,7 +44,7 @@ def test_create_scout_load_config( status_db: Store = cg_context.status_db # GIVEN a case with a balsamic analysis - case: Family = helpers.ensure_case( + case: Case = helpers.ensure_case( store=status_db, data_analysis=Pipeline.BALSAMIC, case_id=case_id ) helpers.add_analysis(store=status_db, pipeline=Pipeline.BALSAMIC, case=case) diff --git a/tests/cli/upload/test_cli_upload.py b/tests/cli/upload/test_cli_upload.py index 0bb15b46a3..bbdaaec7bc 100644 --- a/tests/cli/upload/test_cli_upload.py +++ b/tests/cli/upload/test_cli_upload.py @@ -6,7 +6,7 @@ from cg.cli.upload.base import upload from cg.models.cg_config import CGConfig from cg.store import Store -from cg.store.models import Family +from cg.store.models import Case from tests.store_helpers import StoreHelpers @@ -38,7 +38,7 @@ def test_upload_force_restart(cli_runner: CliRunner, base_context: CGConfig, hel # GIVEN an analysis that is already uploading disk_store: Store = base_context.status_db - case: Family = helpers.add_case(disk_store) + case: Case = helpers.add_case(disk_store) case_id: str = case.internal_id helpers.add_analysis(disk_store, case=case, uploading=True) diff --git a/tests/cli/upload/test_cli_upload_observations.py b/tests/cli/upload/test_cli_upload_observations.py index 3f8aabd487..6e85ccecb4 100644 --- a/tests/cli/upload/test_cli_upload_observations.py +++ b/tests/cli/upload/test_cli_upload_observations.py @@ -21,7 +21,7 @@ from cg.meta.observations.mip_dna_observations_api import MipDNAObservationsAPI from cg.models.cg_config import CGConfig from cg.store import Store -from cg.store.models import Family, FamilySample, Sample +from cg.store.models import Case, FamilySample, Sample from tests.store_helpers import StoreHelpers @@ -33,7 +33,7 @@ def test_observations( store: Store = base_context.status_db # GIVEN a case ready to be uploaded to Loqusdb - case: Family = helpers.add_case(store) + case: Case = helpers.add_case(store) case.customer.loqus_upload = True sample: Sample = helpers.add_sample(store, application_type=SequencingMethod.WES) link = store.relate_sample(family=case, sample=sample, status=PhenotypeStatus.UNKNOWN) @@ -54,7 +54,7 @@ def test_get_observations_case(base_context: CGConfig, helpers: StoreHelpers): store: Store = base_context.status_db # GIVEN an observations valid case - case: Family = helpers.add_case(store) + case: Case = helpers.add_case(store) # WHEN retrieving a case given a specific case ID extracted_case = get_observations_case(base_context, case.internal_id, upload=True) @@ -80,7 +80,7 @@ def test_get_observations_case_to_upload(base_context: CGConfig, helpers: StoreH store: Store = base_context.status_db # GIVEN a case ready to be uploaded to Loqusdb - case: Family = helpers.add_case(store) + case: Case = helpers.add_case(store) case.customer.loqus_upload = True # WHEN retrieving a case given a specific case ID @@ -95,7 +95,7 @@ def test_get_observations_api(base_context: CGConfig, helpers: StoreHelpers): store: Store = base_context.status_db # GIVEN a Loqusdb supported case - case: Family = helpers.add_case(store, data_analysis=Pipeline.MIP_DNA) + case: Case = helpers.add_case(store, data_analysis=Pipeline.MIP_DNA) sample: Sample = helpers.add_sample(store, application_type=SequencingMethod.WES) link = store.relate_sample(family=case, sample=sample, status=PhenotypeStatus.UNKNOWN) store.session.add(link) @@ -113,7 +113,7 @@ def test_get_sequencing_method(base_context: CGConfig, helpers: StoreHelpers): store: Store = base_context.status_db # GIVEN a case object with a WGS sequencing method - case: Family = helpers.add_case(store) + case: Case = helpers.add_case(store) sample: Sample = helpers.add_sample(store, application_type=SequencingMethod.WGS) link = store.relate_sample(family=case, sample=sample, status=PhenotypeStatus.UNKNOWN) store.session.add(link) @@ -136,7 +136,7 @@ def test_get_sequencing_method_exception( store: Store = base_context.status_db # GIVEN a case object with a WGS and WES mixed sequencing methods - case: Family = helpers.add_case(store) + case: Case = helpers.add_case(store) sample_wgs: Sample = helpers.add_sample( store, application_tag=wgs_application_tag, application_type=SequencingMethod.WGS ) diff --git a/tests/cli/workflow/conftest.py b/tests/cli/workflow/conftest.py index b673e83978..55cc8472b2 100644 --- a/tests/cli/workflow/conftest.py +++ b/tests/cli/workflow/conftest.py @@ -9,7 +9,7 @@ from cg.models.cg_config import CGConfig from cg.store import Store from cg.store.api.find_business_data import FindBusinessDataHandler -from cg.store.models import Family +from cg.store.models import Case from tests.store_helpers import StoreHelpers @@ -94,21 +94,21 @@ def fastq_case(case_id, family_name, sample_id, cust_sample_id, ticket_id: str) @pytest.fixture(scope="function") -def dna_case(analysis_store, helpers) -> Family: +def dna_case(analysis_store, helpers) -> Case: """Case with DNA application""" cust = helpers.ensure_customer(analysis_store) return analysis_store.get_case_by_name_and_customer(customer=cust, case_name="dna_case") @pytest.fixture(scope="function") -def rna_case(analysis_store, helpers) -> Family: +def rna_case(analysis_store, helpers) -> Case: """Case with RNA application""" cust = helpers.ensure_customer(analysis_store) return analysis_store.get_case_by_name_and_customer(customer=cust, case_name="rna_case") @pytest.fixture(scope="function") -def dna_rna_mix_case(analysis_store, helpers) -> Family: +def dna_rna_mix_case(analysis_store, helpers) -> Case: """Case with MIP analysis type DNA and RNA application""" cust = helpers.ensure_customer(analysis_store) return analysis_store.get_case_by_name_and_customer(customer=cust, case_name="dna_rna_mix_case") diff --git a/tests/cli/workflow/fastq/test_fastq_base.py b/tests/cli/workflow/fastq/test_fastq_base.py index c727879ef3..ddd9b570bd 100644 --- a/tests/cli/workflow/fastq/test_fastq_base.py +++ b/tests/cli/workflow/fastq/test_fastq_base.py @@ -6,7 +6,7 @@ store_fastq_analysis, ) from cg.constants.constants import CaseActions, Pipeline -from cg.store.models import Analysis, Family, Sample +from cg.store.models import Analysis, Case, Sample def test_store_fastq_analysis(caplog, another_case_id: str, cli_runner, fastq_context, helpers): @@ -14,7 +14,7 @@ def test_store_fastq_analysis(caplog, another_case_id: str, cli_runner, fastq_co # GIVEN a fastq context caplog.set_level(logging.INFO) helpers.ensure_case(fastq_context.status_db, case_id=another_case_id) - case_obj: Family = fastq_context.status_db.get_case_by_internal_id(internal_id=another_case_id) + case_obj: Case = fastq_context.status_db.get_case_by_internal_id(internal_id=another_case_id) assert not case_obj.analyses # WHEN the store_fastq_analysis command is invoked cli_runner.invoke(store_fastq_analysis, [another_case_id], obj=fastq_context) @@ -41,7 +41,7 @@ def test_store_available_fastq_analysis( sample_obj.last_sequenced_at = datetime.now() # GIVEN a case with no analysis but which is to be analyzed, a sample that has been sequenced and a fastq context - case_obj: Family = helpers.add_case_with_sample( + case_obj: Case = helpers.add_case_with_sample( fastq_context.status_db, case_id=another_case_id, sample_id="sample_for_another_case_id" ) assert not case_obj.analyses diff --git a/tests/cli/workflow/mip/conftest.py b/tests/cli/workflow/mip/conftest.py index ebcbf66684..81548dd647 100644 --- a/tests/cli/workflow/mip/conftest.py +++ b/tests/cli/workflow/mip/conftest.py @@ -13,7 +13,7 @@ from cg.models.cg_config import CGConfig from cg.store.api.find_business_data import FindBusinessDataHandler from cg.store.api.status import StatusHandler -from cg.store.models import Family +from cg.store.models import Case from tests.store.conftest import case_obj from tests.store_helpers import StoreHelpers @@ -157,7 +157,7 @@ def mip_dna_context( def setup_mocks( mocker, can_at_least_one_sample_be_decompressed: bool = False, - case_to_analyze: Family = None, + case_to_analyze: Case = None, decompress_spring: bool = False, has_latest_analysis_started: bool = False, is_spring_decompression_needed: bool = False, diff --git a/tests/cli/workflow/mip/test_cli_mip_base.py b/tests/cli/workflow/mip/test_cli_mip_base.py index 9a68f08983..52c3bf6290 100644 --- a/tests/cli/workflow/mip/test_cli_mip_base.py +++ b/tests/cli/workflow/mip/test_cli_mip_base.py @@ -10,14 +10,14 @@ from cg.constants.process import EXIT_SUCCESS from cg.meta.workflow.prepare_fastq import PrepareFastqAPI from cg.models.cg_config import CGConfig -from cg.store.models import Family +from cg.store.models import Case from tests.cli.workflow.mip.conftest import setup_mocks from tests.store.conftest import case_obj def test_spring_decompression_needed_and_started( caplog: LogCaptureFixture, - case: Family, + case: Case, cli_runner: CliRunner, mip_dna_context: CGConfig, mocker: MockFixture, @@ -53,7 +53,7 @@ def test_spring_decompression_needed_and_started( def test_spring_decompression_needed_and_start_failed( caplog: LogCaptureFixture, - case: Family, + case: Case, cli_runner: CliRunner, mip_dna_context: CGConfig, mocker: MockFixture, @@ -88,7 +88,7 @@ def test_spring_decompression_needed_and_start_failed( def test_spring_decompression_needed_and_cant_start( caplog: LogCaptureFixture, - case: Family, + case: Case, cli_runner: CliRunner, mip_dna_context: CGConfig, mocker: MockFixture, @@ -128,7 +128,7 @@ def test_decompression_cant_start_and_is_running( cli_runner: CliRunner, caplog: LogCaptureFixture, mip_dna_context: CGConfig, - case: Family, + case: Case, ): """Tests starting the MIP analysis when decompression is needed but can't start""" caplog.set_level(logging.INFO) @@ -165,7 +165,7 @@ def test_case_needs_to_be_stored( cli_runner: CliRunner, caplog: LogCaptureFixture, mip_dna_context: CGConfig, - case: Family, + case: Case, ): """Test starting MIP when files are decompressed but not stored in housekeeper""" caplog.set_level(logging.INFO) diff --git a/tests/conftest.py b/tests/conftest.py index 6c02b1d55b..83e0676260 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -49,7 +49,7 @@ from cg.models.taxprofiler.taxprofiler import TaxprofilerParameters from cg.store import Store from cg.store.database import create_all_tables, drop_all_tables, initialize_database -from cg.store.models import Bed, BedVersion, Customer, Family, Organism, Sample +from cg.store.models import Bed, BedVersion, Customer, Case, Organism, Sample from cg.utils import Process from tests.mocks.crunchy import MockCrunchyAPI from tests.mocks.hk_mock import MockHousekeeperAPI @@ -2828,7 +2828,7 @@ def rnafusion_context( helpers.add_case(status_db, internal_id=no_sample_case_id, name=no_sample_case_id) # Create textbook case with enough reads - case_enough_reads: Family = helpers.add_case( + case_enough_reads: Case = helpers.add_case( store=status_db, internal_id=rnafusion_case_id, name=rnafusion_case_id, @@ -2850,7 +2850,7 @@ def rnafusion_context( ) # Create case without enough reads - case_not_enough_reads: Family = helpers.add_case( + case_not_enough_reads: Case = helpers.add_case( store=status_db, internal_id=case_id_not_enough_reads, name=case_id_not_enough_reads, @@ -3079,7 +3079,7 @@ def taxprofiler_context( cg_context.meta_apis["analysis_api"] = TaxprofilerAnalysisAPI(config=cg_context) status_db: Store = cg_context.status_db - taxprofiler_case: Family = helpers.add_case( + taxprofiler_case: Case = helpers.add_case( store=status_db, internal_id=taxprofiler_case_id, name=taxprofiler_case_id, diff --git a/tests/meta/deliver/conftest.py b/tests/meta/deliver/conftest.py index 66f7db61ef..b9630f9ec7 100644 --- a/tests/meta/deliver/conftest.py +++ b/tests/meta/deliver/conftest.py @@ -8,7 +8,7 @@ from cg.constants.housekeeper_tags import AlignmentFileTag from cg.meta.deliver import DeliverAPI from cg.store import Store -from cg.store.models import Family +from cg.store.models import Case from tests.store_helpers import StoreHelpers @@ -90,5 +90,5 @@ def samples_missing_in_inbox( @pytest.fixture(name="deliver_api_destination_path") -def deliver_api_destination_path(customer_id: str, case: Family, ticket_id: str) -> Path: +def deliver_api_destination_path(customer_id: str, case: Case, ticket_id: str) -> Path: return Path(customer_id, INBOX_NAME, ticket_id, case.name) diff --git a/tests/meta/deliver/test_delivery_api.py b/tests/meta/deliver/test_delivery_api.py index 2e22162c70..3f720d4f8d 100644 --- a/tests/meta/deliver/test_delivery_api.py +++ b/tests/meta/deliver/test_delivery_api.py @@ -10,7 +10,7 @@ from cg.constants.housekeeper_tags import AlignmentFileTag from cg.meta.deliver import DeliverAPI from cg.store import Store -from cg.store.models import Family, FamilySample, Sample +from cg.store.models import Case, FamilySample, Sample from tests.cli.deliver.conftest import fastq_delivery_bundle, mip_delivery_bundle from tests.store.conftest import case_obj from tests.store_helpers import StoreHelpers @@ -203,7 +203,7 @@ def test_deliver_files_enough_reads( ): """Tests the deliver_files method for a sample with enough reads.""" # GIVEN a case to be delivered and a sample with enough reads - case: Family = deliver_api.store.get_case_by_internal_id(internal_id=case_id) + case: Case = deliver_api.store.get_case_by_internal_id(internal_id=case_id) sample: Sample = deliver_api.store.get_sample_by_internal_id(sample_id) helpers.ensure_hk_bundle(deliver_api.hk_api, fastq_delivery_bundle, include=True) helpers.ensure_hk_bundle(deliver_api.hk_api, mip_delivery_bundle, include=True) @@ -227,7 +227,7 @@ def test_deliver_files_not_enough_reads( ): """Tests the deliver_files method for a sample with too few reads.""" # GIVEN a case to be delivered and a sample with too few reads - case: Family = deliver_api.store.get_case_by_internal_id(internal_id=case_id) + case: Case = deliver_api.store.get_case_by_internal_id(internal_id=case_id) sample: Sample = deliver_api.store.get_sample_by_internal_id(sample_id) sample.reads = 1 helpers.ensure_hk_bundle(deliver_api.hk_api, fastq_delivery_bundle, include=True) @@ -254,7 +254,7 @@ def test_deliver_files_not_enough_reads_force( ): """Tests the deliver_files method for a sample with too few reads but with override.""" # GIVEN a case to be delivered and a sample with too few reads - case: Family = deliver_api.store.get_case_by_internal_id(internal_id=case_id) + case: Case = deliver_api.store.get_case_by_internal_id(internal_id=case_id) sample: Sample = deliver_api.store.get_sample_by_internal_id(sample_id) sample.reads = 1 helpers.ensure_hk_bundle(deliver_api.hk_api, fastq_delivery_bundle, include=True) diff --git a/tests/meta/demultiplex/conftest.py b/tests/meta/demultiplex/conftest.py index 1684547db3..f69724e4ad 100644 --- a/tests/meta/demultiplex/conftest.py +++ b/tests/meta/demultiplex/conftest.py @@ -14,7 +14,7 @@ from cg.models.cg_config import CGConfig from cg.models.flow_cell.flow_cell import FlowCellDirectoryData from cg.store.api import Store -from cg.store.models import Family, Sample +from cg.store.models import Case, Sample from tests.store_helpers import StoreHelpers FlowCellInfo = namedtuple("FlowCellInfo", "directory name sample_internal_ids") @@ -100,7 +100,7 @@ def populated_flow_cell_store( populated_flow_cell_store: Store = store sample: Sample = helpers.add_sample(store=populated_flow_cell_store, internal_id=sample_id) - family: Family = helpers.add_case(store=populated_flow_cell_store, internal_id=family_name) + family: Case = helpers.add_case(store=populated_flow_cell_store, internal_id=family_name) helpers.add_relationship( store=populated_flow_cell_store, sample=sample, @@ -126,7 +126,7 @@ def active_flow_cell_store( """Populate a store with a Novaseq flow cell, with active samples on it.""" active_flow_cell_store: Store = base_store sample: Sample = helpers.add_sample(store=active_flow_cell_store, internal_id=sample_id) - family: Family = helpers.add_case( + family: Case = helpers.add_case( store=active_flow_cell_store, internal_id=family_name, action="running" ) helpers.add_relationship( diff --git a/tests/meta/observations/test_meta_upload_observations.py b/tests/meta/observations/test_meta_upload_observations.py index 90503c8e21..7b303fac59 100644 --- a/tests/meta/observations/test_meta_upload_observations.py +++ b/tests/meta/observations/test_meta_upload_observations.py @@ -22,7 +22,7 @@ BalsamicObservationsInputFiles, MipDNAObservationsInputFiles, ) -from cg.store.models import Customer, Family +from cg.store.models import Customer, Case from tests.store_helpers import StoreHelpers @@ -38,7 +38,7 @@ def test_observations_upload( caplog.set_level(logging.DEBUG) # GIVEN a mocked observations API and a list of mocked observations files - case: Family = mip_dna_observations_api.store.get_case_by_internal_id(internal_id=case_id) + case: Case = mip_dna_observations_api.store.get_case_by_internal_id(internal_id=case_id) case.customer.internal_id = LoqusdbMipCustomers.KLINISK_IMMUNOLOGI.value mocker.patch.object( mip_dna_observations_api, @@ -83,7 +83,7 @@ def test_is_duplicate( """Test duplicate extraction for a case that is not in Loqusdb.""" # GIVEN a Loqusdb instance with no case duplicates - case: Family = mip_dna_observations_api.store.get_case_by_internal_id(internal_id=case_id) + case: Case = mip_dna_observations_api.store.get_case_by_internal_id(internal_id=case_id) mocker.patch.object(mip_dna_observations_api.loqusdb_api, "get_case", return_value=None) mocker.patch.object(mip_dna_observations_api.loqusdb_api, "get_duplicate", return_value=False) @@ -107,7 +107,7 @@ def test_is_duplicate_case_output( """Test duplicate extraction for a case that already exists in Loqusdb.""" # GIVEN a Loqusdb instance with a duplicated case - case: Family = mip_dna_observations_api.store.get_case_by_internal_id(internal_id=case_id) + case: Case = mip_dna_observations_api.store.get_case_by_internal_id(internal_id=case_id) # WHEN checking that a case has already been uploaded to Loqusdb is_duplicate: bool = mip_dna_observations_api.is_duplicate( @@ -131,7 +131,7 @@ def test_is_duplicate_loqusdb_id( """Test duplicate extraction for a case that already exists in Loqusdb.""" # GIVEN a Loqusdb instance with a duplicated case and whose samples already have a Loqusdb ID - case: Family = mip_dna_observations_api.store.get_case_by_internal_id(internal_id=case_id) + case: Case = mip_dna_observations_api.store.get_case_by_internal_id(internal_id=case_id) case.links[0].sample.loqusdb_id = loqusdb_id mocker.patch.object(mip_dna_observations_api.loqusdb_api, "get_case", return_value=None) mocker.patch.object(mip_dna_observations_api.loqusdb_api, "get_duplicate", return_value=False) @@ -212,7 +212,7 @@ def test_mip_dna_load_observations( caplog.set_level(logging.DEBUG) # GIVEN a mock MIP DNA observations API and a list of observations input files - case: Family = mip_dna_observations_api.store.get_case_by_internal_id(internal_id=case_id) + case: Case = mip_dna_observations_api.store.get_case_by_internal_id(internal_id=case_id) mocker.patch.object(mip_dna_observations_api, "is_duplicate", return_value=False) # WHEN loading the case to Loqusdb @@ -233,7 +233,7 @@ def test_mip_dna_load_observations_duplicate( caplog.set_level(logging.DEBUG) # GIVEN a mocked observations API and a case object that has already been uploaded to Loqusdb - case: Family = mip_dna_observations_api.store.get_case_by_internal_id(internal_id=case_id) + case: Case = mip_dna_observations_api.store.get_case_by_internal_id(internal_id=case_id) mocker.patch.object(mip_dna_observations_api, "is_duplicate", return_value=True) # WHEN uploading the case observations to Loqusdb @@ -255,7 +255,7 @@ def test_mip_dna_load_observations_tumor_case( caplog.set_level(logging.DEBUG) # GIVEN a MIP DNA observations API and a case object with a tumour sample - case: Family = mip_dna_observations_api.store.get_case_by_internal_id(internal_id=case_id) + case: Case = mip_dna_observations_api.store.get_case_by_internal_id(internal_id=case_id) mocker.patch.object(mip_dna_observations_api, "is_duplicate", return_value=False) case.links[0].sample.is_tumour = True @@ -276,7 +276,7 @@ def test_mip_dna_delete_case( caplog.set_level(logging.DEBUG) # GIVEN a Loqusdb instance filled with a case - case: Family = mip_dna_observations_api.store.get_case_by_internal_id(internal_id=case_id) + case: Case = mip_dna_observations_api.store.get_case_by_internal_id(internal_id=case_id) # WHEN deleting a case mip_dna_observations_api.delete_case(case) @@ -296,7 +296,7 @@ def test_mip_dna_delete_case_not_found( # GIVEN an observations instance and a case that has not been uploaded to Loqusdb loqusdb_api.process.stdout = None mip_dna_observations_api.loqusdb_api = loqusdb_api - case: Family = helpers.add_case(mip_dna_observations_api.store) + case: Case = helpers.add_case(mip_dna_observations_api.store) # WHEN deleting a rare disease case that does not exist in Loqusdb with pytest.raises(CaseNotFoundError): @@ -321,7 +321,7 @@ def test_balsamic_load_observations( caplog.set_level(logging.DEBUG) # GIVEN a mock BALSAMIC observations API and a list of observations input files - case: Family = balsamic_observations_api.store.get_case_by_internal_id(internal_id=case_id) + case: Case = balsamic_observations_api.store.get_case_by_internal_id(internal_id=case_id) mocker.patch.object(balsamic_observations_api, "is_duplicate", return_value=False) # WHEN loading the case to Loqusdb @@ -342,7 +342,7 @@ def test_balsamic_load_observations_duplicate( caplog.set_level(logging.DEBUG) # GIVEN a balsamic observations API and a case object that has already been uploaded to Loqusdb - case: Family = mip_dna_observations_api.store.get_case_by_internal_id(internal_id=case_id) + case: Case = mip_dna_observations_api.store.get_case_by_internal_id(internal_id=case_id) mocker.patch.object(mip_dna_observations_api, "is_duplicate", return_value=True) # WHEN uploading the case observations to Loqusdb @@ -364,7 +364,7 @@ def test_balsamic_load_cancer_observations( caplog.set_level(logging.DEBUG) # GIVEN a mock BALSAMIC observations API and a list of observations input files - case: Family = balsamic_observations_api.store.get_case_by_internal_id(internal_id=case_id) + case: Case = balsamic_observations_api.store.get_case_by_internal_id(internal_id=case_id) # WHEN loading the case to a somatic Loqusdb instance balsamic_observations_api.load_cancer_observations( @@ -385,7 +385,7 @@ def test_balsamic_delete_case( caplog.set_level(logging.DEBUG) # GIVEN a Loqusdb instance and a case that has been uploaded to both somatic and tumor instances - case: Family = balsamic_observations_api.store.get_case_by_internal_id(internal_id=case_id) + case: Case = balsamic_observations_api.store.get_case_by_internal_id(internal_id=case_id) # WHEN deleting the case balsamic_observations_api.delete_case(case) @@ -406,7 +406,7 @@ def test_balsamic_delete_case_not_found( loqusdb_api.process.stdout = None balsamic_observations_api.loqusdb_somatic_api = loqusdb_api balsamic_observations_api.loqusdb_tumor_api = loqusdb_api - case: Family = helpers.add_case(balsamic_observations_api.store) + case: Case = helpers.add_case(balsamic_observations_api.store) # WHEN deleting a cancer case that does not exist in Loqusdb with pytest.raises(CaseNotFoundError): diff --git a/tests/meta/orders/test_meta_orders_api.py b/tests/meta/orders/test_meta_orders_api.py index 6829f3ec22..606cb781c4 100644 --- a/tests/meta/orders/test_meta_orders_api.py +++ b/tests/meta/orders/test_meta_orders_api.py @@ -11,7 +11,7 @@ from cg.models.orders.order import OrderIn, OrderType from cg.models.orders.samples import MipDnaSample from cg.store import Store -from cg.store.models import Customer, Family, Pool, Sample +from cg.store.models import Customer, Case, Pool, Sample from tests.store_helpers import StoreHelpers SUBMITTERS = [ @@ -79,7 +79,7 @@ def test_submit( assert record.ticket == ticket_id elif isinstance(record, Sample): assert record.original_ticket == ticket_id - elif isinstance(record, Family): + elif isinstance(record, Case): for link_obj in record.links: assert link_obj.sample.original_ticket == ticket_id @@ -243,7 +243,7 @@ def test_submit_duplicate_sample_case_name( for sample in order_data.samples: case_id = sample.family_name if not store.get_case_by_name_and_customer(customer=customer, case_name=case_id): - case: Family = store.add_case( + case: Case = store.add_case( data_analysis=Pipeline.MIP_DNA, data_delivery=DataDelivery.SCOUT, name=case_id, diff --git a/tests/meta/orders/test_meta_orders_status.py b/tests/meta/orders/test_meta_orders_status.py index 4403c0800a..751e1b0b90 100644 --- a/tests/meta/orders/test_meta_orders_status.py +++ b/tests/meta/orders/test_meta_orders_status.py @@ -20,7 +20,7 @@ from cg.meta.orders.submitter import Submitter from cg.models.orders.order import OrderIn, OrderType from cg.store import Store -from cg.store.models import Application, Delivery, Family, Pool, Sample +from cg.store.models import Application, Delivery, Case, Pool, Sample def test_pools_to_status(rml_order_to_submit): @@ -197,7 +197,7 @@ def test_cases_to_status_synopsis(mip_order_to_submit): def test_store_rml(orders_api, base_store, rml_status_data, ticket_id: str): # GIVEN a basic store with no samples and a rml order assert base_store._get_query(table=Pool).count() == 0 - assert base_store._get_query(table=Family).count() == 0 + assert base_store._get_query(table=Case).count() == 0 assert not base_store._get_query(table=Sample).first() submitter: RmlSubmitter = RmlSubmitter(lims=orders_api.lims, status=orders_api.status) @@ -214,7 +214,7 @@ def test_store_rml(orders_api, base_store, rml_status_data, ticket_id: str): # THEN it should update the database with new pools assert len(new_pools) == 2 - assert base_store._get_query(table=Pool).count() == base_store._get_query(table=Family).count() + assert base_store._get_query(table=Pool).count() == base_store._get_query(table=Case).count() assert len(base_store._get_query(table=Sample).all()) == 4 # ASSERT that there is one negative sample @@ -248,7 +248,7 @@ def test_store_rml(orders_api, base_store, rml_status_data, ticket_id: str): def test_store_samples(orders_api, base_store, fastq_status_data, ticket_id: str): # GIVEN a basic store with no samples and a fastq order assert not base_store._get_query(table=Sample).first() - assert base_store._get_query(table=Family).count() == 0 + assert base_store._get_query(table=Case).count() == 0 submitter: FastqSubmitter = FastqSubmitter(lims=orders_api.lims, status=orders_api.status) @@ -264,7 +264,7 @@ def test_store_samples(orders_api, base_store, fastq_status_data, ticket_id: str # THEN it should store the samples and create a case for each sample assert len(new_samples) == 2 assert len(base_store._get_query(table=Sample).all()) == 2 - assert base_store._get_query(table=Family).count() == 2 + assert base_store._get_query(table=Case).count() == 2 first_sample = new_samples[0] assert len(first_sample.links) == 2 family_link = first_sample.links[0] @@ -278,7 +278,7 @@ def test_store_samples(orders_api, base_store, fastq_status_data, ticket_id: str def test_store_samples_sex_stored(orders_api, base_store, fastq_status_data, ticket_id: str): # GIVEN a basic store with no samples and a fastq order assert not base_store._get_query(table=Sample).first() - assert base_store._get_query(table=Family).count() == 0 + assert base_store._get_query(table=Case).count() == 0 submitter = FastqSubmitter(lims=orders_api.lims, status=orders_api.status) @@ -298,7 +298,7 @@ def test_store_samples_sex_stored(orders_api, base_store, fastq_status_data, tic def test_store_fastq_samples_non_tumour_wgs_to_mip(orders_api, base_store, fastq_status_data): # GIVEN a basic store with no samples and a non-tumour fastq order as wgs assert not base_store._get_query(table=Sample).first() - assert base_store._get_query(table=Family).count() == 0 + assert base_store._get_query(table=Case).count() == 0 base_store.get_application_by_tag( fastq_status_data["samples"][0]["application"] ).prep_category = PrepCategory.WHOLE_GENOME_SEQUENCING @@ -324,7 +324,7 @@ def test_store_fastq_samples_tumour_wgs_to_fastq( ): # GIVEN a basic store with no samples and a tumour fastq order as wgs assert not base_store._get_query(table=Sample).first() - assert base_store._get_query(table=Family).count() == 0 + assert base_store._get_query(table=Case).count() == 0 base_store.get_application_by_tag( fastq_status_data["samples"][0]["application"] ).prep_category = PrepCategory.WHOLE_GENOME_SEQUENCING @@ -350,7 +350,7 @@ def test_store_fastq_samples_non_wgs_as_fastq( ): # GIVEN a basic store with no samples and a fastq order as non wgs assert not base_store._get_query(table=Sample).first() - assert base_store._get_query(table=Family).count() == 0 + assert base_store._get_query(table=Case).count() == 0 non_wgs_prep_category = PrepCategory.WHOLE_EXOME_SEQUENCING non_wgs_applications = base_store._get_query(table=Application).filter( @@ -380,7 +380,7 @@ def test_store_fastq_samples_non_wgs_as_fastq( def test_store_samples_bad_apptag(orders_api, base_store, fastq_status_data, ticket_id: str): # GIVEN a basic store with no samples and a fastq order assert not base_store._get_query(table=Sample).first() - assert base_store._get_query(table=Family).count() == 0 + assert base_store._get_query(table=Case).count() == 0 for sample in fastq_status_data["samples"]: sample["application"] = "nonexistingtag" @@ -402,7 +402,7 @@ def test_store_samples_bad_apptag(orders_api, base_store, fastq_status_data, tic def test_store_microbial_samples(orders_api, base_store, microbial_status_data, ticket_id: str): # GIVEN a basic store with no samples and a microbial order and one Organism assert not base_store._get_query(table=Sample).first() - assert base_store._get_query(table=Family).count() == 0 + assert base_store._get_query(table=Case).count() == 0 assert base_store.get_all_organisms().count() == 1 submitter = MicrobialSubmitter(lims=orders_api.lims, status=orders_api.status) @@ -422,7 +422,7 @@ def test_store_microbial_samples(orders_api, base_store, microbial_status_data, # THEN it should store the samples under a case (case) and the used previously unknown # organisms assert new_samples - assert base_store._get_query(table=Family).count() == 1 + assert base_store._get_query(table=Case).count() == 1 assert len(new_samples) == 5 assert len(base_store._get_query(table=Sample).all()) == 5 assert base_store.get_all_organisms().count() == 3 @@ -433,7 +433,7 @@ def test_store_microbial_case_data_analysis_stored( ): # GIVEN a basic store with no samples and a microbial order and one Organism assert not base_store._get_query(table=Sample).first() - assert base_store._get_query(table=Family).count() == 0 + assert base_store._get_query(table=Case).count() == 0 submitter = MicrobialSubmitter(lims=orders_api.lims, status=orders_api.status) @@ -451,7 +451,7 @@ def test_store_microbial_case_data_analysis_stored( # THEN store the samples under a case with the microbial data_analysis type on case level assert len(base_store._get_query(table=Sample).all()) > 0 - assert base_store._get_query(table=Family).count() == 1 + assert base_store._get_query(table=Case).count() == 1 microbial_case = base_store.get_cases()[0] assert microbial_case.data_analysis == str(Pipeline.MICROSALT) @@ -738,7 +738,7 @@ def test_store_existing_case( ) base_store.session.close() - new_cases: list[Family] = base_store.get_cases() + new_cases: list[Case] = base_store.get_cases() # Save internal id stored_cases_internal_ids = dict([(case.name, case.internal_id) for case in new_cases]) @@ -754,7 +754,7 @@ def test_store_existing_case( ) base_store.session.close() - rerun_cases: list[Family] = base_store.get_cases() + rerun_cases: list[Case] = base_store.get_cases() # THEN the sample ticket should be appended to previos ticket and action set to analyze assert rerun_cases[0].tickets == f"{ticket_id},{ticket_id}" diff --git a/tests/meta/report/conftest.py b/tests/meta/report/conftest.py index 5434805a56..66cac3ca3e 100644 --- a/tests/meta/report/conftest.py +++ b/tests/meta/report/conftest.py @@ -11,7 +11,7 @@ from cg.meta.report.rnafusion import RnafusionReportAPI from cg.models.cg_config import CGConfig from cg.store import Store -from cg.store.models import Family +from cg.store.models import Case from tests.apps.scout.conftest import MockScoutApi from tests.mocks.balsamic_analysis_mock import MockBalsamicAnalysis from tests.mocks.limsmock import MockLimsAPI @@ -57,13 +57,13 @@ def report_api_rnafusion( @pytest.fixture(scope="function") -def case_mip_dna(case_id: str, report_api_mip_dna: MipDNAReportAPI) -> Family: +def case_mip_dna(case_id: str, report_api_mip_dna: MipDNAReportAPI) -> Case: """MIP DNA case instance.""" return report_api_mip_dna.status_db.get_case_by_internal_id(internal_id=case_id) @pytest.fixture(scope="function") -def case_balsamic(case_id: str, report_api_balsamic: BalsamicReportAPI) -> Family: +def case_balsamic(case_id: str, report_api_balsamic: BalsamicReportAPI) -> Case: """BALSAMIC case instance.""" return report_api_balsamic.status_db.get_case_by_internal_id(internal_id=case_id) diff --git a/tests/meta/report/test_balsamic_api.py b/tests/meta/report/test_balsamic_api.py index f783ff5df9..e2568eca50 100644 --- a/tests/meta/report/test_balsamic_api.py +++ b/tests/meta/report/test_balsamic_api.py @@ -4,13 +4,13 @@ from cg.models.balsamic.analysis import BalsamicAnalysis from cg.models.report.metadata import BalsamicTargetedSampleMetadataModel from cg.store import Store -from cg.store.models import BedVersion, Family, Sample +from cg.store.models import BedVersion, Case, Sample from tests.store_helpers import StoreHelpers def test_get_sample_metadata( report_api_balsamic: BalsamicReportAPI, - case_balsamic: Family, + case_balsamic: Case, helpers: StoreHelpers, sample_store: Store, ): diff --git a/tests/meta/report/test_report_api.py b/tests/meta/report/test_report_api.py index 19a4ce065d..caf835540b 100644 --- a/tests/meta/report/test_report_api.py +++ b/tests/meta/report/test_report_api.py @@ -14,12 +14,12 @@ from cg.models.report.report import CaseModel, CustomerModel, DataAnalysisModel, ReportModel from cg.models.report.sample import ApplicationModel, MethodsModel, SampleModel, TimestampModel from cg.store import Store -from cg.store.models import Analysis, Family, FamilySample +from cg.store.models import Analysis, Case, FamilySample from tests.meta.report.helper import recursive_assert from tests.store_helpers import StoreHelpers -def test_create_delivery_report(report_api_mip_dna: MipDNAReportAPI, case_mip_dna: Family): +def test_create_delivery_report(report_api_mip_dna: MipDNAReportAPI, case_mip_dna: Case): """Tests the creation of the rendered delivery report.""" # GIVEN a pre-built case @@ -36,7 +36,7 @@ def test_create_delivery_report(report_api_mip_dna: MipDNAReportAPI, case_mip_dn def test_create_delivery_report_file( - report_api_mip_dna: MipDNAReportAPI, case_mip_dna: Family, tmp_path: Path + report_api_mip_dna: MipDNAReportAPI, case_mip_dna: Case, tmp_path: Path ): """Tests file generation containing the delivery report data.""" @@ -55,7 +55,7 @@ def test_create_delivery_report_file( assert created_report_file.exists() -def test_render_delivery_report(report_api_mip_dna: MipDNAReportAPI, case_mip_dna: Family): +def test_render_delivery_report(report_api_mip_dna: MipDNAReportAPI, case_mip_dna: Case): """Tests delivery report rendering.""" # GIVEN a generated report @@ -71,7 +71,7 @@ def test_render_delivery_report(report_api_mip_dna: MipDNAReportAPI, case_mip_dn assert "html" in rendered_report -def test_get_validated_report_data(report_api_mip_dna: MipDNAReportAPI, case_mip_dna: Family): +def test_get_validated_report_data(report_api_mip_dna: MipDNAReportAPI, case_mip_dna: Case): """Tests report data retrieval.""" # GIVEN a valid case @@ -92,7 +92,7 @@ def test_get_validated_report_data(report_api_mip_dna: MipDNAReportAPI, case_mip def test_validate_report_empty_fields( - report_api_mip_dna: MipDNAReportAPI, case_mip_dna: Family, caplog: LogCaptureFixture + report_api_mip_dna: MipDNAReportAPI, case_mip_dna: Case, caplog: LogCaptureFixture ): """Tests the validations of allowed empty report fields.""" caplog.set_level(logging.INFO) @@ -118,7 +118,7 @@ def test_validate_report_empty_fields( def test_validate_report_missing_fields( - report_api_mip_dna: MipDNAReportAPI, case_mip_dna: Family, caplog: LogCaptureFixture + report_api_mip_dna: MipDNAReportAPI, case_mip_dna: Case, caplog: LogCaptureFixture ): """Tests the validations of empty required report fields.""" @@ -144,7 +144,7 @@ def test_validate_report_missing_fields( def test_get_validated_report_data_external_sample( - report_api_mip_dna: MipDNAReportAPI, case_mip_dna: Family + report_api_mip_dna: MipDNAReportAPI, case_mip_dna: Case ): """Tests report data retrieval.""" @@ -164,7 +164,7 @@ def test_get_validated_report_data_external_sample( assert report_data -def test_get_customer_data(report_api_mip_dna: MipDNAReportAPI, case_mip_dna: Family): +def test_get_customer_data(report_api_mip_dna: MipDNAReportAPI, case_mip_dna: Case): """Checks that the retrieved customer data is the expected one.""" # GIVEN a pre-built case @@ -210,7 +210,7 @@ def test_get_report_version_version( def test_get_case_data( report_api_mip_dna: MipDNAReportAPI, mip_analysis_api: MipDNAAnalysisAPI, - case_mip_dna: Family, + case_mip_dna: Case, family_name: str, ): """Tests the extracted case data.""" @@ -235,7 +235,7 @@ def test_get_case_data( def test_get_samples_data( report_api_mip_dna: MipDNAReportAPI, mip_analysis_api: MipDNAAnalysisAPI, - case_mip_dna: Family, + case_mip_dna: Case, case_samples_data: list[FamilySample], lims_samples: list[dict], ): @@ -313,7 +313,7 @@ def test_get_sample_application_data( def test_get_unique_applications( - report_api_mip_dna: MipDNAReportAPI, mip_analysis_api: MipDNAAnalysisAPI, case_mip_dna: Family + report_api_mip_dna: MipDNAReportAPI, mip_analysis_api: MipDNAAnalysisAPI, case_mip_dna: Case ): """Tests unique applications filtering.""" @@ -352,7 +352,7 @@ def test_get_sample_methods_data( def test_get_case_analysis_data( - report_api_mip_dna: MipDNAReportAPI, mip_analysis_api: MipDNAAnalysisAPI, case_mip_dna: Family + report_api_mip_dna: MipDNAReportAPI, mip_analysis_api: MipDNAAnalysisAPI, case_mip_dna: Case ): """Tests data analysis parameters retrieval.""" @@ -375,7 +375,7 @@ def test_get_case_analysis_data( def test_get_case_analysis_data_pipeline_match_error( report_api_mip_dna: MipDNAReportAPI, mip_analysis_api: MipDNAAnalysisAPI, - case_mip_dna: Family, + case_mip_dna: Case, caplog: LogCaptureFixture, ): """Test validation error if a customer requested pipeline does not match the data analysis.""" @@ -403,7 +403,7 @@ def test_get_case_analysis_data_pipeline_match_error( def test_get_case_analysis_data_pipeline_not_supported( report_api_mip_dna: MipDNAReportAPI, mip_analysis_api: MipDNAAnalysisAPI, - case_mip_dna: Family, + case_mip_dna: Case, caplog: LogCaptureFixture, ): """Test validation error if the analysis pipeline is not supported by the delivery report workflow.""" diff --git a/tests/meta/report/test_rnafusion_api.py b/tests/meta/report/test_rnafusion_api.py index 6c01436374..fa046ce844 100644 --- a/tests/meta/report/test_rnafusion_api.py +++ b/tests/meta/report/test_rnafusion_api.py @@ -4,7 +4,7 @@ from cg.meta.report.rnafusion import RnafusionReportAPI from cg.models.report.metadata import RnafusionSampleMetadataModel from cg.models.rnafusion.rnafusion import RnafusionAnalysis -from cg.store.models import Family, Sample +from cg.store.models import Case, Sample def test_get_sample_metadata( @@ -17,7 +17,7 @@ def test_get_sample_metadata( """Test Rnafusion sample metadata extraction.""" # GIVEN a Rnafusion case and associated sample - case: Family = report_api_rnafusion.status_db.get_case_by_internal_id( + case: Case = report_api_rnafusion.status_db.get_case_by_internal_id( internal_id=rnafusion_case_id ) sample: Sample = report_api_rnafusion.status_db.get_sample_by_internal_id(internal_id=sample_id) diff --git a/tests/meta/rsync/conftest.py b/tests/meta/rsync/conftest.py index bc08100b49..61b9a0d1f9 100644 --- a/tests/meta/rsync/conftest.py +++ b/tests/meta/rsync/conftest.py @@ -4,11 +4,11 @@ from cg.constants.constants import Pipeline from cg.models.cg_config import CGConfig -from cg.store.models import Family +from cg.store.models import Case @pytest.fixture -def mutant_case(cg_context: CGConfig, case_id: str, ticket_id: str, helpers) -> Family: +def mutant_case(cg_context: CGConfig, case_id: str, ticket_id: str, helpers) -> Case: """Return mutant case""" case = helpers.add_case( store=cg_context.status_db, @@ -20,7 +20,7 @@ def mutant_case(cg_context: CGConfig, case_id: str, ticket_id: str, helpers) -> @pytest.fixture -def microsalt_case(cg_context: CGConfig, case_id: str, ticket_id: str, helpers) -> Family: +def microsalt_case(cg_context: CGConfig, case_id: str, ticket_id: str, helpers) -> Case: """Return mutant case""" case = helpers.add_case( store=cg_context.status_db, diff --git a/tests/meta/rsync/test_rsync.py b/tests/meta/rsync/test_rsync.py index 621defb887..fadbca2565 100644 --- a/tests/meta/rsync/test_rsync.py +++ b/tests/meta/rsync/test_rsync.py @@ -9,13 +9,13 @@ from cg.exc import CgError from cg.meta.rsync import RsyncAPI from cg.store import Store -from cg.store.models import Family +from cg.store.models import Case from tests.meta.deliver.conftest import all_samples_in_inbox, dummy_file_name from tests.store.conftest import case_obj def test_get_source_and_destination_paths( - mutant_case: Family, rsync_api: RsyncAPI, ticket_id: str, mocker + mutant_case: Case, rsync_api: RsyncAPI, ticket_id: str, mocker ): """Test generating the source path before rsync.""" @@ -76,13 +76,13 @@ def test_make_log_dir(rsync_api: RsyncAPI, ticket_id: str, caplog): def test_run_rsync_on_slurm( - microsalt_case: Family, rsync_api: RsyncAPI, ticket_id: str, caplog, mocker, helpers + microsalt_case: Case, rsync_api: RsyncAPI, ticket_id: str, caplog, mocker, helpers ): """Test for running rsync using SLURM.""" caplog.set_level(logging.INFO) # GIVEN a valid microsalt case - case: Family = microsalt_case + case: Case = microsalt_case # GIVEN paths needed to run rsync mocker.patch.object(RsyncAPI, "get_source_and_destination_paths") @@ -182,7 +182,7 @@ def test_concatenate_rsync_commands( def test_slurm_rsync_single_case( all_samples_in_inbox: Path, - case: Family, + case: Case, destination_path: Path, rsync_api: RsyncAPI, caplog, @@ -219,7 +219,7 @@ def test_slurm_rsync_single_case( def test_slurm_rsync_single_case_missing_file( all_samples_in_inbox: Path, - case: Family, + case: Case, destination_path: Path, rsync_api: RsyncAPI, caplog, diff --git a/tests/meta/upload/balsamic/test_balsamic.py b/tests/meta/upload/balsamic/test_balsamic.py index 3cfc2b61d2..dd7865cc65 100644 --- a/tests/meta/upload/balsamic/test_balsamic.py +++ b/tests/meta/upload/balsamic/test_balsamic.py @@ -2,7 +2,7 @@ from cg.meta.upload.gt import UploadGenotypesAPI from cg.models.cg_config import CGConfig -from cg.store.models import Family +from cg.store.models import Case from tests.cli.workflow.balsamic.conftest import ( balsamic_context, balsamic_housekeeper, @@ -24,7 +24,7 @@ def test_genotype_check_wgs_normal(balsamic_context: CGConfig): """Test a cancer case with WGS and normal sample that is Genotype compatible.""" # GIVEN a balsamic case with WGS tag and a normal sample internal_id = "balsamic_case_wgs_paired_enough_reads" - case: Family = balsamic_context.status_db.get_case_by_internal_id(internal_id=internal_id) + case: Case = balsamic_context.status_db.get_case_by_internal_id(internal_id=internal_id) # WHEN checking if the case is Genotype upload compatible passed_check = UploadGenotypesAPI.is_suitable_for_genotype_upload(case) @@ -37,7 +37,7 @@ def test_genotype_check_non_wgs_normal(balsamic_context: CGConfig): """Test a cancer case with no WGS sample that is not Genotype compatible.""" # GIVEN a balsamic case with a normal sample, but no WGS tag internal_id = "balsamic_case_tgs_paired" - case: Family = balsamic_context.status_db.get_case_by_internal_id(internal_id=internal_id) + case: Case = balsamic_context.status_db.get_case_by_internal_id(internal_id=internal_id) # WHEN checking if the case is Genotype upload compatible passed_check = UploadGenotypesAPI.is_suitable_for_genotype_upload(case) @@ -50,7 +50,7 @@ def test_genotype_check_only_tumour(balsamic_context: CGConfig): """Test a cancer case with only a tumour sample that is not Genotype compatible.""" # GIVEN a balsamic case with only tumour sample internal_id = "balsamic_case_wgs_single" - case: Family = balsamic_context.status_db.get_case_by_internal_id(internal_id=internal_id) + case: Case = balsamic_context.status_db.get_case_by_internal_id(internal_id=internal_id) # WHEN checking if the case is Genotype upload compatible passed_check = UploadGenotypesAPI.is_suitable_for_genotype_upload(case) diff --git a/tests/meta/upload/conftest.py b/tests/meta/upload/conftest.py index e888ba48d5..bad9e5ef25 100644 --- a/tests/meta/upload/conftest.py +++ b/tests/meta/upload/conftest.py @@ -13,7 +13,7 @@ from cg.meta.upload.gt import UploadGenotypesAPI from cg.models.cg_config import CGConfig from cg.store import Store -from cg.store.models import Analysis, Family, Sample +from cg.store.models import Analysis, Case, Sample from tests.cli.workflow.mip.conftest import ( mip_case_id, mip_case_ids, @@ -89,12 +89,12 @@ def genotype_analysis_sex() -> dict: @pytest.fixture(name="mip_dna_case") -def mip_dna_case(mip_dna_context: CGConfig, helpers: StoreHelpers) -> Family: +def mip_dna_case(mip_dna_context: CGConfig, helpers: StoreHelpers) -> Case: """Return a MIP DNA case.""" store: Store = mip_dna_context.status_db - mip_dna_case: Family = helpers.add_case( + mip_dna_case: Case = helpers.add_case( store=store, internal_id="mip-dna-case", name="mip-dna-case", @@ -123,9 +123,7 @@ def mip_rna_case(mip_rna_context: CGConfig, case_id: str): @pytest.fixture(name="mip_rna_analysis") -def mip_rna_analysis( - mip_rna_context: CGConfig, helpers: StoreHelpers, mip_rna_case: Family -) -> Family: +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, diff --git a/tests/meta/upload/scout/conftest.py b/tests/meta/upload/scout/conftest.py index 92b66d831f..e06477b6b4 100644 --- a/tests/meta/upload/scout/conftest.py +++ b/tests/meta/upload/scout/conftest.py @@ -18,7 +18,7 @@ from cg.models.cg_config import CGConfig from cg.models.scout.scout_load_config import MipLoadConfig from cg.store import Store -from cg.store.models import Analysis, Family, Sample +from cg.store.models import Analysis, Case, Sample # Mocks from tests.mocks.hk_mock import MockHousekeeperAPI @@ -504,7 +504,7 @@ def mip_dna_analysis( ) -> Analysis: """Return a MIP DNA analysis object.""" helpers.add_synopsis_to_case(store=analysis_store_trio, case_id=case_id) - case: Family = analysis_store_trio.get_case_by_internal_id(internal_id=case_id) + case: Case = analysis_store_trio.get_case_by_internal_id(internal_id=case_id) analysis: Analysis = helpers.add_analysis( store=analysis_store_trio, case=case, 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 713d8e8b5a..d144cb4d06 100644 --- a/tests/meta/upload/scout/test_meta_upload_scoutapi_rna.py +++ b/tests/meta/upload/scout/test_meta_upload_scoutapi_rna.py @@ -13,7 +13,7 @@ from cg.constants.sequencing import SequencingMethod from cg.exc import CgDataError from cg.meta.upload.scout.uploadscoutapi import RNADNACollection, UploadScoutAPI -from cg.store.models import Family, Sample +from cg.store.models import Case, Sample from tests.mocks.hk_mock import MockHousekeeperAPI from tests.store_helpers import StoreHelpers @@ -521,7 +521,7 @@ def test_create_rna_dna_collections( """Test that the create_rna_dna_collections returns a list of RNADNACollections.""" # GIVEN an RNA case with RNA samples that are connected by subject ID to DNA samples in a DNA case - rna_case: Family = rna_store.get_case_by_internal_id(rna_case_id) + rna_case: Case = rna_store.get_case_by_internal_id(rna_case_id) # WHEN running the method to create a list of RNADNACollections # with the relationships between RNA/DNA samples and DNA cases @@ -544,7 +544,7 @@ def test_add_rna_sample( """Test that for a given RNA case the RNA samples are added to the RNADNACollections.""" # GIVEN an RNA case and the associated RNA samples - rna_case: Family = rna_store.get_case_by_internal_id(internal_id=rna_case_id) + rna_case: Case = rna_store.get_case_by_internal_id(internal_id=rna_case_id) rna_sample_list: list[Sample] = ( rna_store._get_query(table=Sample).filter(Sample.internal_id.like("rna")).all() ) @@ -594,7 +594,7 @@ def test_add_dna_cases_to_dna_sample( # GIVEN an RNA sample, a DNA sample, and a DNA case rna_sample: Sample = rna_store.get_sample_by_internal_id(internal_id=rna_sample_son_id) - dna_case: Family = rna_store.get_case_by_internal_id(internal_id=dna_case_id) + dna_case: Case = rna_store.get_case_by_internal_id(internal_id=dna_case_id) # WHEN adding creating the RNADNACollection rna_dna_collection: RNADNACollection = upload_scout_api.create_rna_dna_collection(rna_sample) @@ -615,7 +615,7 @@ def test_map_dna_cases_to_dna_sample_incorrect_pipeline( # GIVEN an RNA sample and a DNA sample dna_sample: Sample = rna_store.get_sample_by_internal_id(dna_sample_son_id) - dna_case: Family = rna_store.get_case_by_internal_id(dna_case_id) + 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 @@ -643,7 +643,7 @@ def test_map_dna_cases_to_dna_sample_incorrect_customer( # GIVEN an RNA sample, a DNA sample, and a rna-dna case map dna_sample: Sample = rna_store.get_sample_by_internal_id(internal_id=dna_sample_son_id) - dna_case: Family = rna_store.get_case_by_internal_id(internal_id=dna_case_id) + dna_case: Case = rna_store.get_case_by_internal_id(internal_id=dna_case_id) rna_sample: Sample = rna_store.get_sample_by_internal_id(internal_id=rna_sample_son_id) # GIVEN that the DNA case has a different customer than the expected customer @@ -668,7 +668,7 @@ def test_get_multiqc_html_report( """Test that the multiqc html report is returned.""" # GIVEN a DNA case with a multiqc-htlml report - case: Family = rna_store.get_case_by_internal_id(internal_id=dna_case_id) + case: Case = rna_store.get_case_by_internal_id(internal_id=dna_case_id) multiqc_file: File = mip_dna_analysis_hk_api.files( bundle=dna_case_id, tags=[ScoutCustomCaseReportTags.MULTIQC] )[0] @@ -779,7 +779,7 @@ def test_upload_rna_report_to_not_yet_uploaded_dna_case_in_scout( dna_case_ids: Set[str] = upload_mip_analysis_scout_api.get_unique_dna_cases_related_to_rna_case( case_id=rna_case_id ) - dna_case: Family = rna_store.get_case_by_internal_id(internal_id=list(dna_case_ids)[0]) + dna_case: Case = rna_store.get_case_by_internal_id(internal_id=list(dna_case_ids)[0]) dna_case.analyses[0].uploaded_at = None # WHEN trying to upload the report diff --git a/tests/meta/upload/test_meta_upload_coverage.py b/tests/meta/upload/test_meta_upload_coverage.py index 347a609393..c1bc95e6cd 100644 --- a/tests/meta/upload/test_meta_upload_coverage.py +++ b/tests/meta/upload/test_meta_upload_coverage.py @@ -6,13 +6,13 @@ from cg.apps.housekeeper.hk import HousekeeperAPI from cg.meta.upload.coverage import UploadCoverageApi from cg.store import Store -from cg.store.models import Family +from cg.store.models import Case class MockAnalysis: """Mock Analysis object""" - def __init__(self, case_obj: Family, started_at: datetime): + def __init__(self, case_obj: Case, started_at: datetime): self.case_obj = case_obj self.started_at = started_at diff --git a/tests/meta/upload/test_upload_api.py b/tests/meta/upload/test_upload_api.py index 55aa72a8f9..f7f62a5078 100644 --- a/tests/meta/upload/test_upload_api.py +++ b/tests/meta/upload/test_upload_api.py @@ -3,11 +3,11 @@ from cg.meta.upload.upload_api import UploadAPI from cg.models.cg_config import CGConfig -from cg.store.models import Analysis, Family +from cg.store.models import Analysis, Case from tests.cli.workflow.conftest import tb_api -def test_mip_dna_update_uploaded_at(mip_dna_context: CGConfig, mip_dna_case: Family): +def test_mip_dna_update_uploaded_at(mip_dna_context: CGConfig, mip_dna_case: Case): """Test setting uploaded at for a finished analysis.""" # GIVEN an analysis that should be uploaded upload_api: UploadAPI = UploadAPI( diff --git a/tests/meta/workflow/conftest.py b/tests/meta/workflow/conftest.py index 85e2d55b8f..471c382b18 100644 --- a/tests/meta/workflow/conftest.py +++ b/tests/meta/workflow/conftest.py @@ -10,7 +10,7 @@ from cg.meta.workflow.mip_dna import MipDNAAnalysisAPI from cg.models.cg_config import CGConfig from cg.models.compression_data import CompressionData -from cg.store.models import Family, Sample +from cg.store.models import Case, Sample from tests.cli.workflow.balsamic.conftest import ( balsamic_housekeeper_dir, fastq_file_l_1_r_1, @@ -153,7 +153,7 @@ def qc_microsalt_context( store = analysis_api.status_db # Create MWR microsalt case that passes QC - microsalt_case_qc_pass: Family = helpers.add_case( + microsalt_case_qc_pass: Case = helpers.add_case( store=store, internal_id=microsalt_case_qc_pass, name=microsalt_case_qc_pass, @@ -173,7 +173,7 @@ def qc_microsalt_context( helpers.add_relationship(store=store, case=microsalt_case_qc_pass, sample=sample_to_add) # Create a microsalt MWX case that fails QC - microsalt_case_qc_fail: Family = helpers.add_case( + microsalt_case_qc_fail: Case = helpers.add_case( store=store, internal_id=microsalt_case_qc_fail, name=microsalt_case_qc_fail, diff --git a/tests/meta/workflow/test_analysis.py b/tests/meta/workflow/test_analysis.py index 711f4075a1..f073ccdc81 100644 --- a/tests/meta/workflow/test_analysis.py +++ b/tests/meta/workflow/test_analysis.py @@ -14,7 +14,7 @@ from cg.meta.workflow.mip_dna import MipDNAAnalysisAPI from cg.meta.workflow.prepare_fastq import PrepareFastqAPI from cg.store import Store -from cg.store.models import Family +from cg.store.models import Case @pytest.mark.parametrize( @@ -78,7 +78,7 @@ def test_is_flow_cell_check_applicable(mip_analysis_api: MipDNAAnalysisAPI, anal down-sampled nor external samples.""" # GIVEN a case - case: Family = analysis_store.get_cases()[0] + case: Case = analysis_store.get_cases()[0] # GIVEN that no samples are down-sampled nor external for sample in case.samples: @@ -97,7 +97,7 @@ def test_is_flow_cell_check_not_applicable_when_external( down-sampled nor external samples.""" # GIVEN a case - case: Family = analysis_store.get_cases()[0] + case: Case = analysis_store.get_cases()[0] # WHEN marking all of its samples as external for sample in case.samples: @@ -115,7 +115,7 @@ def test_is_flow_cell_check_not_applicable_when_down_sampled( down-sampled nor external samples.""" # GIVEN a case - case: Family = analysis_store.get_cases()[0] + case: Case = analysis_store.get_cases()[0] # WHEN marking all of its samples as down sampled from TestSample for sample in case.samples: @@ -133,7 +133,7 @@ def test_ensure_flow_cells_on_disk_check_not_applicable( when is_flow_cell_check_applicable returns false.""" # GIVEN a case - case: Family = analysis_store.get_cases()[0] + case: Case = analysis_store.get_cases()[0] # WHEN _is_flow_cell_check_available returns False with mock.patch.object( @@ -158,7 +158,7 @@ def test_ensure_flow_cells_on_disk_does_not_request_flow_cells( when is_flow_cell_check_applicable returns True and all flow cells are ON_DISK already.""" # GIVEN a case - case: Family = analysis_store.get_cases()[0] + case: Case = analysis_store.get_cases()[0] helpers.add_flow_cell( analysis_store, @@ -191,7 +191,7 @@ def test_ensure_flow_cells_on_disk_does_request_flow_cells( when is_flow_cell_check_applicable returns True..""" # GIVEN a case with a REMOVED flow cell - case: Family = analysis_store.get_cases()[0] + case: Case = analysis_store.get_cases()[0] helpers.add_flow_cell( analysis_store, flow_cell_name="flow_cell_test", @@ -221,7 +221,7 @@ def test_is_case_ready_for_analysis_true( files need no decompression nor are being decompressed currently.""" # GIVEN a case and a flow cell with status ON_DISK - case: Family = analysis_store.get_cases()[0] + case: Case = analysis_store.get_cases()[0] helpers.add_flow_cell( analysis_store, flow_cell_name="flowcell_test", @@ -248,7 +248,7 @@ def test_is_case_ready_for_analysis_decompression_needed( files need decompression.""" # GIVEN a case and a flow cell - case: Family = analysis_store.get_cases()[0] + case: Case = analysis_store.get_cases()[0] helpers.add_flow_cell( analysis_store, flow_cell_name="flowcell_test", @@ -278,7 +278,7 @@ def test_is_case_ready_for_analysis_decompression_running( files are being decompressed currently.""" # GIVEN a case and a flow cell - case: Family = analysis_store.get_cases()[0] + case: Case = analysis_store.get_cases()[0] helpers.add_flow_cell( analysis_store, flow_cell_name="flowcell_test", @@ -303,7 +303,7 @@ def test_prepare_fastq_files_success(mip_analysis_api: MipDNAAnalysisAPI, analys and no spring decompression is needed nor is running.""" # GIVEN a case with a flow cell ON_DISK - case: Family = analysis_store.get_cases()[0] + case: Case = analysis_store.get_cases()[0] helpers.add_flow_cell( analysis_store, flow_cell_name="flowcell_test", @@ -334,7 +334,7 @@ def test_prepare_fastq_files_decompression_needed( when running prepare_fastq_files.""" # GIVEN a case with its flow cell with status ON_DISK - case: Family = analysis_store.get_cases()[0] + case: Case = analysis_store.get_cases()[0] helpers.add_flow_cell( analysis_store, flow_cell_name="flowcell_test", @@ -366,7 +366,7 @@ def test_prepare_fastq_files_decompression_running( when running prepare_fastq_files.""" # GIVEN a case with all its flow cells being ON_DISK - case: Family = analysis_store.get_cases()[0] + case: Case = analysis_store.get_cases()[0] helpers.add_flow_cell( analysis_store, flow_cell_name="flowcell_test", diff --git a/tests/meta/workflow/test_microsalt.py b/tests/meta/workflow/test_microsalt.py index 3144cdc990..f2d3d54fcb 100644 --- a/tests/meta/workflow/test_microsalt.py +++ b/tests/meta/workflow/test_microsalt.py @@ -9,7 +9,7 @@ from cg.models.cg_config import CGConfig from cg.models.orders.sample_base import ControlEnum from cg.store import Store -from cg.store.models import Family +from cg.store.models import Case from tests.mocks.tb_mock import MockTB from tests.store_helpers import StoreHelpers @@ -28,7 +28,7 @@ def test_qc_check_fail( microsalt_api: MicrosaltAnalysisAPI = qc_microsalt_context.meta_apis["analysis_api"] # GIVEN a case that is to be stored - microsalt_case: Family = store.get_case_by_internal_id(internal_id=microsalt_case_qc_fail) + microsalt_case: Case = store.get_case_by_internal_id(internal_id=microsalt_case_qc_fail) for index in range(4): microsalt_case.samples[index].reads = 1000 @@ -60,7 +60,7 @@ def test_qc_check_pass( microsalt_api: MicrosaltAnalysisAPI = qc_microsalt_context.meta_apis["analysis_api"] # GIVEN a case that is to be stored - microsalt_case: Family = store.get_case_by_internal_id(internal_id=microsalt_case_qc_pass) + microsalt_case: Case = store.get_case_by_internal_id(internal_id=microsalt_case_qc_pass) microsalt_case.samples[1].control = ControlEnum.negative microsalt_case.samples[1].reads = 1100000 @@ -93,7 +93,7 @@ def test_qc_check_negative_control_fail( microsalt_api: MicrosaltAnalysisAPI = qc_microsalt_context.meta_apis["analysis_api"] # GIVEN a case that is to be stored - microsalt_case: Family = store.get_case_by_internal_id(internal_id=microsalt_case_qc_fail) + microsalt_case: Case = store.get_case_by_internal_id(internal_id=microsalt_case_qc_fail) microsalt_case.samples[0].control = ControlEnum.negative mocker.patch.object(MicrosaltAnalysisAPI, "create_qc_done_file") @@ -152,8 +152,8 @@ def test_get_cases_to_store( helpers.ensure_case(store=store, data_analysis=Pipeline.MICROSALT, action=CaseActions.RUNNING) # WHEN getting the cases to store in Housekeeper - cases_to_store: list[Family] = analysis_api.get_cases_to_store() - case: Family = cases_to_store[0] + cases_to_store: list[Case] = analysis_api.get_cases_to_store() + case: Case = cases_to_store[0] # THEN a list with one microsalt case is returned assert len(cases_to_store) == 1 diff --git a/tests/meta/workflow/test_prepare_fastq_api.py b/tests/meta/workflow/test_prepare_fastq_api.py index 5211db79bb..c6594627c2 100644 --- a/tests/meta/workflow/test_prepare_fastq_api.py +++ b/tests/meta/workflow/test_prepare_fastq_api.py @@ -10,7 +10,7 @@ from cg.meta.workflow.prepare_fastq import PrepareFastqAPI from cg.models import CompressionData from cg.store import Store -from cg.store.models import Family +from cg.store.models import Case def test_is_spring_decompression_needed_when_true( @@ -26,7 +26,7 @@ def test_is_spring_decompression_needed_when_true( store=analysis_store_single_case, compress_api=populated_compress_spring_api ) # GIVEN a store with a case that has linked samples - case_obj: Family = analysis_store_single_case.get_case_by_internal_id(internal_id=case_id) + case_obj: Case = analysis_store_single_case.get_case_by_internal_id(internal_id=case_id) assert case_obj # GIVEN that the case has linked samples link_objects = [link_obj for link_obj in case_obj.links] @@ -57,7 +57,7 @@ def test_is_spring_decompression_needed_when_false( store=analysis_store_single_case, compress_api=populated_compress_api_fastq_spring ) # GIVEN a store with a case that has linked samples - case_obj: Family = analysis_store_single_case.get_case_by_internal_id(internal_id=case_id) + case_obj: Case = analysis_store_single_case.get_case_by_internal_id(internal_id=case_id) assert case_obj # GIVEN that the case has linked samples link_objects = [link_obj for link_obj in case_obj.links] diff --git a/tests/mocks/store_model.py b/tests/mocks/store_model.py index c90c400e06..8a525ac55c 100644 --- a/tests/mocks/store_model.py +++ b/tests/mocks/store_model.py @@ -1,7 +1,7 @@ """Mock models from the store. Used for processing them without using the store""" import datetime -from cg.store.models import Analysis, Customer, Family +from cg.store.models import Analysis, Customer, Case class Customer(Customer): @@ -11,7 +11,7 @@ def __init__(self): self.internal_id = "cust000" -class Family(Family): +class Case(Case): """Mock a case object""" def __init__(self): @@ -28,4 +28,4 @@ class Analysis(Analysis): def __init__(self): self.id = 1 self.completed_at = datetime.datetime.now() - self.family: Family = Family() + self.family: Case = Case() diff --git a/tests/store/api/delete/test_store_api_delete.py b/tests/store/api/delete/test_store_api_delete.py index bc78b0b7a9..45fe01ea73 100644 --- a/tests/store/api/delete/test_store_api_delete.py +++ b/tests/store/api/delete/test_store_api_delete.py @@ -1,5 +1,5 @@ from cg.store import Store -from cg.store.models import Family, FamilySample, Flowcell, Sample +from cg.store.models import Case, FamilySample, Flowcell, Sample def test_delete_flow_cell(bcl2fastq_flow_cell_id: str, populated_flow_cell_store: Store): @@ -109,10 +109,10 @@ def test_store_api_delete_non_existing_case( """Test that nothing happens when trying to delete a case that does not exist.""" # GIVEN a database containing some cases but not a specific case - case: Family = store_with_multiple_cases_and_samples.get_case_by_internal_id( + case: Case = store_with_multiple_cases_and_samples.get_case_by_internal_id( internal_id=case_id_does_not_exist ) - existing_cases: list[Family] = store_with_multiple_cases_and_samples.get_cases() + existing_cases: list[Case] = store_with_multiple_cases_and_samples.get_cases() assert not case assert existing_cases @@ -123,7 +123,7 @@ def test_store_api_delete_non_existing_case( ) # THEN no case has been deleted and nothing happens - remaining_cases: list[Family] = store_with_multiple_cases_and_samples.get_cases() + remaining_cases: list[Case] = store_with_multiple_cases_and_samples.get_cases() assert len(remaining_cases) == len(existing_cases) diff --git a/tests/store/api/find/test_find_business_data.py b/tests/store/api/find/test_find_business_data.py index 93f284784f..a7a0dcbd2a 100644 --- a/tests/store/api/find/test_find_business_data.py +++ b/tests/store/api/find/test_find_business_data.py @@ -16,7 +16,7 @@ ApplicationLimitations, ApplicationVersion, Customer, - Family, + Case, FamilySample, Flowcell, Invoice, @@ -90,7 +90,7 @@ def test_get_flow_cells_by_case( base_store: Store, bcl2fastq_flow_cell_id: str, bcl_convert_flow_cell_id: str, - case: Family, + case: Case, helpers: StoreHelpers, sample: Sample, ): @@ -478,9 +478,7 @@ def test_find_cases_for_non_existing_case(store_with_multiple_cases_and_samples: # GIVEN a database containing some cases but not a specific case case_id: str = "some_case" - case: Family = store_with_multiple_cases_and_samples.get_case_by_internal_id( - internal_id=case_id - ) + case: Case = store_with_multiple_cases_and_samples.get_case_by_internal_id(internal_id=case_id) assert not case @@ -543,7 +541,7 @@ def test_verify_case_exists_with_no_case_samples( assert "Case {case_id} has no samples in in Status DB!" in caplog.text -def test_is_case_down_sampled_true(base_store: Store, case: Family, sample_id: str): +def test_is_case_down_sampled_true(base_store: Store, case: Case, sample_id: str): """Tests the down sampling check when all samples are down sampled.""" # GIVEN a case where all samples are down sampled for sample in case.samples: @@ -557,7 +555,7 @@ def test_is_case_down_sampled_true(base_store: Store, case: Family, sample_id: s assert is_down_sampled -def test_is_case_down_sampled_false(base_store: Store, case: Family, sample_id: str): +def test_is_case_down_sampled_false(base_store: Store, case: Case, sample_id: str): """Tests the down sampling check when none of the samples are down sampled.""" # GIVEN a case where all samples are not down sampled for sample in case.samples: @@ -571,7 +569,7 @@ def test_is_case_down_sampled_false(base_store: Store, case: Family, sample_id: def test_is_case_external_true( - base_store: Store, case: Family, helpers: StoreHelpers, sample_id: str + base_store: Store, case: Case, helpers: StoreHelpers, sample_id: str ): """Tests the external case check when all the samples are external.""" # GIVEN a case where all samples are not external @@ -589,7 +587,7 @@ def test_is_case_external_true( assert is_external -def test_is_case_external_false(base_store: Store, case: Family, sample_id: str): +def test_is_case_external_false(base_store: Store, case: Case, sample_id: str): """Tests the external case check when none of the samples are external.""" # GIVEN a case where all samples are not external for sample in case.samples: @@ -752,13 +750,13 @@ def test_get_pools_to_render_with_customer_and_order_enquiry( def test_get_case_by_name_and_customer_case_found(store_with_multiple_cases_and_samples: Store): """Test that a case can be found by customer and case name.""" # GIVEN a database with multiple cases for a customer - case: Family = store_with_multiple_cases_and_samples._get_query(table=Family).first() + case: Case = store_with_multiple_cases_and_samples._get_query(table=Case).first() customer: Customer = store_with_multiple_cases_and_samples._get_query(table=Customer).first() assert case.customer == customer # WHEN fetching a case by customer and case name - filtered_case: Family = store_with_multiple_cases_and_samples.get_case_by_name_and_customer( + filtered_case: Case = store_with_multiple_cases_and_samples.get_case_by_name_and_customer( customer=customer, case_name=case.name, ) @@ -789,7 +787,7 @@ def test_get_cases_not_analysed_by_sample_internal_id_multiple_cases( ): """Test that multiple cases are returned when more than one case matches the sample internal id.""" # GIVEN a store with multiple cases having the same sample internal id - cases_query: Query = store_with_multiple_cases_and_samples._get_query(table=Family) + cases_query: Query = store_with_multiple_cases_and_samples._get_query(table=Case) # Set all cases to not analysed and HOLD action for case in cases_query.all(): diff --git a/tests/store/api/find/test_find_business_data_case.py b/tests/store/api/find/test_find_business_data_case.py index 0d4f5ccc50..5def5d76c4 100644 --- a/tests/store/api/find/test_find_business_data_case.py +++ b/tests/store/api/find/test_find_business_data_case.py @@ -1,15 +1,15 @@ -"""Tests the findbusinessdata part of the Cg store API related to the Family model.""" +"""Tests the findbusinessdata part of the Cg store API related to the Case model.""" from cg.constants.constants import CaseActions, Pipeline from cg.store import Store -from cg.store.models import Family +from cg.store.models import Case def test_get_cases_by_customer_and_case_name_search(store_with_cases_and_customers: Store): """Test that only cases with the specified customer and case name search pattern are returned.""" # GIVEN a store with some cases and customers - case = store_with_cases_and_customers._get_query(table=Family).first() + case = store_with_cases_and_customers._get_query(table=Case).first() case_name_search = case.name[:3] customer = case.customer @@ -29,7 +29,7 @@ def test_get_cases_by_customers_action_and_case_search_pattern( ): """Test that only cases with the specified customers, action, and case search pattern are returned.""" # GIVEN a store with some cases and customers - case = store_with_cases_and_customers._get_query(table=Family).first() + case = store_with_cases_and_customers._get_query(table=Case).first() customer = case.customer assert case, customer @@ -53,7 +53,7 @@ def test_get_cases_by_customer_pipeline_and_case_search_pattern( ): """Test that only cases with the specified customer, pipeline, and case search pattern are returned.""" # GIVEN a store with some cases and customers - case = store_with_cases_and_customers._get_query(table=Family).first() + case = store_with_cases_and_customers._get_query(table=Case).first() # Set the pipeline and case_search customer = case.customer @@ -77,7 +77,7 @@ def test_get_running_cases_in_pipeline(store_with_cases_and_customers: Store): # GIVEN a store with some cases # WHEN getting cases with a pipeline and are running - cases: list[Family] = store_with_cases_and_customers.get_running_cases_in_pipeline( + cases: list[Case] = store_with_cases_and_customers.get_running_cases_in_pipeline( pipeline=Pipeline.MIP_DNA ) diff --git a/tests/store/api/status/test_store_api_status_analysis.py b/tests/store/api/status/test_store_api_status_analysis.py index d1afbaea6c..cdc639e140 100644 --- a/tests/store/api/status/test_store_api_status_analysis.py +++ b/tests/store/api/status/test_store_api_status_analysis.py @@ -8,7 +8,7 @@ from cg.constants.constants import CaseActions from cg.constants.subject import PhenotypeStatus from cg.store import Store -from cg.store.models import Analysis, Family, FamilySample, Sample +from cg.store.models import Analysis, Case, FamilySample, Sample from tests.store_helpers import StoreHelpers @@ -35,7 +35,7 @@ def test_get_families_with_extended_models( # WHEN getting cases to analyse cases: list[Query] = list(base_store._get_outer_join_cases_with_analyses_query()) - case: Family = cases[0] + case: Case = cases[0] # THEN cases should be returned assert cases @@ -87,12 +87,12 @@ def test_that_many_cases_can_have_one_sample_each( """Test that tests that cases are returned even if there are many result rows in the query.""" # GIVEN a database with max_nr_of_cases cases - test_cases: list[Family] = helpers.add_cases_with_samples( + test_cases: list[Case] = helpers.add_cases_with_samples( base_store, max_nr_of_cases, sequenced_at=timestamp_now ) # WHEN getting cases to analyse - cases: list[Family] = base_store.cases_to_analyze(pipeline=Pipeline.MIP_DNA) + cases: list[Case] = base_store.cases_to_analyze(pipeline=Pipeline.MIP_DNA) # THEN cases should contain all cases since they are to be analysed assert len(cases) == len(test_cases) @@ -104,7 +104,7 @@ def test_that_cases_can_have_many_samples( """Test that tests that cases are returned even if there are many result rows in the query.""" # GIVEN a cases with max_nr_of_samples sequenced samples - case_with_50: Family = helpers.add_case_with_samples( + case_with_50: Case = helpers.add_case_with_samples( base_store, "case_with_50_samples", max_nr_of_samples, sequenced_at=timestamp_now ) @@ -113,14 +113,14 @@ def test_that_cases_can_have_many_samples( assert test_sample.last_sequenced_at # GIVEN a case with one sample - case_with_one: Family = helpers.add_case(base_store, "case_with_one_sample") + case_with_one: Case = helpers.add_case(base_store, "case_with_one_sample") # GIVEN a database with a case with one sample sequenced sample link = base_store.relate_sample(case_with_one, test_sample, PhenotypeStatus.UNKNOWN) base_store.session.add(link) # WHEN getting cases to analyse - cases: list[Family] = base_store.cases_to_analyze(pipeline=Pipeline.MIP_DNA) + cases: list[Case] = base_store.cases_to_analyze(pipeline=Pipeline.MIP_DNA) # THEN cases should be returned assert cases @@ -153,7 +153,7 @@ def test_external_sample_to_re_analyse( base_store.session.add(link) # WHEN getting cases to analyse - cases: list[Family] = base_store.cases_to_analyze(pipeline=Pipeline.MIP_DNA) + cases: list[Case] = base_store.cases_to_analyze(pipeline=Pipeline.MIP_DNA) # THEN cases should be returned assert cases @@ -169,14 +169,14 @@ def test_new_external_case_not_in_result(base_store: Store, helpers: StoreHelper test_sample: Sample = helpers.add_sample(base_store, last_sequenced_at=None, is_external=True) # GIVEN a cancer case - test_case: Family = helpers.add_case(base_store, data_analysis=Pipeline.BALSAMIC) + test_case: Case = helpers.add_case(base_store, data_analysis=Pipeline.BALSAMIC) # GIVEN a database with a case with one externally sequenced samples for BALSAMIC analysis link = base_store.relate_sample(test_case, test_sample, PhenotypeStatus.UNKNOWN) base_store.session.add(link) # WHEN getting cases to analyse - cases: list[Family] = base_store.cases_to_analyze(pipeline=Pipeline.BALSAMIC) + cases: list[Case] = base_store.cases_to_analyze(pipeline=Pipeline.BALSAMIC) # THEN cases should not contain the test case assert test_case not in cases @@ -202,7 +202,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[Family] = base_store.cases_to_analyze(pipeline=Pipeline.MIP_DNA) + cases: list[Case] = base_store.cases_to_analyze(pipeline=Pipeline.MIP_DNA) # THEN cases should be returned assert cases @@ -231,7 +231,7 @@ def test_all_samples_and_analysis_completed( base_store.session.add(link) # WHEN getting cases to analyse - cases: list[Family] = base_store.cases_to_analyze(pipeline=Pipeline.MIP_DNA) + cases: list[Case] = base_store.cases_to_analyze(pipeline=Pipeline.MIP_DNA) # THEN cases should not contain the test case assert not cases @@ -246,14 +246,14 @@ def test_specified_analysis_in_result( test_sample: Sample = helpers.add_sample(base_store, last_sequenced_at=timestamp_now) # GIVEN a cancer case - test_case: Family = helpers.add_case(base_store, data_analysis=Pipeline.BALSAMIC) + test_case: Case = helpers.add_case(base_store, data_analysis=Pipeline.BALSAMIC) # GIVEN a database with a case with one sequenced samples for BALSAMIC analysis link = base_store.relate_sample(test_case, test_sample, PhenotypeStatus.UNKNOWN) base_store.session.add(link) # WHEN getting cases to analyse - cases: list[Family] = base_store.cases_to_analyze(pipeline=Pipeline.BALSAMIC) + cases: list[Case] = base_store.cases_to_analyze(pipeline=Pipeline.BALSAMIC) # THEN cases should be returned assert cases @@ -279,7 +279,7 @@ def test_exclude_other_pipeline_analysis_from_result( base_store.session.add(link) # WHEN getting cases to analyse for another pipeline - cases: list[Family] = base_store.cases_to_analyze(pipeline=Pipeline.MIP_DNA) + cases: list[Case] = base_store.cases_to_analyze(pipeline=Pipeline.MIP_DNA) # THEN cases should not contain the test case assert test_case not in cases @@ -292,7 +292,7 @@ def test_one_of_two_sequenced_samples( cases to analyse.""" # GIVEN a case - test_case: Family = helpers.add_case(base_store) + test_case: Case = helpers.add_case(base_store) # GIVEN a sequenced sample sequenced_sample: Sample = helpers.add_sample(base_store, last_sequenced_at=timestamp_now) @@ -310,7 +310,7 @@ def test_one_of_two_sequenced_samples( base_store.session.add_all([link_1, link_2]) # WHEN getting cases to analyse - cases: list[Family] = base_store.cases_to_analyze(pipeline=Pipeline.MIP_DNA, threshold=True) + cases: list[Case] = base_store.cases_to_analyze(pipeline=Pipeline.MIP_DNA, threshold=True) # THEN no cases should be returned assert not cases @@ -323,7 +323,7 @@ def test_one_of_one_sequenced_samples( cases to analyse.""" # GIVEN a case - test_case: Family = helpers.add_case(base_store) + test_case: Case = helpers.add_case(base_store) # GIVEN a sequenced sample test_sample = helpers.add_sample(base_store, last_sequenced_at=timestamp_now) @@ -334,7 +334,7 @@ def test_one_of_one_sequenced_samples( assert test_sample.last_sequenced_at is not None # WHEN getting cases to analyse - cases: list[Family] = base_store.cases_to_analyze(pipeline=Pipeline.MIP_DNA) + cases: list[Case] = base_store.cases_to_analyze(pipeline=Pipeline.MIP_DNA) # THEN cases should be returned assert cases diff --git a/tests/store/api/status/test_store_api_status_cases.py b/tests/store/api/status/test_store_api_status_cases.py index c893a0626b..bccf0a2f4e 100644 --- a/tests/store/api/status/test_store_api_status_cases.py +++ b/tests/store/api/status/test_store_api_status_cases.py @@ -2,7 +2,7 @@ from cg.constants import CASE_ACTIONS, DataDelivery, Pipeline, Priority from cg.store import Store -from cg.store.models import Analysis, Family, FamilySample +from cg.store.models import Analysis, Case, FamilySample def test_delivered_at_affects_tat(base_store: Store, helpers): @@ -1307,7 +1307,7 @@ def test_analysis_completed_at(base_store: Store, helpers): # GIVEN a database with an analysis that is completed analysis = helpers.add_analysis(base_store, completed_at=datetime.now()) assert analysis.completed_at is not None - assert base_store._get_query(table=Family).count() == 1 + assert base_store._get_query(table=Case).count() == 1 assert base_store._get_query(table=Analysis).count() == 1 # WHEN getting active cases diff --git a/tests/store/conftest.py b/tests/store/conftest.py index b3cea4443c..434055ae4e 100644 --- a/tests/store/conftest.py +++ b/tests/store/conftest.py @@ -8,7 +8,7 @@ from cg.constants import Pipeline from cg.constants.subject import Gender, PhenotypeStatus from cg.store import Store -from cg.store.models import Analysis, Application, Customer, Family, FamilySample, Organism, Sample +from cg.store.models import Analysis, Application, Customer, Case, FamilySample, Organism, Sample from tests.store_helpers import StoreHelpers @@ -159,7 +159,7 @@ def microbial_store( @pytest.fixture(name="case") -def case_obj(analysis_store: Store) -> Family: +def case_obj(analysis_store: Store) -> Case: """Return a case models object.""" return analysis_store.get_cases()[0] @@ -385,7 +385,7 @@ def store_with_an_invoice_with_and_without_attributes( def store_with_older_and_newer_analyses( base_store: Store, helpers: StoreHelpers, - case: Family, + case: Case, timestamp_now: dt.datetime, timestamp_yesterday: dt.datetime, old_timestamp: dt.datetime, diff --git a/tests/store/filters/test_status_analyses_filters.py b/tests/store/filters/test_status_analyses_filters.py index d3f74a3abe..62736cac37 100644 --- a/tests/store/filters/test_status_analyses_filters.py +++ b/tests/store/filters/test_status_analyses_filters.py @@ -20,14 +20,14 @@ order_analyses_by_completed_at_asc, order_analyses_by_uploaded_at_asc, ) -from cg.store.models import Analysis, Family +from cg.store.models import Analysis, Case from tests.store_helpers import StoreHelpers def test_filter_valid_analyses_in_production( base_store: Store, helpers: StoreHelpers, - case: Family, + case: Case, timestamp_now: datetime, old_timestamp: datetime, ): @@ -52,7 +52,7 @@ 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: Family): +def test_filter_analyses_with_pipeline(base_store: Store, helpers: StoreHelpers, case: Case): """Test analyses filtering by pipeline.""" # GIVEN a set of mock analyses @@ -166,7 +166,7 @@ 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: Family): +def test_filter_report_analyses_by_pipeline(base_store: Store, helpers: StoreHelpers, case: Case): """Test filtering delivery report related analysis by pipeline.""" # GIVEN a set of mock analysis @@ -191,7 +191,7 @@ def test_filter_report_analyses_by_pipeline(base_store: Store, helpers: StoreHel def test_order_analyses_by_completed_at_asc( store: Store, helpers: StoreHelpers, - case: Family, + case: Case, timestamp_now: datetime, timestamp_yesterday: datetime, ): @@ -231,7 +231,7 @@ def test_order_analyses_by_uploaded_at_asc( assert analyses.all()[index].uploaded_at <= analyses.all()[index + 1].uploaded_at -def test_filter_analysis_by_case(base_store: Store, helpers: StoreHelpers, case: Family): +def test_filter_analysis_by_case(base_store: Store, helpers: StoreHelpers, case: Case): """Test filtering of analyses by case.""" # GIVEN a set of mock analyses diff --git a/tests/store/filters/test_status_cases_filters.py b/tests/store/filters/test_status_cases_filters.py index 688af2c63e..0dbbcd7342 100644 --- a/tests/store/filters/test_status_cases_filters.py +++ b/tests/store/filters/test_status_cases_filters.py @@ -29,7 +29,7 @@ filter_report_supported_data_delivery_cases, filter_running_cases, ) -from cg.store.models import Analysis, Family, FamilySample, Sample +from cg.store.models import Analysis, Case, FamilySample, Sample from tests.store_helpers import StoreHelpers @@ -175,7 +175,7 @@ def test_filter_cases_with_pipeline_when_incorrect_pipline( test_sample: Sample = helpers.add_sample(base_store, last_sequenced_at=timestamp_now) # GIVEN a cancer case - test_case: Family = helpers.add_case(base_store, data_analysis=Pipeline.BALSAMIC) + test_case: Case = helpers.add_case(base_store, data_analysis=Pipeline.BALSAMIC) # GIVEN a database with a case with one sequenced samples for specified analysis link = base_store.relate_sample(test_case, test_sample, PhenotypeStatus.UNKNOWN) @@ -200,9 +200,9 @@ def test_filter_cases_with_loqusdb_supported_pipeline( test_sample: Sample = helpers.add_sample(base_store, last_sequenced_at=timestamp_now) # GIVEN a MIP-DNA and a FLUFFY case - test_mip_case: Family = helpers.add_case(base_store, data_analysis=Pipeline.MIP_DNA) + test_mip_case: Case = helpers.add_case(base_store, data_analysis=Pipeline.MIP_DNA) test_mip_case.customer.loqus_upload = True - test_fluffy_case: Family = helpers.add_case( + test_fluffy_case: Case = helpers.add_case( base_store, name="test", data_analysis=Pipeline.FLUFFY ) test_fluffy_case.customer.loqus_upload = True @@ -238,7 +238,7 @@ def test_filter_cases_with_loqusdb_supported_sequencing_method( ) # GIVEN a MIP-DNA associated test case - test_case_wes: Family = helpers.add_case(base_store, data_analysis=Pipeline.MIP_DNA) + test_case_wes: Case = helpers.add_case(base_store, data_analysis=Pipeline.MIP_DNA) link = base_store.relate_sample(test_case_wes, test_sample_wes, PhenotypeStatus.UNKNOWN) base_store.session.add(link) @@ -268,7 +268,7 @@ def test_filter_cases_with_loqusdb_supported_sequencing_method_empty( ) # GIVEN a MIP-DNA associated test case - test_case_wts: Family = helpers.add_case(base_store, data_analysis=Pipeline.MIP_DNA) + test_case_wts: Case = helpers.add_case(base_store, data_analysis=Pipeline.MIP_DNA) link = base_store.relate_sample(test_case_wts, test_sample_wts, PhenotypeStatus.UNKNOWN) base_store.session.add(link) @@ -490,7 +490,7 @@ def test_filter_inactive_analysis_cases(base_store: Store, helpers: StoreHelpers test_case = helpers.add_case(base_store) # GIVEN a cases Query - cases: Query = base_store._get_query(table=Family) + cases: Query = base_store._get_query(table=Case) # WHEN getting completed cases cases: Query = filter_inactive_analysis_cases(cases=cases) @@ -511,7 +511,7 @@ def test_filter_inactive_analysis_cases_when_on_hold(base_store: Store, helpers: test_case = helpers.add_case(base_store, action=CaseActions.HOLD) # GIVEN a cases Query - cases: Query = base_store._get_query(table=Family) + cases: Query = base_store._get_query(table=Case) # WHEN getting completed cases cases: Query = filter_inactive_analysis_cases(cases=cases) @@ -534,7 +534,7 @@ def test_filter_inactive_analysis_cases_when_not_completed( helpers.add_case(base_store, action=CaseActions.RUNNING) # GIVEN a cases Query - cases: Query = base_store._get_query(table=Family) + cases: Query = base_store._get_query(table=Case) # WHEN getting completed cases cases: Query = filter_inactive_analysis_cases(cases=cases) @@ -553,7 +553,7 @@ def test_get_old_cases(base_store: Store, helpers: StoreHelpers, timestamp_in_2_ test_case = helpers.add_case(base_store) # GIVEN a cases Query - cases: Query = base_store._get_query(table=Family) + cases: Query = base_store._get_query(table=Case) # WHEN getting completed cases cases: Query = filter_older_cases_by_creation_date( @@ -578,7 +578,7 @@ def test_get_old_cases_none_when_all_cases_are_too_new( helpers.add_case(base_store) # GIVEN a cases Query - cases: Query = base_store._get_query(table=Family) + cases: Query = base_store._get_query(table=Case) # WHEN getting completed cases cases: Query = filter_older_cases_by_creation_date( @@ -594,7 +594,7 @@ def test_get_old_cases_none_when_all_cases_are_too_new( def test_filter_case_by_existing_entry_id(store_with_multiple_cases_and_samples: Store): # GIVEN a store containing a case with an entry id - cases_query: Query = store_with_multiple_cases_and_samples._get_query(table=Family) + cases_query: Query = store_with_multiple_cases_and_samples._get_query(table=Case) entry_id: int = cases_query.first().id assert entry_id @@ -609,7 +609,7 @@ def test_filter_cases_by_non_existing_entry_id( store_with_multiple_cases_and_samples: Store, non_existent_id: str ): # GIVEN a store containing cases without a specific entry id - cases_query: Query = store_with_multiple_cases_and_samples._get_query(table=Family) + cases_query: Query = store_with_multiple_cases_and_samples._get_query(table=Case) entry_ids = [case.id for case in cases_query.all()] assert non_existent_id not in entry_ids @@ -624,7 +624,7 @@ def test_filter_case_by_existing_internal_id( store_with_multiple_cases_and_samples: Store, case_id: str ): # GIVEN a store containing a case with an internal id case_id - cases_query: Query = store_with_multiple_cases_and_samples._get_query(table=Family) + cases_query: Query = store_with_multiple_cases_and_samples._get_query(table=Case) internal_ids = [case.internal_id for case in cases_query.all()] assert case_id in internal_ids @@ -642,7 +642,7 @@ def test_filter_cases_by_non_existing_internal_id( store_with_multiple_cases_and_samples: Store, non_existent_id: str ): # GIVEN a store containing a case with an internal id case_id - cases_query: Query = store_with_multiple_cases_and_samples._get_query(table=Family) + cases_query: Query = store_with_multiple_cases_and_samples._get_query(table=Case) internal_ids = [case.internal_id for case in cases_query.all()] assert non_existent_id not in internal_ids @@ -655,7 +655,7 @@ def test_filter_cases_by_non_existing_internal_id( def test_filter_case_by_empty_internal_id(store_with_multiple_cases_and_samples: Store): # GIVEN a store containing cases - cases_query: Query = store_with_multiple_cases_and_samples._get_query(table=Family) + cases_query: Query = store_with_multiple_cases_and_samples._get_query(table=Case) # WHEN filtering for cases with an empty internal id cases: Query = filter_case_by_internal_id(cases=cases_query, internal_id="") @@ -667,8 +667,8 @@ def test_filter_case_by_empty_internal_id(store_with_multiple_cases_and_samples: def test_filter_running_cases_no_running_cases(store_with_multiple_cases_and_samples: Store): """Test that no cases are returned when no cases have a running action.""" # GIVEN a store containing cases with no "running" action - cases_query: Query = store_with_multiple_cases_and_samples._get_query(table=Family) - cases_query = cases_query.filter(Family.action != CaseActions.RUNNING) + cases_query: Query = store_with_multiple_cases_and_samples._get_query(table=Case) + cases_query = cases_query.filter(Case.action != CaseActions.RUNNING) # WHEN getting active cases active_cases: Query = filter_running_cases(cases=cases_query) @@ -680,7 +680,7 @@ def test_filter_running_cases_no_running_cases(store_with_multiple_cases_and_sam def test_filter_running_cases_with_running_cases(store_with_multiple_cases_and_samples: Store): """Test that at least one case is returned when at least one case has a running action.""" # GIVEN a store containing cases with at least one "running" action - cases_query: Query = store_with_multiple_cases_and_samples._get_query(table=Family) + cases_query: Query = store_with_multiple_cases_and_samples._get_query(table=Case) actions: list[str] = [case.action for case in cases_query.all()] assert CaseActions.RUNNING in actions @@ -694,7 +694,7 @@ def test_filter_running_cases_with_running_cases(store_with_multiple_cases_and_s def test_filter_running_cases_only_running_cases(store_with_multiple_cases_and_samples: Store): """Test that all cases are returned when all cases have a running action.""" # GIVEN a store containing only cases with "running" action - cases_query: Query = store_with_multiple_cases_and_samples._get_query(table=Family) + cases_query: Query = store_with_multiple_cases_and_samples._get_query(table=Case) for case in cases_query.all(): case.action = CaseActions.RUNNING @@ -710,7 +710,7 @@ def test_filter_cases_by_ticket_no_matching_ticket( ): """Test that no cases are returned when filtering by a non-existent ticket.""" # GIVEN a store containing cases with no matching ticket id - cases_query: Query = store_with_multiple_cases_and_samples._get_query(table=Family) + cases_query: Query = store_with_multiple_cases_and_samples._get_query(table=Case) # WHEN filtering cases by a non-existent ticket filtered_cases: Query = filter_cases_by_ticket_id(cases=cases_query, ticket_id=non_existent_id) @@ -724,7 +724,7 @@ def test_filter_cases_by_ticket_matching_ticket( ): """Test that cases are returned when filtering by an existing ticket id.""" # GIVEN a store containing cases with a matching ticket id - cases_query: Query = store_with_multiple_cases_and_samples._get_query(table=Family) + cases_query: Query = store_with_multiple_cases_and_samples._get_query(table=Case) # WHEN filtering cases by an existing ticket id filtered_cases: Query = filter_cases_by_ticket_id(cases=cases_query, ticket_id=ticket_id) @@ -738,7 +738,7 @@ def test_filter_cases_by_ticket_matching_ticket( def test_filter_cases_by_customer_entry_ids(store_with_multiple_cases_and_samples: Store): """Test that cases are returned when filtering by customer entry ids.""" # GIVEN a store containing cases with customer ids - cases_query: Query = store_with_multiple_cases_and_samples._get_query(table=Family) + cases_query: Query = store_with_multiple_cases_and_samples._get_query(table=Case) customer_ids = [case.customer_id for case in cases_query.all()] assert customer_ids @@ -758,7 +758,7 @@ def test_filter_cases_by_customer_entry_ids(store_with_multiple_cases_and_sample def test_filter_cases_by_name(store_with_multiple_cases_and_samples: Store): """Test that cases are returned when filtering by name.""" # GIVEN a store containing cases with various names - cases_query: Query = store_with_multiple_cases_and_samples._get_query(table=Family) + cases_query: Query = store_with_multiple_cases_and_samples._get_query(table=Case) test_name = cases_query.first().name # WHEN filtering cases by a specific name @@ -772,7 +772,7 @@ def test_filter_cases_by_name(store_with_multiple_cases_and_samples: Store): def test_filter_cases_by_search_pattern(store_with_multiple_cases_and_samples: Store): """Test that cases are returned when filtering by matching internal ids.""" # GIVEN a store containing cases with internal ids and names - cases_query: Query = store_with_multiple_cases_and_samples._get_query(table=Family) + cases_query: Query = store_with_multiple_cases_and_samples._get_query(table=Case) test_internal_id_pattern = cases_query.first().internal_id[:3] test_name_pattern = cases_query.first().name[:3] @@ -796,7 +796,7 @@ def test_filter_cases_not_analysed_no_cases( ): """Test that no cases are returned when all cases have been analysed.""" # GIVEN a store containing only cases that have been analysed - cases_query: Query = store_with_multiple_cases_and_samples._get_query(table=Family) + cases_query: Query = store_with_multiple_cases_and_samples._get_query(table=Case) for case in cases_query.all(): case.analyses.append(Analysis(completed_at=datetime.now())) @@ -812,7 +812,7 @@ def test_filter_cases_not_analysed_no_cases_in_progress( ): """Test that all cases are returned when no cases are in progress.""" # GIVEN a store containing cases that have not been analysed and no cases are in progress - cases_query: Query = store_with_multiple_cases_and_samples._get_query(table=Family) + cases_query: Query = store_with_multiple_cases_and_samples._get_query(table=Case) for case in cases_query.all(): case.analyses = [] case.action = CaseActions.HOLD @@ -829,7 +829,7 @@ def test_filter_cases_not_analysed_in_progress( ): """Test that no cases in progress are returned.""" # GIVEN a store containing cases that have not been analysed and at least one case is in progress - cases_query: Query = store_with_multiple_cases_and_samples._get_query(table=Family) + cases_query: Query = store_with_multiple_cases_and_samples._get_query(table=Case) for case in cases_query.all(): case.analyses = [] case.action = CaseActions.ANALYZE @@ -846,7 +846,7 @@ def test_filter_cases_by_pipeline_search_no_matching_pipeline( ): """Test that no cases are returned when there are no cases with matching pipeline search.""" # GIVEN a store containing cases with different pipeline names - cases_query: Query = store_with_multiple_cases_and_samples._get_query(table=Family) + cases_query: Query = store_with_multiple_cases_and_samples._get_query(table=Case) pipeline_search = "non_existent_pipeline" # WHEN filtering cases by a non-matching pipeline search @@ -863,7 +863,7 @@ def test_filter_cases_by_pipeline_search_partial_match( ): """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=Family) + cases_query: Query = store_with_multiple_cases_and_samples._get_query(table=Case) pipeline_search = cases_query.first().data_analysis[:3] # WHEN filtering cases by a partially matching pipeline search @@ -882,7 +882,7 @@ def test_filter_cases_by_pipeline_search_exact_match( ): """Test that cases with exactly 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=Family) + cases_query: Query = store_with_multiple_cases_and_samples._get_query(table=Case) pipeline_search = cases_query.first().data_analysis # WHEN filtering cases by an exactly matching pipeline search @@ -901,7 +901,7 @@ def test_filter_cases_by_priority_no_matching_priority( ): """Test that no cases are returned when there are no cases with matching priority.""" # GIVEN a store containing cases with different priorities - cases_query: Query = store_with_multiple_cases_and_samples._get_query(table=Family) + cases_query: Query = store_with_multiple_cases_and_samples._get_query(table=Case) non_existent_priority = "non_existent_priority" # WHEN filtering cases by a non-matching priority @@ -918,7 +918,7 @@ def test_filter_cases_by_priority_matching_priority( ): """Test that cases with matching priority are returned.""" # GIVEN a store containing cases with different priorities - cases_query: Query = store_with_multiple_cases_and_samples._get_query(table=Family) + cases_query: Query = store_with_multiple_cases_and_samples._get_query(table=Case) existing_priority = cases_query.first().priority # WHEN filtering cases by a matching priority @@ -935,7 +935,7 @@ def test_filter_cases_by_priority_all_priorities( ): """Test that filtering cases by all available priorities returns all cases.""" # GIVEN a store containing cases with different priorities - cases_query: Query = store_with_multiple_cases_and_samples._get_query(table=Family) + cases_query: Query = store_with_multiple_cases_and_samples._get_query(table=Case) all_priorities = set(case.priority for case in cases_query) # WHEN filtering cases by all available priorities @@ -952,7 +952,7 @@ def test_filter_newer_cases_by_order_date_no_newer_cases( ): """Test that no cases are returned when there are no cases with a newer order date.""" # GIVEN a store containing cases with different order dates - cases_query: Query = store_with_multiple_cases_and_samples._get_query(table=Family) + cases_query: Query = store_with_multiple_cases_and_samples._get_query(table=Case) latest_order_date = max(case.ordered_at for case in cases_query) # WHEN filtering cases by a date that is later than the latest order date @@ -969,7 +969,7 @@ def test_filter_newer_cases_by_order_date_some_newer_cases( ): """Test that cases with order dates newer than the given date are returned.""" # GIVEN a store containing cases with different order dates - cases_query: Query = store_with_multiple_cases_and_samples._get_query(table=Family) + cases_query: Query = store_with_multiple_cases_and_samples._get_query(table=Case) min_order_date = min(case.ordered_at for case in cases_query) max_order_date = max(case.ordered_at for case in cases_query) @@ -992,7 +992,7 @@ def test_get_older_cases_by_created_date_no_older_cases( ): """Test that no cases are returned when there are no cases with an older creation date.""" # GIVEN a store containing cases with different creation dates - cases_query: Query = store_with_multiple_cases_and_samples._get_query(table=Family) + cases_query: Query = store_with_multiple_cases_and_samples._get_query(table=Case) oldest_created_date = min(case.created_at for case in cases_query) # WHEN filtering cases by a date that is later than the oldest order date @@ -1009,7 +1009,7 @@ def test_filter_runningfilter_older_cases_by_creation_date_some_newer_cases( ): """Test that cases with creation dates older than the given date are returned.""" # GIVEN a store containing cases with different creation dates - cases_query: Query = store_with_multiple_cases_and_samples._get_query(table=Family) + cases_query: Query = store_with_multiple_cases_and_samples._get_query(table=Case) min_creation_date = min(case.created_at for case in cases_query) max_creation_date = max(case.created_at for case in cases_query) diff --git a/tests/store/filters/test_status_flow_cell_filters.py b/tests/store/filters/test_status_flow_cell_filters.py index 1c677fa640..3f775703db 100644 --- a/tests/store/filters/test_status_flow_cell_filters.py +++ b/tests/store/filters/test_status_flow_cell_filters.py @@ -10,13 +10,13 @@ filter_flow_cells_by_case, filter_flow_cells_with_statuses, ) -from cg.store.models import Family, Flowcell, Sample +from cg.store.models import Case, Flowcell, Sample from tests.store_helpers import StoreHelpers def test_get_flow_cells_by_case( base_store: Store, - case: Family, + case: Case, bcl2fastq_flow_cell_id: str, helpers: StoreHelpers, sample: Sample, @@ -42,7 +42,7 @@ def test_get_flow_cells_by_case( def test_get_flow_cells_by_case_when_no_flow_cell_for_case( base_store: Store, - case: Family, + case: Case, ): """Test that a flow cell is not returned when there is a flow cell with no matching flow cell for case.""" diff --git a/tests/store/test_delivery.py b/tests/store/test_delivery.py index 818f5eae3d..9396be5340 100644 --- a/tests/store/test_delivery.py +++ b/tests/store/test_delivery.py @@ -4,10 +4,10 @@ from cg.constants import DataDelivery from cg.constants.constants import Pipeline -from cg.store.models import Family, Sample +from cg.store.models import Case, Sample -def test_get_delivery_arguments(case: Family): +def test_get_delivery_arguments(case: Case): """Testing the parsing of delivery arguments from the case data_delivery.""" # GIVEN a DataDelivery case.data_delivery = DataDelivery.FASTQ_ANALYSIS_SCOUT diff --git a/tests/store_helpers.py b/tests/store_helpers.py index fa130a45e4..219d6fec60 100644 --- a/tests/store_helpers.py +++ b/tests/store_helpers.py @@ -21,7 +21,7 @@ BedVersion, Collaboration, Customer, - Family, + Case, FamilySample, Flowcell, Invoice, @@ -273,7 +273,7 @@ def ensure_customer( @staticmethod def add_analysis( store: Store, - case: Family = None, + case: Case = None, started_at: datetime = None, completed_at: datetime = None, uploaded_at: datetime = None, @@ -410,9 +410,9 @@ def add_case( internal_id: str = None, customer_id: str = "cust000", panels: list[str] = [], - case_obj: Family = None, + case_obj: Case = None, ticket: str = "123456", - ) -> Family: + ) -> Case: """Utility function to add a case to use in tests, If no case object is used a autogenerated case id will be used. @@ -428,7 +428,7 @@ def add_case( ) if not case_obj: - case_obj: Optional[Family] = store.get_case_by_internal_id(internal_id=name) + case_obj: Optional[Case] = store.get_case_by_internal_id(internal_id=name) if not case_obj: case_obj = store.add_case( data_analysis=data_analysis, @@ -487,7 +487,7 @@ def ensure_case_from_dict( ): """Load a case with samples and link relations from a dictionary.""" customer_obj = StoreHelpers.ensure_customer(store) - case = Family( + case = Case( name=case_info["name"], panels=case_info["panels"], internal_id=case_info["internal_id"], @@ -649,7 +649,7 @@ def add_flow_cell( def add_relationship( store: Store, sample: Sample, - case: Family, + case: Case, status: str = PhenotypeStatus.UNKNOWN, father: Sample = None, mother: Sample = None, @@ -665,9 +665,9 @@ def add_relationship( @staticmethod def add_synopsis_to_case( store: Store, case_id: str, synopsis: str = "a synopsis" - ) -> Optional[Family]: + ) -> Optional[Case]: """Function for adding a synopsis to a case in the database.""" - case_obj: Family = store.get_case_by_internal_id(internal_id=case_id) + case_obj: Case = store.get_case_by_internal_id(internal_id=case_id) if not case_obj: LOG.warning("Could not find case") return None @@ -719,7 +719,7 @@ def add_subject_id_to_sample( return sample_obj @classmethod - def relate_samples(cls, base_store: Store, case: Family, samples: list[Sample]): + def relate_samples(cls, base_store: Store, case: Case, samples: list[Sample]): """Utility function to relate many samples to one case.""" for sample in samples: @@ -736,25 +736,25 @@ def add_case_with_samples( case_id: str, nr_samples: int, sequenced_at: datetime = datetime.now(), - ) -> Family: + ) -> Case: """Utility function to add one case with many samples and return the case.""" samples: list[Sample] = cls.add_samples(store=base_store, nr_samples=nr_samples) for sample in samples: sample.last_sequenced_at: datetime = sequenced_at - case: Family = cls.add_case(store=base_store, internal_id=case_id, name=case_id) + case: Case = cls.add_case(store=base_store, internal_id=case_id, name=case_id) cls.relate_samples(base_store=base_store, case=case, samples=samples) return case @classmethod def add_cases_with_samples( cls, base_store: Store, nr_cases: int, sequenced_at: datetime - ) -> list[Family]: + ) -> list[Case]: """Utility function to add many cases with two samples to use in tests.""" - cases: list[Family] = [] + cases: list[Case] = [] for i in range(nr_cases): - case: list[Family] = cls.add_case_with_samples( + case: list[Case] = cls.add_case_with_samples( base_store, f"f{i}", 2, sequenced_at=sequenced_at ) cases.append(case) @@ -857,7 +857,7 @@ def ensure_invoice( return invoice @classmethod - def add_case_with_sample(cls, base_store: Store, case_id: str, sample_id: str) -> Family: + def add_case_with_sample(cls, base_store: Store, case_id: str, sample_id: str) -> Case: """Helper function to add a case associated with a sample with the given ids.""" case = cls.add_case(store=base_store, internal_id=case_id, name=case_id)