Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore!: remove to-be-unused /overview endpoint #557

Merged
merged 1 commit into from
Jan 9, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 10 additions & 58 deletions chord_metadata_service/restapi/api_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,16 @@

from adrf.decorators import api_view
from bento_lib.responses import errors
from django.db.models import QuerySet
from drf_spectacular.utils import extend_schema, inline_serializer
from rest_framework import serializers, status
from rest_framework import status
from rest_framework.decorators import permission_classes
from rest_framework.request import Request as DrfRequest
from rest_framework.response import Response

from chord_metadata_service.authz.helpers import get_data_type_query_permissions
from chord_metadata_service.authz.middleware import authz_middleware
from chord_metadata_service.authz.permissions import BentoAllowAny
from chord_metadata_service.authz.types import DataTypeDiscoveryPermissions
from chord_metadata_service.chord.data_types import DATA_TYPE_PHENOPACKET, DATA_TYPE_EXPERIMENT
from chord_metadata_service.discovery.scope import ValidatedDiscoveryScope, get_request_discovery_scope
from chord_metadata_service.discovery.scope import get_request_discovery_scope
from chord_metadata_service.experiments import models as experiments_models
from chord_metadata_service.experiments.summaries import dt_experiment_summary
from chord_metadata_service.metadata.service_info import get_service_info
Expand All @@ -37,54 +34,6 @@ async def service_info(_request: DrfRequest):
return Response(await get_service_info())


async def build_overview_response(
scope: ValidatedDiscoveryScope,
dt_permissions: DataTypeDiscoveryPermissions,
phenopackets: QuerySet | None = None,
experiments: QuerySet | None = None,
) -> Response:
phenopackets_summary, experiments_summary = await asyncio.gather(
dt_phenopacket_summary(scope, dt_permissions[DATA_TYPE_PHENOPACKET], phenopackets),
dt_experiment_summary(scope, dt_permissions[DATA_TYPE_EXPERIMENT], experiments),
)

return Response({
DATA_TYPE_PHENOPACKET: phenopackets_summary,
DATA_TYPE_EXPERIMENT: experiments_summary,
})


@extend_schema(
description="Overview of all Phenopackets in the database",
responses={
200: inline_serializer(
name='overview_response',
fields={
'phenopackets': serializers.IntegerField(),
'data_type_specific': serializers.JSONField(),
}
)
}
)
@api_view(["GET"])
@permission_classes([BentoAllowAny])
async def overview(request: DrfRequest):
"""
get:
Overview of all Phenopackets and experiments in the database - private endpoint
"""

# TODO: permissions based on project - this endpoint should be scrapped / completely rethought
# use node level discovery config for private overview
discovery_scope = ValidatedDiscoveryScope(project=None, dataset=None)

dt_permissions = await get_data_type_query_permissions(
request, [DATA_TYPE_PHENOPACKET, DATA_TYPE_EXPERIMENT], discovery_scope.as_authz_resource()
)

return await build_overview_response(discovery_scope, dt_permissions)


@api_view(["GET"])
@permission_classes([BentoAllowAny])
def extra_properties_schema_types(_request: DrfRequest):
Expand Down Expand Up @@ -132,9 +81,12 @@ async def search_overview(request: DrfRequest):
# If we don't have query:data on phenopackets, we cannot request a search overview
return Response(errors.forbidden_error("Forbidden"), status=status.HTTP_403_FORBIDDEN)

