Browse Source

bump OpenApi from 2.0 to 3.0

- Rm drf-yasg e add drj-spectacular
- corrige schema de listagem
- ajusta urls para /api/schema, /api/schema/swagger-ui, api/schema/redoc
- insere na paginação links diretos de next e previous com filtro
pull/3446/head
Leandro Roberto 3 years ago
parent
commit
b6f9a76b05
  1. 2
      requirements/requirements.txt
  2. 4
      sapl/api/core/__init__.py
  3. 5
      sapl/api/core/schema.py
  4. 65
      sapl/api/pagination.py
  5. 20
      sapl/api/urls.py
  6. 13
      sapl/settings.py

2
requirements/requirements.txt

@ -14,7 +14,7 @@ django-speedinfo==1.4.0
django-extensions==2.1.4 django-extensions==2.1.4
django-image-cropping==1.2 django-image-cropping==1.2
django-webpack-loader==0.6.0 django-webpack-loader==0.6.0
drf-yasg==1.20.0 drf-spectacular==0.18.2
django-ratelimit==3.0.1 django-ratelimit==3.0.1
easy-thumbnails==2.5 easy-thumbnails==2.5
python-decouple==3.1 python-decouple==3.1

4
sapl/api/core/__init__.py

@ -101,7 +101,7 @@ class SaplApiViewSetConstrutor():
class Meta(_meta_serializer): class Meta(_meta_serializer):
if not hasattr(_meta_serializer, 'ref_name'): if not hasattr(_meta_serializer, 'ref_name'):
ref_name = None ref_name = f'{object_name}Serializer'
if not hasattr(_meta_serializer, 'model'): if not hasattr(_meta_serializer, 'model'):
model = _model model = _model
@ -117,7 +117,7 @@ class SaplApiViewSetConstrutor():
else: else:
fields = _meta_serializer.fields fields = _meta_serializer.fields
def get___str__(self, obj): def get___str__(self, obj) -> str:
return str(obj) return str(obj)
_meta_filterset = object if not hasattr( _meta_filterset = object if not hasattr(

5
sapl/api/core/schema.py

@ -0,0 +1,5 @@
from drf_spectacular.openapi import AutoSchema
class Schema(AutoSchema):
pass

65
sapl/api/pagination.py

@ -13,6 +13,67 @@ class StandardPagination(pagination.PageNumberPagination):
return None return None
return super().paginate_queryset(queryset, request, view=view) return super().paginate_queryset(queryset, request, view=view)
def get_paginated_response_schema(self, schema):
r = {
'type': 'object',
'properties': {
'pagination': {
'type': 'object',
'properties': {
'links': {
'type': 'object',
'properties': {
'next': {
'type': 'string',
'nullable': True,
'format': 'uri',
'example': 'http://api.example.org/accounts/?{page_query_param}=4'.format(
page_query_param=self.page_query_param)
},
'previous': {
'type': 'string',
'nullable': True,
'format': 'uri',
'example': 'http://api.example.org/accounts/?{page_query_param}=2'.format(
page_query_param=self.page_query_param)
},
}
},
'previous_page': {
'type': 'integer',
'example': 123,
},
'next_page': {
'type': 'integer',
'example': 123,
},
'start_index': {
'type': 'integer',
'example': 123,
},
'end_index': {
'type': 'integer',
'example': 123,
},
'total_entries': {
'type': 'integer',
'example': 123,
},
'total_pages': {
'type': 'integer',
'example': 123,
},
'page': {
'type': 'integer',
'example': 123,
},
}
},
'results': schema,
},
}
return r
def get_paginated_response(self, data): def get_paginated_response(self, data):
try: try:
previous_page_number = self.page.previous_page_number() previous_page_number = self.page.previous_page_number()
@ -26,6 +87,10 @@ class StandardPagination(pagination.PageNumberPagination):
return Response({ return Response({
'pagination': { 'pagination': {
'links': {
'next': self.get_next_link(),
'previous': self.get_previous_link(),
},
'previous_page': previous_page_number, 'previous_page': previous_page_number,
'next_page': next_page_number, 'next_page': next_page_number,
'start_index': self.page.start_index(), 'start_index': self.page.start_index(),

20
sapl/api/urls.py

@ -1,6 +1,7 @@
from django.conf import settings
from django.conf.urls import include, url from django.conf.urls import include, url
from rest_framework import permissions from drf_spectacular.views import SpectacularAPIView, SpectacularSwaggerView,\
SpectacularRedocView
from rest_framework.routers import DefaultRouter from rest_framework.routers import DefaultRouter
from sapl.api.deprecated import MateriaLegislativaViewSet, SessaoPlenariaViewSet,\ from sapl.api.deprecated import MateriaLegislativaViewSet, SessaoPlenariaViewSet,\
@ -28,8 +29,17 @@ for app, built_sets in SaplApiViewSetConstrutor._built_sets.items():
urlpatterns_router = router.urls urlpatterns_router = router.urls
urlpatterns_api_doc = [] urlpatterns_api_doc = [
if 'drf_yasg' in settings.INSTALLED_APPS: # Optional UI:
url('^schema/swagger-ui/',
SpectacularSwaggerView.as_view(url_name='sapl.api:schema_api'), name='swagger-ui'),
url('^schema/redoc/',
SpectacularRedocView.as_view(url_name='sapl.api:schema_api'), name='redoc'),
# YOUR PATTERNS
url('^schema/', SpectacularAPIView.as_view(), name='schema_api'),
]
"""if 'drf_yasg' in settings.INSTALLED_APPS:
from drf_yasg import openapi from drf_yasg import openapi
from drf_yasg.views import get_schema_view from drf_yasg.views import get_schema_view
schema_view = get_schema_view( schema_view = get_schema_view(
@ -50,7 +60,7 @@ if 'drf_yasg' in settings.INSTALLED_APPS:
schema_view.with_ui('swagger', cache_timeout=0), name='schema-swagger-ui'), schema_view.with_ui('swagger', cache_timeout=0), name='schema-swagger-ui'),
url(r'^docs/redoc/$', url(r'^docs/redoc/$',
schema_view.with_ui('redoc', cache_timeout=0), name='schema-redoc'), schema_view.with_ui('redoc', cache_timeout=0), name='schema-redoc'),
] ]"""
# TODO: refatorar para customização da api automática # TODO: refatorar para customização da api automática
deprecated_urlpatterns_api = [ deprecated_urlpatterns_api = [

13
sapl/settings.py

@ -81,7 +81,7 @@ INSTALLED_APPS = (
'crispy_forms', 'crispy_forms',
'floppyforms', 'floppyforms',
'drf_yasg', 'drf_spectacular',
'rest_framework', 'rest_framework',
'rest_framework.authtoken', 'rest_framework.authtoken',
'django_filters', 'django_filters',
@ -160,12 +160,23 @@ REST_FRAMEWORK = {
'rest_framework.authentication.TokenAuthentication', 'rest_framework.authentication.TokenAuthentication',
"rest_framework.authentication.SessionAuthentication", "rest_framework.authentication.SessionAuthentication",
), ),
'DEFAULT_SCHEMA_CLASS': 'sapl.api.core.schema.Schema',
"DEFAULT_PAGINATION_CLASS": "sapl.api.pagination.StandardPagination", "DEFAULT_PAGINATION_CLASS": "sapl.api.pagination.StandardPagination",
"DEFAULT_FILTER_BACKENDS": ( "DEFAULT_FILTER_BACKENDS": (
"rest_framework.filters.SearchFilter", "rest_framework.filters.SearchFilter",
'django_filters.rest_framework.DjangoFilterBackend', 'django_filters.rest_framework.DjangoFilterBackend',
), ),
} }
SPECTACULAR_SETTINGS = {
'TITLE': 'Sapl API - docs',
'DESCRIPTION': 'Sapl API - Docs',
'VERSION': '1.0.0',
}
CACHES = { CACHES = {
'default': { 'default': {
'BACKEND': 'speedinfo.backends.proxy_cache', 'BACKEND': 'speedinfo.backends.proxy_cache',

Loading…
Cancel
Save