Skip to content

Commit

Permalink
Additional APIs
Browse files Browse the repository at this point in the history
  • Loading branch information
williamputraintan committed Jul 18, 2024
1 parent d759538 commit 13c56d7
Show file tree
Hide file tree
Showing 6 changed files with 188 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ def reduce_multi_values_qor(key: str, values: List[str]):
)

def get_model_fields_query(self, qs: QuerySet, **kwargs) -> QuerySet:

def exclude_params(params):
for param in params:
kwargs.pop(param) if param in kwargs.keys() else None
Expand Down
50 changes: 47 additions & 3 deletions lib/workload/stateless/stacks/metadata-manager/app/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
from app.models import Subject, Specimen, Library


class SubjectSerializer(serializers.ModelSerializer):
class LibrarySerializer(serializers.ModelSerializer):
class Meta:
model = Subject
model = Library
fields = "__all__"


Expand All @@ -15,7 +15,51 @@ class Meta:
fields = "__all__"


class LibrarySerializer(serializers.ModelSerializer):
class SubjectSerializer(serializers.ModelSerializer):
class Meta:
model = Subject
fields = "__all__"


class SubjectFullSerializer(serializers.ModelSerializer):
"""
This is a full Subject serializer which include all the children's (specimen and library) related models
"""

class SpecimenLibrarySerializer(serializers.ModelSerializer):
"""
This is a full Specimen serializer which include the library model
"""
library_set = LibrarySerializer(many=True)

class Meta:
model = Specimen
fields = "__all__"

specimen_set = SpecimenLibrarySerializer(many=True)

class Meta:
model = Subject
fields = "__all__"


class LibraryFullSerializer(serializers.ModelSerializer):
"""
This is a full Library serializer which include the specimen and subject models
"""

class SpecimenSubjectSerializer(serializers.ModelSerializer):
"""
This is a full Specimen serializer which include the subject model
"""
subject = SubjectSerializer()

class Meta:
model = Specimen
fields = "__all__"

specimen = SpecimenSubjectSerializer(many=False)

class Meta:
model = Library
fields = "__all__"
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@
"level": "INFO",
"handlers": ["console"],
},

},
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,30 @@
REDOC_SETTINGS = {
"LAZY_RENDERING": False,
}

LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'formatters': {
'console': {
'format': '%(asctime)s %(name)-12s %(levelname)-8s %(message)s',
},
},
'handlers': {
'console': {
'class': 'logging.StreamHandler',
'formatter': 'console',
},
},
'loggers': {
'django.db.backends': {
'level': 'DEBUG',
'handlers': ['console'],
},
'django.db.backends.schema': {
'handlers': ['console'],
'level': 'INFO',
'propagate': False,
},
},
}
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,54 @@ def test_get_api(self):
0,
"No results are expected for unrecognized query parameter",
)

def test_library_full_model_api(self):
"""
python manage.py test app.tests.test_viewsets.LabViewSetTestCase.test_library_full_model_api
"""
path = 'library/full'

logger.info(f"check API path for '{path}'")
response = self.client.get(f"/{path}/")
self.assertEqual(response.status_code, 200,
"Ok status response is expected")

result_response = response.data["results"]
self.assertGreater(len(result_response), 0, "A result is expected")

logger.debug("Check if unique data has a single entry")
response = self.client.get(f"/{path}/?internal_id={LIBRARY_1['internal_id']}")
results_response = response.data["results"]
self.assertEqual(
len(results_response), 1, "Single result is expected for unique data"
)

logger.debug("check if specimen and library are linked")
self.assertEqual(result_response[0]['specimen']['internal_id'], SPECIMEN_1["internal_id"], )
self.assertEqual(result_response[0]['specimen']['subject']['internal_id'], SUBJECT_1["internal_id"], )

def test_subject_full_model_api(self):
"""
python manage.py test app.tests.test_viewsets.LabViewSetTestCase.test_subject_full_model_api
"""
path = 'subject/full'

logger.info(f"check API path for '{path}'")
response = self.client.get(f"/{path}/")
self.assertEqual(response.status_code, 200,
"Ok status response is expected")