return await build_overview_response(
scope,
dt_permissions,
phenopackets=phenopackets,
experiments=experiments,
phenopackets_summary, experiments_summary = await asyncio.gather(
dt_phenopacket_summary(scope, dt_permissions[DATA_TYPE_PHENOPACKET], phenopackets),
dt_experiment_summary(scope, dt_permissions[DATA_TYPE_EXPERIMENT], experiments),
)

return Response({
DATA_TYPE_PHENOPACKET: phenopackets_summary,
DATA_TYPE_EXPERIMENT: experiments_summary,
})
40 changes: 0 additions & 40 deletions chord_metadata_service/restapi/tests/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,46 +73,6 @@ def setUp(self) -> None:
self.experiment_result = exp_m.ExperimentResult.objects.create(**exp_c.valid_experiment_result())
self.experiment.experiment_results.set([self.experiment_result])

def test_overview(self):
response = self.dt_authz_full_get('/api/overview')
response_obj = response.json()
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertIsInstance(response_obj, dict)
# phenopackets
phenopacket_res = response_obj['phenopacket']
self.assertEqual(phenopacket_res['count'], 2)
self.assertEqual(phenopacket_res['data_type_specific']['individuals']['count'], 2)
self.assertIsInstance(phenopacket_res['data_type_specific']['individuals']['age'], dict)
self.assertEqual(
phenopacket_res['data_type_specific']['individuals']['age'],
{**{'40': 1, '30': 1}, **phenopacket_res['data_type_specific']['individuals']['age']})
self.assertEqual(phenopacket_res['data_type_specific']['biosamples']['count'], 2)
self.assertEqual(phenopacket_res['data_type_specific']['phenotypic_features']['count'], 1)
self.assertEqual(phenopacket_res['data_type_specific']['diseases']['count'], 1)
# experiments
experiment_res = response_obj['experiment']
self.assertEqual(experiment_res['count'], 2)
self.assertEqual(
experiment_res['data_type_specific']['experiments']['study_type']['Whole genome Sequencing'], 2)
self.assertEqual(
experiment_res['data_type_specific']['experiments']['experiment_type']['DNA Methylation'], 2
)
self.assertEqual(experiment_res['data_type_specific']['experiments']['molecule']['total RNA'], 2)
self.assertEqual(experiment_res['data_type_specific']['experiments']['library_strategy']['Bisulfite-Seq'], 2)
self.assertEqual(experiment_res['data_type_specific']['experiments']['library_source']['Genomic'], 2)
self.assertEqual(experiment_res['data_type_specific']['experiments']['library_selection']['PCR'], 2)
self.assertEqual(experiment_res['data_type_specific']['experiments']['library_layout']['Single'], 2)
self.assertEqual(experiment_res['data_type_specific']['experiments']['extraction_protocol']['NGS'], 2)
self.assertEqual(experiment_res['data_type_specific']['experiment_results']['count'], 1)
self.assertEqual(experiment_res['data_type_specific']['experiment_results']['file_format']['VCF'], 1)
self.assertEqual(
experiment_res['data_type_specific']['experiment_results']['data_output_type']['Derived data'], 1
)
self.assertEqual(experiment_res['data_type_specific']['experiment_results']['usage']['download'], 1)
self.assertEqual(experiment_res['data_type_specific']['instruments']['count'], 1)
self.assertEqual(experiment_res['data_type_specific']['instruments']['platform']['Illumina'], 2)
self.assertEqual(experiment_res['data_type_specific']['instruments']['model']['Illumina HiSeq 4000'], 2)

def test_search_overview(self):
payload = json.dumps({'id': [ph_c.VALID_INDIVIDUAL_1['id']]})
response = self.dt_authz_full_post(reverse('search-overview'), data=payload, content_type='application/json')
Expand Down
3 changes: 1 addition & 2 deletions chord_metadata_service/restapi/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from chord_metadata_service.patients import api_views as individual_views
from chord_metadata_service.phenopackets import api_views as phenopacket_views
from chord_metadata_service.resources import api_views as resources_views
from chord_metadata_service.restapi.api_views import overview, search_overview, extra_properties_schema_types
from chord_metadata_service.restapi.api_views import search_overview, extra_properties_schema_types
from chord_metadata_service.restapi.routers import BatchListRouter

__all__ = ["router", "batch_router", "urlpatterns"]
Expand Down Expand Up @@ -61,7 +61,6 @@
path('extra_properties_schema_types', extra_properties_schema_types, name="extra-properties-schema-types"),

# overviews (statistics)
path('overview', overview, name="overview"),
path('search_overview', search_overview, name="search-overview"),

# public endpoints (no confidential information leak)
Expand Down
8 changes: 0 additions & 8 deletions docs/modules/overview_api.rst

This file was deleted.

Loading