Esempio n. 1
0
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
Esempio n. 2
0
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)
Esempio n. 3
0
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,
    )
Esempio n. 4
0
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
Esempio n. 5
0
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
Esempio n. 6
0
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
Esempio n. 7
0
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,
            )
Esempio n. 8
0
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)
Esempio n. 9
0
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"])
Esempio n. 10
0
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
Esempio n. 11
0
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
Esempio n. 12
0
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"))