def test_get_case_files_from_version( analysis_store: Store, case_id: str, real_housekeeper_api: HousekeeperAPI, case_hk_bundle_no_files: dict, bed_file: str, vcf_file: Path, project_dir: Path, helpers=StoreHelpers, ): # GIVEN a store with a case case_obj = analysis_store.family(case_id) assert case_obj.internal_id == case_id # GIVEN a delivery api deliver_api = DeliverAPI( store=analysis_store, hk_api=real_housekeeper_api, case_tags=[{"case-tag"}], sample_tags=[{"sample-tag"}], project_base_path=project_dir, delivery_type="balsamic", ) # GIVEN a housekeeper db populated with a bundle including a case specific file and a sample specific file case_hk_bundle_no_files["files"] = [ { "path": bed_file, "archive": False, "tags": ["case-tag"] }, { "path": str(vcf_file), "archive": False, "tags": ["sample-tag", "ADM1"] }, ] helpers.ensure_hk_bundle(real_housekeeper_api, bundle_data=case_hk_bundle_no_files) # GIVEN a version object where two file exists version_obj: hk_models.Version = real_housekeeper_api.last_version(case_id) assert len(version_obj.files) == 2 # GIVEN the sample ids of the samples link_objs: List[FamilySample] = analysis_store.family_samples(case_id) samples: List[Sample] = [link.sample for link in link_objs] sample_ids: Set[str] = set([sample.internal_id for sample in samples]) # WHEN fetching the case files case_files = deliver_api.get_case_files_from_version( version_obj=version_obj, sample_ids=sample_ids) # THEN we should only get the case specific files back nr_files: int = 0 case_file: Path for nr_files, case_file in enumerate(case_files, 1): assert case_file.name == Path(bed_file).name # THEN assert that only the case-tag file was returned assert nr_files == 1
def microsalt(context: click.Context, order_id): """Microbial workflow""" context.obj["db"] = Store(context.obj["database"]) hk_api = hk.HousekeeperAPI(context.obj) lims_api = lims.LimsAPI(context.obj) deliver = DeliverAPI( context.obj, hk_api=hk_api, lims_api=lims_api, case_tags=PROJECT_TAGS, sample_tags=SAMPLE_TAGS, ) context.obj["api"] = AnalysisAPI(db=context.obj["db"], hk_api=hk_api, lims_api=lims_api) context.obj["lims_microsalt_api"] = LimsMicrosaltAPI(lims=lims_api) if context.invoked_subcommand is None: if order_id is None: LOG.error("Please provide an order") context.abort() else: # execute the analysis! context.invoke(config_case, order_id=order_id) context.invoke(link, order_id=order_id) context.invoke(run, order_id=order_id)
def deliver(context): """Deliver stuff.""" context.obj["db"] = Store(context.obj["database"]) context.obj["deliver_api"] = DeliverAPI( db=context.obj["db"], hk_api=hk.HousekeeperAPI(context.obj), lims_api=lims.LimsAPI(context.obj), case_tags=CASE_TAGS, sample_tags=SAMPLE_TAGS, )
def fixture_populated_deliver_api(analysis_store: Store, delivery_hk_api: HousekeeperAPI, project_dir: Path) -> DeliverAPI: """Return a delivery api where housekeeper is populated with some files""" _deliver_api = DeliverAPI( store=analysis_store, hk_api=delivery_hk_api, case_tags=["case-tag"], sample_tags=["sample-tag"], project_base_path=project_dir, delivery_type="balsamic", ) return _deliver_api
def fixture_deliver_api(analysis_store: Store, real_housekeeper_api: HousekeeperAPI, project_dir: Path) -> DeliverAPI: """Fixture for deliver_api The fixture will return a delivery api where the store is populated with a case with three individuals. The housekeeper database is empty """ _deliver_api = DeliverAPI( store=analysis_store, hk_api=real_housekeeper_api, case_tags=[{"case-tag"}], sample_tags=[{"sample-tag"}], project_base_path=project_dir, delivery_type="balsamic", ) yield _deliver_api
def test_get_sample_files_from_version( deliver_api: DeliverAPI, case_hk_bundle_no_files: dict, bed_file: str, vcf_file: Path, project_dir: Path, case_id: str, helpers=StoreHelpers, ): """Test to fetch sample specific files from the deliver API The purpose of the test is to see that only sample specific files are returned """ # GIVEN a case which exist as bundle in hk # GIVEN a housekeeper db populated with a bundle including a case specific file and a sample specific file hk_api = deliver_api.hk_api case_hk_bundle_no_files["files"] = [ { "path": bed_file, "archive": False, "tags": ["case-tag"] }, { "path": str(vcf_file), "archive": False, "tags": ["sample-tag", "ADM1"] }, ] helpers.ensure_hk_bundle(hk_api, bundle_data=case_hk_bundle_no_files) # GIVEN a version object with some files version_obj: hk_models.Version = hk_api.last_version(case_id) assert len(version_obj.files) == 2 # WHEN fetching the sample specific files sample_files = deliver_api.get_sample_files_from_version( version_obj=version_obj, sample_id="ADM1") # THEN assert that only the sample specific file was returned nr_files: int = 0 sample_file: Path for nr_files, sample_file in enumerate(sample_files, 1): assert sample_file.name == vcf_file.name # THEN assert that only the sample-tag file was returned assert nr_files == 1
def mip_dna(context: click.Context, case_id: str, email: str, priority: str, start_with: str): """Rare disease DNA workflow""" context.obj["db"] = Store(context.obj["database"]) hk_api = hk.HousekeeperAPI(context.obj) scout_api = scoutapi.ScoutAPI(context.obj) lims_api = lims.LimsAPI(context.obj) context.obj["tb"] = tb.TrailblazerAPI(context.obj) deliver = DeliverAPI( context.obj, hk_api=hk_api, lims_api=lims_api, case_tags=CASE_TAGS, sample_tags=SAMPLE_TAGS, ) context.obj["api"] = AnalysisAPI( db=context.obj["db"], hk_api=hk_api, tb_api=context.obj["tb"], scout_api=scout_api, lims_api=lims_api, deliver_api=deliver, ) if context.invoked_subcommand is None: if case_id is None: _suggest_cases_to_analyze(context, show_as_error=True) context.abort() # check everything is ok case_obj = context.obj["db"].family(case_id) if case_obj is None: LOG.error("%s: not found", case_id) context.abort() is_ok = context.obj["api"].check(case_obj) if not is_ok: LOG.warning("%s: not ready to run", case_obj.internal_id) # commit the updates to request flowcells context.obj["db"].commit() else: # execute the analysis! context.invoke(config_case, case_id=case_id) context.invoke(link, case_id=case_id) context.invoke(panel, case_id=case_id) context.invoke( run, case_id=case_id, priority=priority, email=email, start_with=start_with, )
def deliver_analysis( context: CGConfig, case_id: Optional[str], ticket_id: Optional[int], delivery_type: List[str], dry_run: bool, ): """Deliver analysis files to customer inbox Files can be delivered either on case level or for all cases connected to a ticket. Any of those needs to be specified. """ if not (case_id or ticket_id): LOG.info("Please provide a case-id or ticket-id") return inbox: str = context.delivery_path if not inbox: LOG.info("Please specify the root path for where files should be delivered") return status_db: Store = context.status_db for delivery in delivery_type: deliver_api = DeliverAPI( store=status_db, hk_api=context.housekeeper_api, case_tags=PIPELINE_ANALYSIS_TAG_MAP[delivery]["case_tags"], sample_tags=PIPELINE_ANALYSIS_TAG_MAP[delivery]["sample_tags"], project_base_path=Path(inbox), delivery_type=delivery, ) deliver_api.set_dry_run(dry_run) cases: List[models.Family] = [] if case_id: case_obj: models.Family = status_db.family(case_id) if not case_obj: LOG.warning("Could not find case %s", case_id) return cases.append(case_obj) else: cases = status_db.get_cases_from_ticket(ticket_id=ticket_id).all() if not cases: LOG.warning("Could not find cases for ticket_id %s", ticket_id) return for case_obj in cases: deliver_api.deliver_files(case_obj=case_obj)
def mip_rna(context: click.Context): """Rare disease RNA workflow""" context.obj["db"] = Store(context.obj["database"]) hk_api = hk.HousekeeperAPI(context.obj) lims_api = lims.LimsAPI(context.obj) context.obj["tb"] = tb.TrailblazerAPI(context.obj) deliver = DeliverAPI( context.obj, hk_api=hk_api, lims_api=lims_api, case_tags=CASE_TAGS, sample_tags=SAMPLE_TAGS, ) context.obj["api"] = AnalysisAPI( db=context.obj["db"], hk_api=hk_api, tb_api=context.obj["tb"], lims_api=lims_api, deliver_api=deliver, ) context.obj["rna_api"] = MipAPI(context.obj["mip-rd-rna"]["script"], context.obj["mip-rd-rna"]["pipeline"])
def deliver_api(analysis_store, housekeeper_api, case_id, timestamp, helpers): """Fixture for deliver_api""" lims_mock = MockLims() hk_mock = housekeeper_api deliver_hk_bundle_data = { "name": case_id, "created": timestamp, "expires": timestamp, "files": [ { "path": "/mock/path", "archive": False, "tags": ["case-tag"] }, { "path": "/mock/path", "archive": False, "tags": ["sample-tag", "ADM1"] }, ], } helpers.ensure_hk_bundle(hk_mock, deliver_hk_bundle_data) _api = DeliverAPI( db=analysis_store, hk_api=hk_mock, lims_api=lims_mock, case_tags=["case-tag"], sample_tags=["sample-tag"], ) yield _api
def test_get_delivery_path(base_store: Store, real_housekeeper_api: HousekeeperAPI, project_dir: Path, case_id: str): """Test to create the delivery path""" # GIVEN a deliver api deliver_api = DeliverAPI( store=base_store, hk_api=real_housekeeper_api, case_tags=["case-tag"], sample_tags=["sample-tag"], project_base_path=project_dir, delivery_type="balsamic", ) customer_id = "cust000" ticket_id = 1234 deliver_api._set_customer_id(customer_id) deliver_api._set_ticket_id(ticket_id) # WHEN fetching the deliver path deliver_path = deliver_api.create_delivery_dir_path(case_name=case_id) # THEN assert that the path looks like expected assert deliver_path == project_dir / customer_id / "inbox" / str( ticket_id) / case_id
def upload(context, family_id, force_restart): """Upload results from analyses.""" click.echo(click.style("----------------- UPLOAD ----------------------")) context.obj["status"] = Store(context.obj["database"]) if family_id: family_obj = context.obj["status"].family(family_id) if not family_obj: message = f"family not found: {family_id}" click.echo(click.style(message, fg="red")) context.abort() if not family_obj.analyses: message = f"no analysis exists for family: {family_id}" click.echo(click.style(message, fg="red")) context.abort() analysis_obj = family_obj.analyses[0] if analysis_obj.uploaded_at is not None: message = f"analysis already uploaded: {analysis_obj.uploaded_at.date()}" click.echo(click.style(message, fg="red")) context.abort() if not force_restart and analysis_obj.upload_started_at is not None: if dt.datetime.now( ) - analysis_obj.upload_started_at > dt.timedelta(hours=24): raise AnalysisUploadError( f"The upload started at {analysis_obj.upload_started_at} " f"something went wrong, restart it with the --restart flag" ) message = f"analysis upload already started: {analysis_obj.upload_started_at.date()}" click.echo(click.style(message, fg="yellow")) return context.obj["housekeeper_api"] = hk.HousekeeperAPI(context.obj) context.obj["madeline_api"] = madeline.api.MadelineAPI(context.obj) context.obj["genotype_api"] = gt.GenotypeAPI(context.obj) context.obj["lims_api"] = lims.LimsAPI(context.obj) context.obj["tb_api"] = tb.TrailblazerAPI(context.obj) context.obj["chanjo_api"] = coverage_app.ChanjoAPI(context.obj) context.obj["deliver_api"] = DeliverAPI( context.obj, hk_api=context.obj["housekeeper_api"], lims_api=context.obj["lims_api"], case_tags=CASE_TAGS, sample_tags=SAMPLE_TAGS, ) context.obj["scout_api"] = scoutapi.ScoutAPI(context.obj) context.obj["analysis_api"] = AnalysisAPI( context.obj, hk_api=context.obj["housekeeper_api"], scout_api=context.obj["scout_api"], tb_api=context.obj["tb_api"], lims_api=context.obj["lims_api"], deliver_api=context.obj["deliver_api"], ) context.obj["report_api"] = ReportAPI( store=context.obj["status"], lims_api=context.obj["lims_api"], chanjo_api=context.obj["chanjo_api"], analysis_api=context.obj["analysis_api"], scout_api=context.obj["scout_api"], ) context.obj["scout_upload_api"] = UploadScoutAPI( hk_api=context.obj["housekeeper_api"], scout_api=context.obj["scout_api"], madeline_api=context.obj["madeline_api"], analysis_api=context.obj["analysis_api"], lims_api=context.obj["lims_api"], ) if context.invoked_subcommand is not None: return if not family_id: _suggest_cases_to_upload(context) context.abort() family_obj = context.obj["status"].family(family_id) analysis_obj = family_obj.analyses[0] if analysis_obj.uploaded_at is not None: message = f"analysis already uploaded: {analysis_obj.uploaded_at.date()}" click.echo(click.style(message, fg="yellow")) else: analysis_obj.upload_started_at = dt.datetime.now() context.obj["status"].commit() context.invoke(coverage, re_upload=True, family_id=family_id) context.invoke(validate, family_id=family_id) context.invoke(genotypes, re_upload=False, family_id=family_id) context.invoke(observations, case_id=family_id) context.invoke(scout, case_id=family_id) analysis_obj.uploaded_at = dt.datetime.now() context.obj["status"].commit() click.echo(click.style(f"{family_id}: analysis uploaded!", fg="green"))