1
0
Fork 0

Updates for newer API / django rest framework

Update to Django Rest Framework 3.12.2 with improved schema generation.

However, it is still not quite complete for what we need (and what we currently postprocess for). Instead of postprocessing, this commit introduces our own extended generator to add the missing fields.

Once this is vetted good, we can remove contrib/postprocess-openapi-schema.py 

Also added better comments to api/views.py which will end up in schema docs

Signed-off-by: Corey Shields <cshields@gmail.com>
spacecruft
Corey Shields 2020-12-28 11:39:26 -05:00
parent cc422353e7
commit 83f9b07e21
6 changed files with 89 additions and 28 deletions

View File

@ -28,12 +28,8 @@ schema:
- >-
./manage.py generateschema
--title "SatNOGS DB"
--description "SatNOGS DB is a transmitter suggestions and crowd-sourcing app." |
./contrib/postprocess-openapi-schema.py
--expand-aliases
--api-version '1'
--server-url 'https://db.satnogs.org'
--enable-apikey-auth -
--description "SatNOGS DB is a transmitter suggestions and crowd-sourcing app."
--generator_class "db.api.generators.SchemaGenerator"
> satnogs-db-api-client/api-schema.yml
artifacts:
expire_in: 1 week

View File

@ -0,0 +1,46 @@
"""
NOTE this is a patch to add missing functionality from DRF's openapi implementation
and should be revisited periodically as new functionality is implemented upstream.
refer to https://github.com/encode/django-rest-framework/pull/7516
"""
from rest_framework.schemas.openapi import SchemaGenerator as OpenAPISchemaGenerator
class SchemaGenerator(OpenAPISchemaGenerator):
"""
Returns an extended schema that includes some missing fields from the
upstream OpenAPI implementation
"""
def get_schema(self, request=None, public=False):
schema = super().get_schema(request, public)
schema['info']['version'] = '1.0'
# temporarily add servers until the following is fixed
# https://github.com/encode/django-rest-framework/issues/7631
schema['servers'] = [
{
'url': 'http://localhost:8000',
'description': 'local dev'
}, {
'url': 'https://db.satnogs.org',
'description': 'production'
}
]
# temporarily add securitySchemes until implemented upstream
if 'securitySchemes' not in schema['components']:
schema['components']['securitySchemes'] = {
'ApiKeyAuth': {
'type': 'apiKey',
'in': 'header',
'name': 'Authorization'
}
}
# temporarily add default security object at top-level
if 'security' not in schema:
schema['security'] = [{'ApiKeyAuth': []}]
return schema

View File

