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

feat(backend): generate OpenAPI v3 swagger docs #5259

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
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
15 changes: 13 additions & 2 deletions dependencies/pip/dev_requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ django==4.2.15
# django-taggit
# django-timezone-field
# djangorestframework
# drf-spectacular
# jsonfield
# model-bakery
django-allauth==0.61.1
Expand Down Expand Up @@ -238,6 +239,7 @@ djangorestframework==3.15.1
# -r dependencies/pip/requirements.in
# djangorestframework-csv
# drf-extensions
# drf-spectacular
djangorestframework-csv==3.0.2
# via -r dependencies/pip/requirements.in
djangorestframework-jsonp==1.0.2
Expand All @@ -252,6 +254,8 @@ docutils==0.20.1
# via statistics
drf-extensions==0.7.1
# via -r dependencies/pip/requirements.in
drf-spectacular==0.27.2
# via -r dependencies/pip/requirements.in
et-xmlfile==1.1.0
# via openpyxl
exceptiongroup==1.2.0
Expand Down Expand Up @@ -344,6 +348,8 @@ idna==3.6
# via
# requests
# yarl
inflection==0.5.1
# via drf-spectacular
iniconfig==2.0.0
# via pytest
invoke==2.2.0
Expand All @@ -365,6 +371,7 @@ jsonfield==3.1.0
jsonschema==4.21.1
# via
# -r dependencies/pip/requirements.in
# drf-spectacular
# formpack
jsonschema-specifications==2023.12.1
# via jsonschema
Expand Down Expand Up @@ -542,7 +549,9 @@ pyxform==2.2.0
# -r dependencies/pip/requirements.in
# formpack
pyyaml==6.0.1
# via responses
# via
# drf-spectacular
# responses
redis==5.0.3
# via
# celery
Expand Down Expand Up @@ -654,7 +663,9 @@ tzdata==2024.1
ua-parser==0.18.0
# via -r dependencies/pip/requirements.in
uritemplate==4.1.1
# via google-api-python-client
# via
# drf-spectacular
# google-api-python-client
urllib3==1.26.18
# via
# botocore
Expand Down
2 changes: 2 additions & 0 deletions dependencies/pip/requirements.in
Original file line number Diff line number Diff line change
Expand Up @@ -111,3 +111,5 @@ modilabs-python-utils
djangorestframework-csv
djangorestframework-jsonp
pandas

drf-spectacular # OpenAPI v3 schema generator
15 changes: 13 additions & 2 deletions dependencies/pip/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ django==4.2.15
# django-taggit
# django-timezone-field
# djangorestframework
# drf-spectacular
# jsonfield
django-allauth==0.61.1
# via -r dependencies/pip/requirements.in
Expand Down Expand Up @@ -206,6 +207,7 @@ djangorestframework==3.15.1
# -r dependencies/pip/requirements.in
# djangorestframework-csv
# drf-extensions
# drf-spectacular
djangorestframework-csv==3.0.2
# via -r dependencies/pip/requirements.in
djangorestframework-jsonp==1.0.2
Expand All @@ -218,6 +220,8 @@ docutils==0.20.1
# via statistics
drf-extensions==0.7.1
# via -r dependencies/pip/requirements.in
drf-spectacular==0.27.2
# via -r dependencies/pip/requirements.in
et-xmlfile==1.1.0
# via openpyxl
flower==2.0.1
Expand Down Expand Up @@ -288,6 +292,8 @@ idna==3.6
# via
# requests
# yarl
inflection==0.5.1
# via drf-spectacular
isodate==0.6.1
# via azure-storage-blob
jmespath==1.0.1
Expand All @@ -299,6 +305,7 @@ jsonfield==3.1.0
jsonschema==4.21.1
# via
# -r dependencies/pip/requirements.in
# drf-spectacular
# formpack
jsonschema-specifications==2023.12.1
# via jsonschema
Expand Down Expand Up @@ -417,7 +424,9 @@ pyxform==2.2.0
# -r dependencies/pip/requirements.in
# formpack
pyyaml==6.0.1
# via responses
# via
# drf-spectacular
# responses
redis==5.0.3
# via
# celery
Expand Down Expand Up @@ -502,7 +511,9 @@ tzdata==2024.1
ua-parser==0.18.0
# via -r dependencies/pip/requirements.in
uritemplate==4.1.1
# via google-api-python-client
# via
# drf-spectacular
# google-api-python-client
urllib3==1.26.18
# via
# botocore
Expand Down
2 changes: 1 addition & 1 deletion kobo/apps/openrosa/libs/renderers/renderers.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ def filter_renderers(self, renderers, format):

