Commit e2013000 authored by Kenzo-Hugo Hillion's avatar Kenzo-Hugo Hillion
Browse files

Make specific routes for eggnog and kegg

parent 66d3f01e
Pipeline #19621 passed with stages
in 2 minutes and 29 seconds
from django.conf.urls import url, include from django.conf.urls import url, include
from rest_framework.routers import DefaultRouter, DynamicRoute, Route from rest_framework.routers import DefaultRouter, DynamicRoute, Route
from metagenedb.api.catalog.views import FunctionViewSet, GeneViewSet, TaxonomyViewSet from metagenedb.api.catalog import views
class CustomRouter(DefaultRouter): class CustomRouter(DefaultRouter):
...@@ -52,9 +52,11 @@ class CustomRouter(DefaultRouter): ...@@ -52,9 +52,11 @@ class CustomRouter(DefaultRouter):
api_router = CustomRouter() api_router = CustomRouter()
api_router.register(r'functions', FunctionViewSet, basename='functions') api_router.register(r'functions', views.FunctionViewSet, basename='functions')
api_router.register(r'genes', GeneViewSet, basename='genes') api_router.register(r'kegg-orthologies', views.KeggOrthologyViewSet, basename='kegg-orthologies')
api_router.register(r'taxonomy', TaxonomyViewSet, basename='taxonomy') api_router.register(r'eggnogs', views.EggNogViewSet, basename='eggnogs')
api_router.register(r'genes', views.GeneViewSet, basename='genes')
api_router.register(r'taxonomy', views.TaxonomyViewSet, basename='taxonomy')
urlpatterns = [ urlpatterns = [
......
from .function import FunctionViewSet # noqa from .function import EggNogViewSet, KeggOrthologyViewSet, FunctionViewSet # noqa
from .gene import GeneViewSet # noqa from .gene import GeneViewSet # noqa
from .taxonomy import TaxonomyViewSet # noqa from .taxonomy import TaxonomyViewSet # noqa
...@@ -78,11 +78,6 @@ class BulkViewSet(ModelViewSet): ...@@ -78,11 +78,6 @@ class BulkViewSet(ModelViewSet):
update_serializer = self._get_update_serializer(instances, data_to_update) update_serializer = self._get_update_serializer(instances, data_to_update)
create_serializer = self._get_create_serializer(data_to_create) create_serializer = self._get_create_serializer(data_to_create)
# if getattr(instance, '_prefetched_objects_cache', None):
# # If 'prefetch_related' has been applied to a queryset, we need to
# # forcibly invalidate the prefetch cache on the instance.
# instance._prefetched_objects_cache = {}
headers = self.get_success_headers(update_serializer.data) headers = self.get_success_headers(update_serializer.data)
return Response( return Response(
self._updated_payload(create_serializer, update_serializer, request), self._updated_payload(create_serializer, update_serializer, request),
......
...@@ -3,11 +3,12 @@ import logging ...@@ -3,11 +3,12 @@ import logging
from marshmallow.exceptions import ValidationError from marshmallow.exceptions import ValidationError
from rest_framework.response import Response from rest_framework.response import Response
from rest_framework.status import HTTP_422_UNPROCESSABLE_ENTITY 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.filters import FunctionFilter
from metagenedb.api.catalog.qparams_validators.function import FunctionQueryParams from metagenedb.api.catalog.qparams_validators.function import FunctionQueryParams
from metagenedb.apps.catalog.models import Function from metagenedb.apps.catalog.models import EggNog, Function, KeggOrthology
from metagenedb.apps.catalog.serializers import FunctionSerializer from metagenedb.apps.catalog.serializers import EggNogSerializer, FunctionSerializer, KeggOrthologySerializer
from metagenedb.common.utils.external_api.togows import GetFunctionExternalInfo from metagenedb.common.utils.external_api.togows import GetFunctionExternalInfo
from .bulk_viewset import BulkViewSet from .bulk_viewset import BulkViewSet
...@@ -21,11 +22,16 @@ class FunctionViewSet(BulkViewSet): ...@@ -21,11 +22,16 @@ class FunctionViewSet(BulkViewSet):
serializer_class = FunctionSerializer serializer_class = FunctionSerializer
lookup_field = 'function_id' lookup_field = 'function_id'
filterset_class = FunctionFilter filterset_class = FunctionFilter
class KeggOrthologyViewSet(ModelViewSet):
queryset = KeggOrthology.objects.all()
serializer_class = KeggOrthologySerializer
lookup_field = 'function_id'
query_params_parser = FunctionQueryParams query_params_parser = FunctionQueryParams
def _get_external_info(self, db_data): def _get_external_info(self, db_data):
detailed_info_retriever = GetFunctionExternalInfo(db_data['function_id'], detailed_info_retriever = GetFunctionExternalInfo(db_data['function_id'], 'kegg')
db_data['source'])
try: try:
detailed_data = detailed_info_retriever.get_details() detailed_data = detailed_info_retriever.get_details()
except NotImplementedError as not_implemented_error: except NotImplementedError as not_implemented_error:
...@@ -36,7 +42,7 @@ class FunctionViewSet(BulkViewSet): ...@@ -36,7 +42,7 @@ class FunctionViewSet(BulkViewSet):
def retrieve(self, request, *args, **kwargs): def retrieve(self, request, *args, **kwargs):
try: try:
query_params = self._get_qparams(request.query_params) query_params = self.query_params_parser().load(request.query_params)
except ValidationError as validation_error: except ValidationError as validation_error:
error_message = validation_error.normalized_messages() error_message = validation_error.normalized_messages()
error_message.update({ error_message.update({
...@@ -49,3 +55,9 @@ class FunctionViewSet(BulkViewSet): ...@@ -49,3 +55,9 @@ class FunctionViewSet(BulkViewSet):
if query_params.get('detailed', False) is True: if query_params.get('detailed', False) is True:
returned_data = self._get_external_info(returned_data) returned_data = self._get_external_info(returned_data)
return Response(returned_data) return Response(returned_data)
class EggNogViewSet(ModelViewSet):
queryset = EggNog.objects.all()
serializer_class = EggNogSerializer
lookup_field = 'function_id'
...@@ -2,16 +2,19 @@ from rest_framework.test import APITestCase ...@@ -2,16 +2,19 @@ from rest_framework.test import APITestCase
import mock import mock
from metagenedb.apps.catalog.factory import FunctionFactory from metagenedb.apps.catalog.factory import EggNogFactory, KeggOrthologyFactory
from metagenedb.common.utils.mocks.metagenedb import MetageneDBCatalogFunctionAPIMock from metagenedb.common.utils.mocks.metagenedb import (
MetageneDBCatalogFunctionAPIMock, MetageneDBCatalogKeggOrthologyAPIMock
)
class TestFunctionViewSet(APITestCase): class TestKeggOrthologyViewSet(APITestCase):
def setUp(self): def setUp(self):
self.function_api = MetageneDBCatalogFunctionAPIMock(self.client) self.function_api = MetageneDBCatalogFunctionAPIMock(self.client)
self.kegg_function = FunctionFactory.create(source='kegg') self.kegg_ortho_api = MetageneDBCatalogKeggOrthologyAPIMock(self.client)
self.eggnog_function = FunctionFactory.create(source='eggnog') self.kegg_function = KeggOrthologyFactory.create()
self.eggnog_function = EggNogFactory.create()
def test_retrieve(self): def test_retrieve(self):
for function in [self.kegg_function, self.eggnog_function]: for function in [self.kegg_function, self.eggnog_function]:
...@@ -34,20 +37,5 @@ class TestFunctionViewSet(APITestCase): ...@@ -34,20 +37,5 @@ class TestFunctionViewSet(APITestCase):
} }
with mock.patch(class_to_mock) as MockGetFunctionExternalInfo: with mock.patch(class_to_mock) as MockGetFunctionExternalInfo:
MockGetFunctionExternalInfo.return_value.get_details.return_value = detailed_kegg MockGetFunctionExternalInfo.return_value.get_details.return_value = detailed_kegg
tested_dict = self.function_api.get(self.kegg_function.function_id, params=query_params) tested_dict = self.kegg_ortho_api.get(self.kegg_function.function_id, params=query_params)
self.assertDictEqual(tested_dict, detailed_kegg) self.assertDictEqual(tested_dict, detailed_kegg)
def test_retrieve_detailed_unavailable(self):
"""
eggnog is not available so it is a good example and should return the DB value.
"""
query_params = {
'detailed': 'true'
}
expected_function = {
'function_id': self.eggnog_function.function_id,
'name': self.eggnog_function.name,
'source': self.eggnog_function.source
}
tested_dict = self.function_api.get(self.eggnog_function.function_id, params=query_params)
self.assertDictEqual(tested_dict, expected_function)
from .function import FunctionFactory # noqa from .function import EggNogFactory, FunctionFactory, KeggOrthologyFactory # noqa
from .gene import GeneFactory # noqa from .gene import GeneFactory # noqa
from .taxonomy import TaxonomyFactory # noqa from .taxonomy import TaxonomyFactory # noqa
...@@ -10,9 +10,23 @@ faker = Factory.create() ...@@ -10,9 +10,23 @@ faker = Factory.create()
SELECTED_SOURCE = [i[0] for i in models.Function.SOURCE_CHOICES] SELECTED_SOURCE = [i[0] for i in models.Function.SOURCE_CHOICES]
class FunctionFactory(DjangoModelFactory): class BaseFunctionFactory(DjangoModelFactory):
function_id = FuzzyLowerText(prefix='function-', length=15)
class FunctionFactory(BaseFunctionFactory):
class Meta: class Meta:
model = models.Function model = models.Function
source = fuzzy.FuzzyChoice(SELECTED_SOURCE) source = fuzzy.FuzzyChoice(SELECTED_SOURCE)
function_id = FuzzyLowerText(prefix='function-', length=15) function_id = FuzzyLowerText(prefix='function-', length=15)
class EggNogFactory(BaseFunctionFactory):
class Meta:
model = models.EggNog
class KeggOrthologyFactory(BaseFunctionFactory):
class Meta:
model = models.KeggOrthology
from .function import FunctionSerializer # noqa from .function import EggNogSerializer, FunctionSerializer, KeggOrthologySerializer # noqa
from .gene import GeneSerializer # noqa from .gene import GeneSerializer # noqa
from .taxonomy import TaxonomySerializer # noqa from .taxonomy import TaxonomySerializer # noqa
from rest_framework import serializers from rest_framework import serializers
from metagenedb.apps.catalog.models import Function from metagenedb.apps.catalog.models import EggNog, Function, KeggOrthology
from .bulk_list import BulkListSerializer from .bulk_list import BulkListSerializer
...@@ -16,3 +16,32 @@ class FunctionSerializer(serializers.ModelSerializer): ...@@ -16,3 +16,32 @@ class FunctionSerializer(serializers.ModelSerializer):
model = Function model = Function
list_serializer_class = FunctionListSerializer list_serializer_class = FunctionListSerializer
fields = ('function_id', 'source', 'name') fields = ('function_id', 'source', 'name')
class EggNogListSerializer(BulkListSerializer):
class Meta:
model = EggNog
class EggNogSerializer(serializers.ModelSerializer):
class Meta:
model = EggNog
list_serializer_class = EggNogListSerializer
fields = ('function_id', 'name', 'functional_category')
class KeggOrthologyListSerializer(BulkListSerializer):
class Meta:
model = KeggOrthology
class KeggOrthologySerializer(serializers.ModelSerializer):
ec_number = serializers.CharField(required=False)
class Meta:
model = KeggOrthology
list_serializer_class = KeggOrthologyListSerializer
fields = ('function_id', 'name', 'long_name', 'ec_number')
...@@ -84,3 +84,11 @@ class MetageneDBCatalogTaxonomyAPIMock(MetageneDBAPIMock): ...@@ -84,3 +84,11 @@ class MetageneDBCatalogTaxonomyAPIMock(MetageneDBAPIMock):
class MetageneDBCatalogFunctionAPIMock(MetageneDBAPIMock): class MetageneDBCatalogFunctionAPIMock(MetageneDBAPIMock):
KEY_ID = 'function_id' KEY_ID = 'function_id'
REVERSE_PATH = 'catalog:v1:functions' REVERSE_PATH = 'catalog:v1:functions'
class MetageneDBCatalogKeggOrthologyAPIMock(MetageneDBCatalogFunctionAPIMock):
REVERSE_PATH = 'catalog:v1:kegg-orthologies'
class MetageneDBCatalogEggNogAPIMock(MetageneDBCatalogFunctionAPIMock):
REVERSE_PATH = 'catalog:v1:eggnogs'
...@@ -5,7 +5,7 @@ import requests ...@@ -5,7 +5,7 @@ import requests
import sys import sys
import time import time
from bioapi import MetageneDBCatalogFunctionAPI from bioapi import MetageneDBCatalogKeggOrthologyAPI
from metagenedb.common.utils.chunks import generate_chunks from metagenedb.common.utils.chunks import generate_chunks
from metagenedb.common.utils.parsers import KEGGLineParser from metagenedb.common.utils.parsers import KEGGLineParser
...@@ -17,7 +17,7 @@ KEGG_KO_LIST_API = "http://rest.kegg.jp/list/ko" ...@@ -17,7 +17,7 @@ KEGG_KO_LIST_API = "http://rest.kegg.jp/list/ko"
class ImportKEGGKO(object): class ImportKEGGKO(object):
METAGENEDB_FUNCTION_API = MetageneDBCatalogFunctionAPI METAGENEDB_FUNCTION_API = MetageneDBCatalogKeggOrthologyAPI
ORM_SOURCE_KEY = 'source' ORM_SOURCE_KEY = 'source'
KEGG_SOURCE = 'kegg' KEGG_SOURCE = 'kegg'
......
...@@ -150,7 +150,7 @@ export default { ...@@ -150,7 +150,7 @@ export default {
this.request_done = true; this.request_done = true;
return; return;
} }
axios.get('/api/catalog/v1/functions/' + this.kegg_id + '?detailed=true', { axios.get('/api/catalog/v1/kegg-orthologies/' + this.kegg_id + '?detailed=true', {
headers: { headers: {
Accept: 'application/json', Accept: 'application/json',
}, },
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment