Skip to content

Commit

Permalink
Refactor flow cells endpoint (#3549)
Browse files Browse the repository at this point in the history
  • Loading branch information
seallard authored Aug 19, 2024
1 parent e60dc6a commit 239fdba
Show file tree
Hide file tree
Showing 14 changed files with 110 additions and 74 deletions.
4 changes: 4 additions & 0 deletions cg/exc.py
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,10 @@ class MissingMetrics(CgError):
"""Exception raised when mandatory metrics are missing."""


class MissingSequencingMetricsError(CgError):
"""Exception raised when sequencing metrics are missing."""


class ArchiveJobFailedError(CgError):
"""Exception raised when an archival or retrieval job has failed."""

Expand Down
2 changes: 1 addition & 1 deletion cg/server/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@

from cg.server import admin, ext, invoices
from cg.server.app_config import app_config
from cg.server.endpoints.flow_cells.flow_cells import FLOW_CELLS_BLUEPRINT
from cg.server.endpoints.analyses import ANALYSES_BLUEPRINT
from cg.server.endpoints.flow_cells import FLOW_CELLS_BLUEPRINT
from cg.server.endpoints.orders import ORDERS_BLUEPRINT
from cg.server.endpoints.applications import APPLICATIONS_BLUEPRINT
from cg.server.endpoints.cases import CASES_BLUEPRINT
Expand Down
29 changes: 0 additions & 29 deletions cg/server/endpoints/flow_cells.py

This file was deleted.

File renamed without changes.
27 changes: 27 additions & 0 deletions cg/server/endpoints/flow_cells/error_handler.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
from http import HTTPStatus
import logging
from functools import wraps
from flask import jsonify

from cg.store.exc import EntryNotFoundError

LOG = logging.getLogger(__name__)


def handle_endpoint_errors(func):

@wraps(func)
def wrapper(*args, **kwargs):
try:
return func(*args, **kwargs)
except EntryNotFoundError as error:
LOG.error(error)
return jsonify(error=str(error)), HTTPStatus.NOT_FOUND
except Exception as error:
LOG.error(f"Unexpected error in flow cells endpoint: {error}")
return (
jsonify(error="An error occurred while processing your request."),
HTTPStatus.INTERNAL_SERVER_ERROR,
)

return wrapper
16 changes: 16 additions & 0 deletions cg/server/endpoints/flow_cells/flow_cells.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from flask import Blueprint, jsonify

from cg.server.endpoints.flow_cells.error_handler import handle_endpoint_errors
from cg.server.endpoints.utils import before_request
from cg.server.ext import flow_cell_service
from cg.services.sample_run_metrics_service.dtos import SequencingMetrics

FLOW_CELLS_BLUEPRINT = Blueprint("flowcells", __name__, url_prefix="/api/v1")
FLOW_CELLS_BLUEPRINT.before_request(before_request)


@FLOW_CELLS_BLUEPRINT.route("/flowcells/<flow_cell_name>/sequencing_metrics", methods=["GET"])
@handle_endpoint_errors
def get_sequencing_metrics(flow_cell_name: str):
metrics: list[SequencingMetrics] = flow_cell_service.get_metrics(flow_cell_name)
return jsonify([metric.model_dump() for metric in metrics])
7 changes: 6 additions & 1 deletion cg/server/ext.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
from cg.apps.osticket import OsTicket
from cg.apps.tb.api import TrailblazerAPI
from cg.services.delivery_message.delivery_message_service import DeliveryMessageService
from cg.services.sample_run_metrics_service.sample_run_metrics_service import (
SampleRunMetricsService,
)
from cg.services.orders.order_service.order_service import OrderService
from cg.services.orders.order_summary_service.order_summary_service import (
OrderSummaryService,
Expand Down Expand Up @@ -87,6 +90,8 @@ def init_app(self, app):
summary_service = OrderSummaryService(store=db, analysis_client=analysis_client)
order_service = OrderService(store=db, status_service=summary_service)
sample_service = SampleService(db)
flow_cell_service = SampleRunMetricsService(db)
order_submitter_registry: OrderSubmitterRegistry = setup_order_submitter_registry(
lims=lims, status_db=db
lims=lims,
status_db=db,
)
Empty file.
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
"""DTO for the sequencing metrics."""

from pydantic import BaseModel


class SequencingMetricsRequest(BaseModel):
class SequencingMetrics(BaseModel):
flow_cell_name: str
flow_cell_lane_number: int
sample_internal_id: str
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
from cg.services.sample_run_metrics_service.dtos import SequencingMetrics
from cg.services.sample_run_metrics_service.utils import create_metrics_dto
from cg.store.models import IlluminaSequencingRun
from cg.store.store import Store


class SampleRunMetricsService:
def __init__(self, store: Store):
self.store = store

def get_metrics(self, flow_cell_name: str) -> list[SequencingMetrics]:
run: IlluminaSequencingRun = self.store.get_illumina_sequencing_run_by_device_internal_id(
flow_cell_name
)
return create_metrics_dto(run.sample_metrics) if run else []
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
from cg.server.dto.sequencing_metrics.sequencing_metrics_request import SequencingMetricsRequest
from cg.services.sample_run_metrics_service.dtos import SequencingMetrics
from cg.store.models import IlluminaSampleSequencingMetrics


def parse_metrics_into_request(
metrics: list[IlluminaSampleSequencingMetrics],
) -> list[SequencingMetricsRequest]:
"""Parse sequencing metrics into a request."""
parsed_metrics: list[SequencingMetricsRequest] = []
def create_metrics_dto(
metrics: list[IlluminaSampleSequencingMetrics] | None,
) -> list[SequencingMetrics]:

if not metrics:
return []

parsed_metrics = []

for metric in metrics:
parsed_metric = SequencingMetricsRequest(
parsed_metric = SequencingMetrics(
flow_cell_name=metric.instrument_run.device.internal_id,
flow_cell_lane_number=metric.flow_cell_lane,
sample_internal_id=metric.sample.internal_id,
Expand Down
33 changes: 0 additions & 33 deletions tests/models/server/dto/test_sequencing_metrics.py

This file was deleted.

13 changes: 13 additions & 0 deletions tests/services/sample_run_metrics_service/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import pytest

from cg.services.sample_run_metrics_service.sample_run_metrics_service import (
SampleRunMetricsService,
)
from cg.store.store import Store


@pytest.fixture
def sample_run_metrics_service(
store_with_illumina_sequencing_data: Store,
) -> SampleRunMetricsService:
return SampleRunMetricsService(store_with_illumina_sequencing_data)
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from cg.services.sample_run_metrics_service.sample_run_metrics_service import (
SampleRunMetricsService,
)


def test_get_metrics_for_flow_cell(
sample_run_metrics_service: SampleRunMetricsService,
novaseq_x_flow_cell_id: str,
):
# GIVEN an existing flow cell with sequencing metrics

# WHEN fetching the metrics for the flow cell
metrics = sample_run_metrics_service.get_metrics(novaseq_x_flow_cell_id)

# THEN the metrics should be returned
assert metrics

0 comments on commit 239fdba

Please sign in to comment.