class MediaFileRenderer(BaseRenderer):
media_type = '*/*'
format = None
format = 'TODO'
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

drf_spectacular requires format to be a string, otherwise it crashes. What would the right format here?

charset = None
render_style = 'binary'

Expand Down
13 changes: 10 additions & 3 deletions kobo/settings/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@
'guardian',
'kobo.apps.openrosa.libs',
'kobo.apps.project_ownership.ProjectOwnershipAppConfig',
'drf_spectacular',
)

MIDDLEWARE = [
Expand Down Expand Up @@ -640,9 +641,6 @@
'positive_int_minus_one': ['django.forms.fields.IntegerField', {
'min_value': -1
}],
'positive_int': ['django.forms.fields.IntegerField', {
'min_value': 0
}],
}

CONSTANCE_CONFIG_FIELDSETS = {
Expand Down Expand Up @@ -937,6 +935,15 @@ def __init__(self, *args, **kwargs):
'DEFAULT_VERSIONING_CLASS': 'kpi.versioning.APIAutoVersioning',
# Cannot be placed in kpi.exceptions.py because of circular imports
'EXCEPTION_HANDLER': 'kpi.utils.drf_exceptions.custom_exception_handler',
'DEFAULT_SCHEMA_CLASS': 'drf_spectacular.openapi.AutoSchema',
}

SPECTACULAR_SETTINGS = {
'TITLE': 'KoboToolbox API',
'DESCRIPTION': 'Warning: experimental schema generation. Use at your own risk.',
'VERSION': '0.0.1',
'SERVE_INCLUDE_SCHEMA': False,
# OTHER SETTINGS
}

OPENROSA_REST_FRAMEWORK = {
Expand Down
20 changes: 17 additions & 3 deletions kobo/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,29 @@
from django.views.generic.base import RedirectView
from rest_framework import status
from rest_framework.exceptions import server_error
from drf_spectacular.views import (
SpectacularAPIView,
SpectacularRedocView,
SpectacularSwaggerView,
)

from kpi.utils.urls import is_request_for_html

admin.autodiscover()
admin.site.login = staff_member_required(
admin.site.login, login_url=settings.LOGIN_URL
)
admin.site.login = staff_member_required(admin.site.login, login_url=settings.LOGIN_URL)

urlpatterns = [
path('api/schema/', SpectacularAPIView.as_view(), name='schema'),
path(
'api/schema/swagger/',
SpectacularSwaggerView.as_view(url_name='schema'),
name='swagger-ui',
),
path(
'api/schema/redoc/',
SpectacularRedocView.as_view(url_name='schema'),
name='redoc',
),
Comment on lines +23 to +33
Copy link
Contributor Author

@Akuukis Akuukis Nov 13, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just copied the example from docs for a quick PoC. Questions:

  1. what api path you'd like?
  2. is this the right urls.py to add spectacular to urls?
  3. let's use swagger or redoc, or both? My preference is swagger.

# https://github.com/stochastic-technologies/django-loginas
re_path(r'^admin/', include('loginas.urls')),
# Disable admin login form
Expand Down
2 changes: 1 addition & 1 deletion kpi/renderers.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class AssetJsonRenderer(renderers.JSONRenderer):

class MediaFileRenderer(renderers.BaseRenderer):
media_type = '*/*'
format = None
format = 'TODO'
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

drf_spectacular requires format to be a string, otherwise it crashes. What would the right format here?

charset = None
render_style = 'binary'

Expand Down
Loading