Skip to content

Commit

Permalink
Adding REST API for small variants (#332)
Browse files Browse the repository at this point in the history
  • Loading branch information
holtgrewe committed Mar 4, 2022
1 parent bb8a9c1 commit 2697a9e
Show file tree
Hide file tree
Showing 41 changed files with 3,581 additions and 480 deletions.
3 changes: 1 addition & 2 deletions .github/workflows/ci.yml
Expand Up @@ -63,10 +63,9 @@ jobs:
uses: actions/checkout@v2
- name: install project Python dependencies
run: |
pip install wheel==0.36.2
pip install wheel==0.37.1
pip install -r requirements/local.txt
pip install -r requirements/test.txt
pip install -U 'celery >4.2'
pip freeze
- name: Build and run Vue app
run: |
Expand Down
5 changes: 4 additions & 1 deletion HISTORY.rst
Expand Up @@ -46,6 +46,7 @@ End-User Summary
- Fix issue with variant annotation export (#328)
- Allowing direct update of variant annotations and ACMG ratings on case annotations details (#344)
- Fixing problem with ACMD classifiction where VUS-3 was given but should be LB-2 (#359)
- Adding REST API for creating small variant queries (#332)

Full Change List
================
Expand Down Expand Up @@ -93,14 +94,16 @@ Full Change List
- Fixing CADD annotation (#319)
- Adding mitochondrial inheritance to case phenotype annotation (#325)
- Fix issue with variant annotation export (#328)
- Adding REST API versioning to (#333)
- Adding REST API versioning (#333)
- Adding more postgres versions to CI (#337)
- Make migrations compatible with Postgres 14 (#338)
- DgvSvs and DgvGoldStandardSvs are two different data sources now
- Adding deep linking into case details tab (#344)
- Allowing direct update of variant annotations and ACMG ratings on case annotations details (#344)
- Removing `display_hgmd_public_membership` (#363)
- Fixing problem with ACMD classifiction where VUS-3 was given but should be LB-2 (#359)
- Adding REST API for creating small variant queries (#332)
- Upgrading sodar-core dependency to 0.10.10

-------
v0.23.9
Expand Down
17 changes: 1 addition & 16 deletions beaconsite/tests/test_views.py
Expand Up @@ -2,23 +2,8 @@
from Crypto.PublicKey import RSA
from django.urls import reverse

from test_plus.test import TestCase

from beaconsite.models import Consortium, Site
from beaconsite.tests.factories import ConsortiumFactory, SiteFactory
from variants.tests.factories import ProjectFactory


class TestViewsBase(TestCase):
def setUp(self):
self.superuser = self.make_user("superuser")
self.superuser.is_superuser = True
self.superuser.is_staff = True
self.superuser.save()

self.project = ProjectFactory()
self.consortium = ConsortiumFactory()
self.site = SiteFactory(role=Site.LOCAL, state=Site.ENABLED)
from variants.tests.helpers import TestViewsBase


class TestIndexView(TestViewsBase):
Expand Down
10 changes: 5 additions & 5 deletions beaconsite/tests/test_views_api.py
@@ -1,15 +1,15 @@
import cattr
from django.shortcuts import reverse
from projectroles.tests.test_views_api import TestAPIViewsBase

from variants.tests.factories import SmallVariantFactory
from variants.tests.helpers import ApiViewTestBase
from .test_permissions_api import AcceptHeaderMixin
from ..models import Site
from .factories import ConsortiumWithLocalAndRemoteSiteFactory, ConsortiumAssignmentFactory
from ..models_api import BeaconAlleleRequest


class TestBeaconInfoApiView(AcceptHeaderMixin, TestAPIViewsBase):
class TestBeaconInfoApiView(AcceptHeaderMixin, ApiViewTestBase):
def setUp(self):
super().setUp()
self.consortium = ConsortiumWithLocalAndRemoteSiteFactory()
Expand All @@ -20,7 +20,7 @@ def setUp(self):
)

def test_get_info(self):
with self.login(self.user):
with self.login(self.superuser):
extra = self.get_accept_header(None, None)
response = self.client.get(reverse("beaconsite:beacon-api-info"), **extra)
self.assertEqual(response.status_code, 200)
Expand All @@ -47,7 +47,7 @@ def test_get_info(self):
)


class TestBeaconQueryApiView(AcceptHeaderMixin, TestAPIViewsBase):
class TestBeaconQueryApiView(AcceptHeaderMixin, ApiViewTestBase):
def setUp(self):
super().setUp()
self.consortium = ConsortiumWithLocalAndRemoteSiteFactory()
Expand All @@ -71,7 +71,7 @@ def test_query(self):
"%s=%s" % (k, v) for k, v in cattr.unstructure(self.beacon_allele_request).items()
)

with self.login(self.user):
with self.login(self.superuser):
extra = self.get_accept_header(None, None)
response = self.client.get(url, **extra)
self.assertEqual(response.status_code, 200)
Expand Down
10 changes: 8 additions & 2 deletions config/settings/base.py
Expand Up @@ -11,9 +11,11 @@
import logging
import os
import environ
import re
import sys

from dotenv import load_dotenv
from varfish import __version__ as varfish_version

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -594,8 +596,12 @@ def set_logging(level=None):
PROJECTROLES_ENABLE_SEARCH = not KIOSK_MODE
PROJECTROLES_SEARCH_PAGINATION = 5

SODAR_API_DEFAULT_VERSION = "0.1"
SODAR_API_MEDIA_TYPE = "application/vnd.bihealth.sodar+json"
SODAR_API_MEDIA_TYPE = "application/vnd.bihealth.varfish+json"
SODAR_API_DEFAULT_VERSION = re.match(r"^([0-9.]+)(?:[+|\-][\S]+)?$", varfish_version)[1]
SODAR_API_ALLOWED_VERSIONS = [
"0.23.9",
]


PROJECTROLES_SITE_MODE = env.str("PROJECTROLES_SITE_MODE", "TARGET")
PROJECTROLES_TARGET_CREATE = env.bool("PROJECTROLES_TARGET_CREATE", True)
Expand Down
62 changes: 62 additions & 0 deletions docs_manual/api_case.rst
@@ -0,0 +1,62 @@
.. _api_case:

================
Case & Query API
================

The REST API for case access and is described in this section.
Cases are not managed directly but through the :ref:`api_importer`.


----------
Versioning
----------

For accept header versioning, the following media type and version are expected in the current VarFish version:

.. code-block:: console
Accept: application/vnd.bihealth.varfish+json; version=0.23.9
-----------
Return Data
-----------

The return data for each request will be a JSON document unless otherwise
specified.

If return data is not specified in the documentation of an API view, it will
return the appropriate HTTP status code along with an optional ``detail`` JSON
field upon a successfully processed request.

For creation views, the ``sodar_uuid`` of the created object is returned
along with other object fields.

--------------
Query Settings
--------------

The query follows a :ref:`JSON Schema <api_json_schemas>`.

---------
API Views
---------

.. currentmodule:: variants.views_api

.. autoclass:: CaseListApiView

.. autoclass:: CaseRetrieveApiView

.. autoclass:: SmallVariantQueryApiView

.. autoclass:: SmallVariantQueryCreateApiView

.. autoclass:: SmallVariantQueryRetrieveApiView

.. autoclass:: SmallVariantQueryStatusApiView

.. autoclass:: SmallVariantQueryUpdateApiView

.. autoclass:: SmallVariantQueryFetchResultsApiView
27 changes: 27 additions & 0 deletions docs_manual/api_importer.rst
@@ -0,0 +1,27 @@
.. _api_importer:

===============
Case Import API
===============

The REST API for case import functionality is documented in this section.


---------
API Views
---------

.. note::

This is currently not implemented.


----------
Versioning
----------

For accept header versioning, the following media type and version are expected in the current VarFish version:

.. code-block:: console
Accept: application/vnd.bihealth.varfish+json; version=0.23.9
16 changes: 16 additions & 0 deletions docs_manual/api_json_schemas.rst
@@ -0,0 +1,16 @@
.. _api_json_schemas:

===========
JSON Schema
===========

This section contains the JSON schemas used in the VarFish Server API.

.. _api_json_schemas_case_query_v1:

--------------------
Case Query Schema V1
--------------------

.. jsonschema:: ../variants/schemas/case-query-v1.json

2 changes: 1 addition & 1 deletion docs_manual/api_overview.rst
Expand Up @@ -35,7 +35,7 @@ Add the token in the ``Authorization`` header of your HTTP request as follows:
Versioning
==========

The SODAR REST API uses accept header versioning.
The VarFish REST API uses accept header versioning.
While specifying the desired API version in your HTTP requests is optional, it is **strongly recommended**.
This ensures you will get the appropriate return data and avoid running into unexpected incompatibility issues.

Expand Down
26 changes: 26 additions & 0 deletions docs_manual/api_projectroles.rst
@@ -0,0 +1,26 @@
.. _api_projectroles:

======================
Project Management API
======================

The REST API for project access and management operations is described in this section.


---------
API Views
---------

The project management API is provided by the SODAR Core package.
The documentation for the REST API views can be found in the `SODAR Core Documentation <https://sodar-core.readthedocs.io/en/latest/app_projectroles_api_rest.html#api-views>`_.


----------
Versioning
----------

For accept header versioning, the following media type and version are expected in the current VarFish version:

.. code-block:: console
Accept: application/vnd.bihealth.sodar-core+json; version=0.10.7
8 changes: 6 additions & 2 deletions docs_manual/conf.py
Expand Up @@ -12,7 +12,11 @@
import os
import sys

sys.path.insert(0, os.path.abspath("."))
import django

sys.path.insert(0, os.path.abspath("../"))
os.environ["DJANGO_SETTINGS_MODULE"] = "config.settings.local"
django.setup()

# Get the project root dir, which is the parent dir of this
cwd = os.getcwd()
Expand All @@ -37,7 +41,7 @@

# Add any Sphinx extension module names here, as strings. They can be extensions
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
extensions = []
extensions = ["sphinx.ext.autodoc", "sphinx.ext.viewcode", "sphinx-jsonschema"]

# Add any paths that contain templates here, relative to this directory.
templates_path = ["_templates"]
Expand Down
4 changes: 4 additions & 0 deletions docs_manual/index.rst
Expand Up @@ -129,6 +129,10 @@ Currently, the main focus is on small/sequence variants called from high-througp
:titlesonly:

api_overview
api_projectroles
api_importer
api_case
api_json_schemas

.. raw:: latex

Expand Down
10 changes: 5 additions & 5 deletions geneinfo/tests/_test_views.py
Expand Up @@ -79,23 +79,23 @@ class TestGeneView(TestViewBase):
setup_case_in_db = fixture_setup_geneinfo

def test_geneinfo_ensembl(self):
with self.login(self.user):
with self.login(self.superuser):
project = Project.objects.first()
response = self.client.get(
reverse("geneinfo:gene", kwargs={"project": project.sodar_uuid, "gene_id": "ENSG1"})
)
self.assertEquals(response.status_code, 200)

def test_geneinfo_refseq(self):
with self.login(self.user):
with self.login(self.superuser):
project = Project.objects.first()
response = self.client.get(
reverse("geneinfo:gene", kwargs={"project": project.sodar_uuid, "gene_id": "123"})
)
self.assertEquals(response.status_code, 200)

def test_geneinfo_render_complete(self):
with self.login(self.user):
with self.login(self.superuser):
project = Project.objects.first()
response = self.client.get(
reverse("geneinfo:gene", kwargs={"project": project.sodar_uuid, "gene_id": "456"})
Expand All @@ -112,7 +112,7 @@ def test_geneinfo_render_complete(self):
self.assertEquals(response.context["hgncomim"]["2"][0]["hpo_id"], "HP:002")

def test_geneinfo_render_empty(self):
with self.login(self.user):
with self.login(self.superuser):
project = Project.objects.first()
response = self.client.get(
reverse("geneinfo:gene", kwargs={"project": project.sodar_uuid, "gene_id": "000"})
Expand All @@ -129,7 +129,7 @@ class TestGeneViewIncomplete(TestViewBase):
setup_case_in_db = fixture_setup_geneinfo_incomplete

def test_geneinfo_render_missing_omim(self):
with self.login(self.user):
with self.login(self.superuser):
project = Project.objects.first()
response = self.client.get(
reverse("geneinfo:gene", kwargs={"project": project.sodar_uuid, "gene_id": "456"})
Expand Down

0 comments on commit 2697a9e

Please sign in to comment.