@ -17,7 +17,7 @@ from db.base.tasks import update_satellite
class ModeView(viewsets.ReadOnlyModelViewSet): # pylint: disable=R0901
"""SatNOGS DB Mode API view class"""
"""View into the transmitter modulation modes in the SatNOGS DB database"""
renderer_classes = [
JSONRenderer, BrowsableAPIRenderer, JSONLDRenderer, BrowserableJSONLDRenderer
]
@ -26,7 +26,7 @@ class ModeView(viewsets.ReadOnlyModelViewSet): # pylint: disable=R0901
class SatelliteView(viewsets.ReadOnlyModelViewSet): # pylint: disable=R0901
"""SatNOGS DB Satellite API view class"""
"""View into the Satellite entities in the SatNOGS DB database"""
renderer_classes = [
JSONRenderer, BrowsableAPIRenderer, JSONLDRenderer, BrowserableJSONLDRenderer
]
@ -37,7 +37,10 @@ class SatelliteView(viewsets.ReadOnlyModelViewSet): # pylint: disable=R0901
class TransmitterView(viewsets.ReadOnlyModelViewSet): # pylint: disable=R0901
"""SatNOGS DB Transmitter API view class"""
"""
View into the Transmitter entities in the SatNOGS DB database.
Transmitters are inclusive of Transceivers and Transponders
"""
renderer_classes = [
JSONRenderer, BrowsableAPIRenderer, JSONLDRenderer, BrowserableJSONLDRenderer
]
@ -48,7 +51,9 @@ class TransmitterView(viewsets.ReadOnlyModelViewSet): # pylint: disable=R0901
class LatestTleSetView(viewsets.ReadOnlyModelViewSet): # pylint: disable=R0901
"""SatNOGS DB Tle API view class"""
"""
View into the most recent two-line elements (TLE) in the SatNOGS DB database
"""
renderer_classes = [JSONRenderer, BrowsableAPIRenderer]
queryset = LatestTleSet.objects.all().select_related('satellite').exclude(
latest_distributable__isnull=True
@ -82,7 +87,11 @@ class LatestTleSetView(viewsets.ReadOnlyModelViewSet): # pylint: disable=R0901
class TelemetryView( # pylint: disable=R0901
mixins.ListModelMixin, mixins.RetrieveModelMixin, mixins.CreateModelMixin,
viewsets.GenericViewSet):
"""SatNOGS DB Telemetry API view class"""
"""
View into the Telemetry objects in the SatNOGS DB database. Currently,
this table is inclusive of all data collected from satellite downlink
observations
"""
renderer_classes = [
JSONRenderer, BrowsableAPIRenderer, JSONLDRenderer, BrowserableJSONLDRenderer
]
@ -94,6 +103,11 @@ class TelemetryView( # pylint: disable=R0901
pagination_class = pagination.LinkedHeaderPageNumberPagination
def create(self, request, *args, **kwargs):
"""
Creates an frame of telemetry data from a satellite observation. See
https://www.pe0sat.vgnet.nl/download/Hidden/Dombrovski-SIDS-Simple-Downlink-Share-Convention.pdf
for a description of the original protocol.
"""
data = {}
norad_cat_id = request.data.get('noradID')
@ -149,7 +163,9 @@ class TelemetryView( # pylint: disable=R0901
class ArtifactView( # pylint: disable=R0901
mixins.ListModelMixin, mixins.RetrieveModelMixin, mixins.CreateModelMixin,
viewsets.GenericViewSet):
"""SatNOGS DB Artifact API view class"""
"""
Artifacts are objects collected in relation to a satellite observation.
"""
queryset = Artifact.objects.all()
filterset_class = filters.ArtifactViewFilter
permission_classes = [IsAuthenticated]
@ -163,7 +179,10 @@ class ArtifactView( # pylint: disable=R0901
return serializers.ArtifactSerializer
def create(self, request, *args, **kwargs):
"""Creates artifact"""
"""
Creates observation artifact
* Requires session or key authentication to create an artifact
"""
serializer = self.get_serializer(data=request.data)
try:
if serializer.is_valid():

View File

@ -4,6 +4,7 @@
# './contrib/refresh-requirements.sh to regenerate this file
-r requirements.txt
Faker==4.1.8
apipkg==1.5
appdirs==1.4.4
click==7.1.2
@ -13,21 +14,20 @@ docopt==0.6.1
docopts==0.6.1
execnet==1.7.1
factory-boy==2.12.0
Faker==4.1.8
filelock==3.0.12
iniconfig==1.1.1
mock==4.0.2
packaging==20.4
packaging==20.7
pluggy==0.13.1
pur==5.3.0
py==1.9.0
pyparsing==2.4.7
pytest==6.1.2
pytest-cov==2.10.1
pytest-django==3.9.0
pytest-forked==1.2.0
pytest-xdist==1.33.0
pytest==6.1.2
text-unidecode==1.3
toml==0.10.2
tox==3.16.0
virtualenv==20.1.0
virtualenv==20.2.1

View File

@ -9,7 +9,7 @@ billiard==3.6.3.0
cachetools==4.1.1
celery==4.4.7
certifi==2020.11.8
cffi==1.14.3
cffi==1.14.4
chardet==3.0.4
cryptography==3.2.1
defusedxml==0.7.0rc1
@ -18,7 +18,7 @@ Django==2.2.17
django-allauth==0.42.0
django-appconf==1.0.4
django-avatar==5.0.0
django-bootstrap-modal-forms==2.0.0
django-bootstrap-modal-forms==2.0.1
django-compressor==2.4
django-countries==6.1.3
django-crispy-forms==1.9.2
@ -30,23 +30,23 @@ django-jsonfield==1.3.1
django-redis-cache==2.0.0
django-shortuuidfield==0.1.3
django-widget-tweaks==1.4.8
djangorestframework==3.11.2
djangorestframework==3.12.2
dnspython==1.16.0
enum34==1.1.10
eventlet==0.29.1
frozendict==1.2
greenlet==0.4.17
gunicorn==19.9.0
h5py==2.10.0
h5py==3.1.0
idna==2.10
importlib-metadata==1.7.0
influxdb==5.3.0
influxdb==5.3.1
kaitaistruct==0.9
kombu==4.6.11
Logbook==1.5.3
lxml==4.6.1
lxml==4.6.2
Markdown==3.2.2
msgpack==0.6.1
msgpack==1.0.0
mysqlclient==2.0.1
numpy==1.19.4
oauthlib==3.1.0
@ -63,7 +63,7 @@ PyYAML==5.3.1
rcssmin==1.0.6
redis==3.5.3
Represent==1.6.0
requests==2.24.0
requests==2.25.0
requests-oauthlib==1.3.0
rjsmin==1.1.0
rush==2018.12.1
@ -80,6 +80,6 @@ spacetrack==0.15.0
sqlparse==0.4.1
Unipath==1.1
uritemplate==3.0.1
urllib3==1.25.11
urllib3==1.26.2
vine==1.3.0
zipp==3.4.0

View File

@ -51,7 +51,7 @@ install_requires =
# Static
django_compressor~=2.4.0
# API
djangorestframework~=3.11.0
djangorestframework~=3.12.0
Markdown~=3.2.0
django-filter~=2.3.0
# Astronomy
@ -66,7 +66,7 @@ install_requires =
simplejson~=3.17.0
uritemplate~=3.0.0
PyYAML~=5.3.0
h5py~=2.10.0
h5py~=3.1.0
PyLD~=2.0.2
# Metasat
django-countries~=6.1.2