result_response = response.data["results"]
self.assertGreater(len(result_response), 0, "A result is expected")

logger.debug("Check if unique data has a single entry")
response = self.client.get(f"/{path}/?internal_id={SUBJECT_1['internal_id']}")
results_response = response.data["results"]
self.assertEqual(
len(results_response), 1, "Single result is expected for unique data"
)

logger.debug("check if specimen and library are linked")
self.assertEqual(result_response[0]['specimen_set'][0]['internal_id'], SPECIMEN_1["internal_id"], )
self.assertEqual(result_response[0]['specimen_set'][0]['library_set'][0]['internal_id'],
LIBRARY_1["internal_id"], )
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
from drf_yasg import openapi
from drf_yasg.utils import swagger_auto_schema, swagger_serializer_method
from rest_framework import filters
from rest_framework.viewsets import ReadOnlyModelViewSet
from rest_framework.decorators import action
from rest_framework.response import Response

from app.models import Subject, Specimen, Library
from app.pagination import StandardResultsSetPagination
from app.serializers import SubjectSerializer, SpecimenSerializer, LibrarySerializer
from app.serializers import SubjectSerializer, SpecimenSerializer, LibrarySerializer, SubjectFullSerializer, \
LibraryFullSerializer


class SubjectViewSet(ReadOnlyModelViewSet):
Expand All @@ -17,6 +22,40 @@ class SubjectViewSet(ReadOnlyModelViewSet):
def get_queryset(self):
return Subject.objects.get_by_keyword(**self.request.query_params)

@action(detail=False, methods=['get'], url_path='full')
@swagger_auto_schema(responses={200: SubjectFullSerializer(many=False)}, manual_parameters=[
openapi.Parameter(
'library_internal_id',
openapi.IN_QUERY,
description="Filter the subjects that contain this particular internal_id in the Library model.",
type=openapi.TYPE_STRING,
), ])
def get_full_model_set(self, request):
query_params = self.request.query_params.copy()
qs = Subject.objects.prefetch_related("specimen_set__library_set").all().order_by("-id")

# Allow filtering by library_internal_id
library_internal_id = query_params.get("library_internal_id", None)
if library_internal_id:
query_params.pop("library_internal_id")
qs = qs.filter(specimen__library__internal_id=library_internal_id)

# Following same pattern with other filter where if unknown query params returns empty qs
qs = Subject.objects.get_model_fields_query(qs, **query_params)

page = self.paginate_queryset(qs)
serializer = SubjectFullSerializer(page, many=True)

return self.get_paginated_response(serializer.data)

@action(detail=True, methods=['get'], url_path='full')
@swagger_auto_schema(responses={200: SubjectFullSerializer(many=True)})
def get_full_model_detail(self, request, pk=None):
subject = Subject.objects.get(id=pk)
serializer = SubjectFullSerializer(subject)

return Response(serializer.data)


class SpecimenViewSet(ReadOnlyModelViewSet):
serializer_class = SpecimenSerializer
Expand All @@ -40,3 +79,24 @@ class LibraryViewSet(ReadOnlyModelViewSet):

def get_queryset(self):
return Library.objects.get_by_keyword(**self.request.query_params)

@action(detail=False, methods=['get'], url_path='full')
@swagger_auto_schema(responses={200: LibraryFullSerializer(many=True)})
def get_full_model_set(self, request):
qs = Library.objects.select_related("specimen__subject").all().order_by("-id")

# Allow filtering by the keys inside the library model
qs = Library.objects.get_model_fields_query(qs, **self.request.query_params)

page = self.paginate_queryset(qs)
serializer = LibraryFullSerializer(page, many=True)

return self.get_paginated_response(serializer.data)

@action(detail=True, methods=['get'], url_path='full')
@swagger_auto_schema(responses={200: LibraryFullSerializer(many=False)})
def get_full_model_detail(self, request, pk=None):
lib = Library.objects.get(id=pk)
serializer = LibraryFullSerializer(lib)

return Response(serializer.data)

0 comments on commit 13c56d7

Please sign in to comment.