diff --git a/backend/metagenedb/api/catalog/filters/__init__.py b/backend/metagenedb/api/catalog/filters/__init__.py index 7ad133f24e7f07826f36d824ff4deb3cc316906c..b00f6025e6c9a29c162f3ad5a40d5d2eff38b585 100644 --- a/backend/metagenedb/api/catalog/filters/__init__.py +++ b/backend/metagenedb/api/catalog/filters/__init__.py @@ -1,3 +1,3 @@ -from .function import FunctionFilter # noqa +from .function import EggNOGFilter, FunctionFilter # noqa from .gene import GeneFilter # noqa from .taxonomy import TaxonomyFilter # noqa diff --git a/backend/metagenedb/api/catalog/filters/function.py b/backend/metagenedb/api/catalog/filters/function.py index 963f19d9cc08ef10313035e0ee581a61e20708ca..735fdc28635f884abf41b58af8ece5420adcecb3 100644 --- a/backend/metagenedb/api/catalog/filters/function.py +++ b/backend/metagenedb/api/catalog/filters/function.py @@ -1,5 +1,5 @@ from django_filters import rest_framework as filters -from metagenedb.apps.catalog.models import Function +from metagenedb.apps.catalog.models import Function, EggNOG class FunctionFilter(filters.FilterSet): @@ -7,3 +7,10 @@ class FunctionFilter(filters.FilterSet): class Meta: model = Function fields = ['source'] + + +class EggNOGFilter(filters.FilterSet): + + class Meta: + model = EggNOG + fields = ['version'] diff --git a/backend/metagenedb/api/catalog/qparams_validators/function.py b/backend/metagenedb/api/catalog/qparams_validators/function.py index b95b016c6184beec2ad1cab37e200dc74402f751..80a17dc73dd0ca4e01672928a2051cee356ff7ff 100644 --- a/backend/metagenedb/api/catalog/qparams_validators/function.py +++ b/backend/metagenedb/api/catalog/qparams_validators/function.py @@ -1,7 +1,20 @@ from marshmallow import fields +from marshmallow.validate import OneOf +from metagenedb.apps.catalog import models from metagenedb.common.django_default.qparams_validators import PaginatedQueryParams +SELECTED_SOURCE = [i[0] for i in models.Function.SOURCE_CHOICES] +EGGNOG_VERSIONS = [i[0] for i in models.EggNOG.VERSION_CHOICES] + class FunctionQueryParams(PaginatedQueryParams): + source = fields.String(validate=OneOf(choices=SELECTED_SOURCE)) + + +class KeggQueryParams(PaginatedQueryParams): detailed = fields.Boolean() + + +class EggNOGQueryParams(PaginatedQueryParams): + version = fields.String(validate=OneOf(choices=EGGNOG_VERSIONS)) diff --git a/backend/metagenedb/api/catalog/views/bulk_viewset.py b/backend/metagenedb/api/catalog/views/base.py similarity index 98% rename from backend/metagenedb/api/catalog/views/bulk_viewset.py rename to backend/metagenedb/api/catalog/views/base.py index ce82fa93b46e3582074e5aac9480d521ab0a79db..62e2f0e35e1fe3b10213f55ef10cb119f814a80c 100644 --- a/backend/metagenedb/api/catalog/views/bulk_viewset.py +++ b/backend/metagenedb/api/catalog/views/base.py @@ -7,16 +7,51 @@ from metagenedb.common.django_default.permissions import ListAndRetrieveAll from metagenedb.common.django_default.qparams_validators import PaginatedQueryParams -class BulkViewSet(ModelViewSet): +class QParamsValidationViewSet(ModelViewSet): query_params_parser = PaginatedQueryParams + + def _get_qparams(self, raw_query_params): + return self.query_params_parser().load(raw_query_params) + + def list(self, request, *args, **kwargs): + try: + query_params = self._get_qparams(request.query_params) # noqa + except ValidationError as validation_error: + error_message = validation_error.normalized_messages() + error_message.update({ + 'allowed_query_params': ', '.join(self.query_params_parser().declared_fields.keys()) + }) + return Response(error_message, status=status.HTTP_422_UNPROCESSABLE_ENTITY) + queryset = self.filter_queryset(self.get_queryset()) + + page = self.paginate_queryset(queryset) + if page is not None: + serializer = self.get_serializer(page, many=True) + return self.get_paginated_response(serializer.data) + + serializer = self.get_serializer(queryset, many=True) + return Response(serializer.data) + + def retrieve(self, request, *args, **kwargs): + try: + query_params = self._get_qparams(request.query_params) # noqa + except ValidationError as validation_error: + error_message = validation_error.normalized_messages() + error_message.update({ + 'allowed_query_params': ', '.join(self.query_params_parser().declared_fields.keys()) + }) + return Response(error_message, status=status.HTTP_422_UNPROCESSABLE_ENTITY) + instance = self.get_object() + serializer = self.get_serializer(instance) + return Response(serializer.data) + + +class BulkViewSet(QParamsValidationViewSet): permission_classes = [ListAndRetrieveAll] def get_objects(self, instance_ids): return self.queryset.in_bulk(instance_ids, field_name=self.lookup_field) - def _get_qparams(self, raw_query_params): - return self.query_params_parser().load(raw_query_params) - def _created_payload(self, serializer, request): if isinstance(request.data, list): return { @@ -83,35 +118,3 @@ class BulkViewSet(ModelViewSet): self._updated_payload(create_serializer, update_serializer, request), status=status.HTTP_201_CREATED, headers=headers ) - - def list(self, request, *args, **kwargs): - try: - query_params = self._get_qparams(request.query_params) # noqa - except ValidationError as validation_error: - error_message = validation_error.normalized_messages() - error_message.update({ - 'allowed_query_params': ', '.join(self.query_params_parser().declared_fields.keys()) - }) - return Response(error_message, status=status.HTTP_422_UNPROCESSABLE_ENTITY) - queryset = self.filter_queryset(self.get_queryset()) - - page = self.paginate_queryset(queryset) - if page is not None: - serializer = self.get_serializer(page, many=True) - return self.get_paginated_response(serializer.data) - - serializer = self.get_serializer(queryset, many=True) - return Response(serializer.data) - - def retrieve(self, request, *args, **kwargs): - try: - query_params = self._get_qparams(request.query_params) # noqa - except ValidationError as validation_error: - error_message = validation_error.normalized_messages() - error_message.update({ - 'allowed_query_params': ', '.join(self.query_params_parser().declared_fields.keys()) - }) - return Response(error_message, status=status.HTTP_422_UNPROCESSABLE_ENTITY) - instance = self.get_object() - serializer = self.get_serializer(instance) - return Response(serializer.data) diff --git a/backend/metagenedb/api/catalog/views/function.py b/backend/metagenedb/api/catalog/views/function.py index 3dcb685f5a07bc7b5a6455ff4dafd09679656d60..3a968b1a2a151cac807af3e2d018ec5c98dff40d 100644 --- a/backend/metagenedb/api/catalog/views/function.py +++ b/backend/metagenedb/api/catalog/views/function.py @@ -5,13 +5,15 @@ from rest_framework.response import Response from rest_framework.status import HTTP_422_UNPROCESSABLE_ENTITY from rest_framework.viewsets import ModelViewSet -from metagenedb.api.catalog.filters import FunctionFilter -from metagenedb.api.catalog.qparams_validators.function import FunctionQueryParams +from metagenedb.api.catalog.filters import FunctionFilter, EggNOGFilter +from metagenedb.api.catalog.qparams_validators.function import ( + EggNOGQueryParams, FunctionQueryParams, KeggQueryParams +) from metagenedb.apps.catalog.models import EggNOG, Function, KeggOrthology from metagenedb.apps.catalog.serializers import EggNOGSerializer, FunctionSerializer, KeggOrthologySerializer from metagenedb.common.utils.external_api.togows import GetFunctionExternalInfo -from .bulk_viewset import BulkViewSet +from .base import BulkViewSet, QParamsValidationViewSet logger = logging.getLogger(__name__) @@ -22,13 +24,14 @@ class FunctionViewSet(BulkViewSet): serializer_class = FunctionSerializer lookup_field = 'function_id' filterset_class = FunctionFilter + query_params_parser = FunctionQueryParams -class KeggOrthologyViewSet(ModelViewSet): +class KeggOrthologyViewSet(QParamsValidationViewSet): queryset = KeggOrthology.objects.all() serializer_class = KeggOrthologySerializer lookup_field = 'function_id' - query_params_parser = FunctionQueryParams + query_params_parser = KeggQueryParams def _get_external_info(self, db_data): detailed_info_retriever = GetFunctionExternalInfo(db_data['function_id'], 'kegg') @@ -57,7 +60,9 @@ class KeggOrthologyViewSet(ModelViewSet): return Response(returned_data) -class EggNOGViewSet(ModelViewSet): +class EggNOGViewSet(QParamsValidationViewSet): queryset = EggNOG.objects.all() serializer_class = EggNOGSerializer lookup_field = 'function_id' + filterset_class = EggNOGFilter + query_params_parser = EggNOGQueryParams diff --git a/backend/metagenedb/api/catalog/views/gene.py b/backend/metagenedb/api/catalog/views/gene.py index 8a2aadff69c1861971d9aac9c9acbed4804719e3..6189e74b961559b018ae22e43ce7d131752b456d 100644 --- a/backend/metagenedb/api/catalog/views/gene.py +++ b/backend/metagenedb/api/catalog/views/gene.py @@ -14,7 +14,7 @@ from metagenedb.api.catalog.filters import GeneFilter from metagenedb.api.catalog.qparams_validators.gene import GeneLengthQueryParams, GeneQueryParams, TaxCountQueryParams from metagenedb.apps.catalog.serializers import GeneSerializer -from .bulk_viewset import BulkViewSet +from .base import BulkViewSet class DocGeneLength(object): diff --git a/backend/metagenedb/api/catalog/views/taxonomy.py b/backend/metagenedb/api/catalog/views/taxonomy.py index e6dc49cc7cc68379f4a3358e4e697c8797c1affa..c32363afe77e2b9beffdc82828347a2b1dcdf919 100644 --- a/backend/metagenedb/api/catalog/views/taxonomy.py +++ b/backend/metagenedb/api/catalog/views/taxonomy.py @@ -7,7 +7,7 @@ from metagenedb.api.catalog.qparams_validators.taxonomy import TaxonomyQueryPara from metagenedb.apps.catalog.models import Taxonomy from metagenedb.apps.catalog.serializers import TaxonomySerializer -from .bulk_viewset import BulkViewSet +from .base import BulkViewSet class TaxonomyViewSet(BulkViewSet): diff --git a/backend/metagenedb/api/catalog/views/test_bulk_viewset.py b/backend/metagenedb/api/catalog/views/test_base.py similarity index 100% rename from backend/metagenedb/api/catalog/views/test_bulk_viewset.py rename to backend/metagenedb/api/catalog/views/test_base.py