Skip to content
6 changes: 3 additions & 3 deletions beagle_etl/jobs/metadb_jobs.py
Original file line number Diff line number Diff line change
Expand Up @@ -180,17 +180,17 @@ def request_update_notification(request_id):


@shared_task
def new_request(message_id):
def new_request(message_id, force_import=False):
message = SMILEMessage.objects.get(id=message_id)

try:
data = RequestMetadata.from_dict(json.loads(message.message))
data = RequestMetadata.from_dict(json.loads(message.message), force_import=force_import)
except Exception as e:
message.add_log(str(e))
message.failed()
return

if not data.isCmoRequest:
if not data.isCmoRequest and not force_import:
# Non CmoRequests not supported
logger.info(f"Request {data.igoRequestId} is not CMO Request")
message.add_log(f"Request {data.igoRequestId} is not CMO Request")
Expand Down
4 changes: 2 additions & 2 deletions beagle_etl/smile_message/objects/request_object.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,15 +41,15 @@ class RequestMetadata:
pooledNormals: Optional[List[str]] = None

@classmethod
def from_dict(cls, data: Dict[str, Any]) -> "RequestMetadata":
def from_dict(cls, data: Dict[str, Any], force_import: bool = False) -> "RequestMetadata":
"""Deserialize from dictionary."""
# Handle nested status
status_data = data.get("status", {})
status = RequestStatus(**status_data) if status_data else RequestStatus(False, "{}")

# Handle nested samples
samples_data = data.get("samples", [])
samples = [SampleMetadata.from_dict(sample) for sample in samples_data]
samples = [SampleMetadata.from_dict(sample, force_import=force_import) for sample in samples_data]

# Handle delivery date conversion
delivery_date = None
Expand Down
8 changes: 6 additions & 2 deletions beagle_etl/smile_message/objects/sample_object.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import re
import logging
from dataclasses import dataclass
from dataclasses import dataclass, field
from typing import List, Optional, Dict, Any
from django.conf import settings
from beagle_etl.exceptions import (
Expand Down Expand Up @@ -217,9 +217,10 @@ class SampleMetadata:
tubeId: Optional[str] = None
cfDNA2dBarcode: Optional[str] = None
cmoInfoIgoId: Optional[str] = None
skip_validation: bool = field(default=False, compare=False, repr=False)

@classmethod
def from_dict(cls, data: Dict[str, Any]) -> "SampleMetadata":
def from_dict(cls, data: Dict[str, Any], force_import: bool = False) -> "SampleMetadata":
"""Deserialize SampleMetadata from dictionary."""
# Handle nested status
status_data = data.get("status", {})
Expand Down Expand Up @@ -275,9 +276,12 @@ def from_dict(cls, data: Dict[str, Any]) -> "SampleMetadata":
sampleAliases=sample_aliases,
patientAliases=patient_aliases,
additionalProperties=data.get("additionalProperties", {}),
skip_validation=force_import,
)

def __post_init__(self):
if self.skip_validation:
return
self._validate_primary_id()
required = PANEL_REQUIRED_FIELDS.get(self.genePanel, DEFAULT_REQUIRED_FIELDS)
self._validate_required_fields(required)
Expand Down
3 changes: 2 additions & 1 deletion file_system/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from file_system.views.file_type_view import FileTypeView
from file_system.views.sample_view import SampleViewSet
from file_system.views.patient_view import PatientViewSet
from file_system.views.request_view import RequestViewSet
from file_system.views.request_view import RequestViewSet, ForceImportRequestView
from file_system.views.distribution_view import DistributionView
from file_system.views.sample_view import SampleFullViewSet

Expand All @@ -33,4 +33,5 @@
path("batch-patch-files", BatchPatchFiles.as_view()),
path("copy-files", CopyFilesView.as_view()),
path("manifest/", Manifest.as_view()),
path("request/force-import/<str:request_id>/", ForceImportRequestView.as_view()),
Comment thread
buehlere marked this conversation as resolved.
Outdated
]
28 changes: 27 additions & 1 deletion file_system/views/request_view.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
from rest_framework import mixins
from django.conf import settings
from rest_framework import mixins, status
from rest_framework.response import Response
from rest_framework.views import APIView
from file_system.models import Request
from file_system.serializers import RequestSerializer
from rest_framework.viewsets import GenericViewSet
from rest_framework.permissions import IsAuthenticated
from rest_framework.filters import SearchFilter
from beagle_etl.models import SMILEMessage
from beagle_etl.jobs.metadb_jobs import new_request


class RequestViewSet(
Expand All @@ -16,3 +21,24 @@ class RequestViewSet(

def get_serializer_class(self):
return RequestSerializer


class ForceImportRequestView(APIView):
permission_classes = (IsAuthenticated,)

def post(self, _request, request_id):
message = (
SMILEMessage.objects.filter(request_id=request_id, topic=settings.METADB_NATS_NEW_REQUEST)
.order_by("-created_date")
.first()
)
if not message:
return Response(
{"detail": f"No new-request SMILEMessage found for request_id {request_id}."},
status=status.HTTP_404_NOT_FOUND,
)
new_request(str(message.id), force_import=True)
Comment thread
buehlere marked this conversation as resolved.
Outdated
return Response(
{"detail": f"Force import complete for request {request_id} (message {message.id})."},
status=status.HTTP_200_OK,
)
Loading