Skip to content

Commit

Permalink
feat(api): add OpenAPI schema using drf-spectacular
Browse files Browse the repository at this point in the history
Issue #12584
  • Loading branch information
nijel committed Sep 30, 2024
1 parent 09ac510 commit ba3cb4c
Show file tree
Hide file tree
Showing 8 changed files with 69 additions and 1 deletion.
10 changes: 10 additions & 0 deletions docs/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,16 @@ The API is accessible on the ``/api/`` URL and it is based on
`Django REST framework <https://www.django-rest-framework.org/>`_.
You can use it directly or by :ref:`wlc`.

The API is also documented using OpenAPI 3.0 on the ``/api/schema/`` URL, you
can browse it using Swagger at ``/api/schema/swagger-ui/`` or Redoc at
``/api/schema/redoc/``.

.. note::

OpenAPI is available as a feature preview. The documentation is most likely
incomplete at this point and subject to change. Please consult the
documentation below for more detailed information on the API.

.. _api-generic:

Authentication and generic parameters
Expand Down
1 change: 1 addition & 0 deletions docs/changes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ Not yet released.
* :ref:`mt-aws` now supports :ref:`glossary-mt`.
* :ref:`autofix` for Devanagari danda now better handles latin script.
* :ref:`autofix` for French and Breton now uses a non-breaking space before colons instead of a narrow one.
* :ref:`api` now has a preview OpenAPI specification.

**Bug fixes**

Expand Down
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ dependencies = [
"django-otp-webauthn>=0.3.0,<0.4",
"Django[argon2]>=5.0,<5.2",
"djangorestframework>=3.15.2,<3.16",
"drf-spectacular[sidecar]>=0.27.2,<0.28",
"filelock<4,>=3.12.2",
"fluent.syntax>=0.18.1,<0.20",
"GitPython>=3.1.0,<3.2",
Expand Down
7 changes: 6 additions & 1 deletion weblate/middleware.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,12 @@
}

# URLs requiring inline javascript
INLINE_PATHS = {"social:begin", "djangosaml2idp:saml_login_process"}
INLINE_PATHS = {
"social:begin",
"djangosaml2idp:saml_login_process",
"swagger-ui",
"redoc",
}


class ProxyMiddleware:
Expand Down
16 changes: 16 additions & 0 deletions weblate/settings_docker.py
Original file line number Diff line number Diff line change
Expand Up @@ -779,6 +779,8 @@
"django_otp.plugins.otp_static",
"django_otp.plugins.otp_totp",
"django_otp_webauthn",
"drf_spectacular",
"drf_spectacular_sidecar",
]

modify_env_list(INSTALLED_APPS, "APPS")
Expand Down Expand Up @@ -1204,6 +1206,20 @@
"VIEW_DESCRIPTION_FUNCTION": "weblate.api.views.get_view_description",
"EXCEPTION_HANDLER": "weblate.api.views.weblate_exception_handler",
"UNAUTHENTICATED_USER": "weblate.auth.models.get_anonymous",
"DEFAULT_SCHEMA_CLASS": "drf_spectacular.openapi.AutoSchema",
}
SPECTACULAR_SETTINGS = {
"SWAGGER_UI_DIST": "SIDECAR",
"SWAGGER_UI_FAVICON_HREF": "SIDECAR",
"REDOC_DIST": "SIDECAR",
"SERVE_URLCONF": "weblate.api.urls",
"TITLE": "Weblate's REST API",
"DESCRIPTION": """
The API is accessible on the ``/api/`` URL and it is based on [Django REST framework](https://www.django-rest-framework.org/).
The OpenAPI specification is available as feature preview, feedback welcome!
""",
"VERSION": None,
}

# Fonts CDN URL
Expand Down
16 changes: 16 additions & 0 deletions weblate/settings_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -438,6 +438,8 @@
"django_otp.plugins.otp_static",
"django_otp.plugins.otp_totp",
"django_otp_webauthn",
"drf_spectacular",
"drf_spectacular_sidecar",
]

# Custom exception reporter to include some details
Expand Down Expand Up @@ -823,6 +825,20 @@
"VIEW_DESCRIPTION_FUNCTION": "weblate.api.views.get_view_description",
"EXCEPTION_HANDLER": "weblate.api.views.weblate_exception_handler",
"UNAUTHENTICATED_USER": "weblate.auth.models.get_anonymous",
"DEFAULT_SCHEMA_CLASS": "drf_spectacular.openapi.AutoSchema",
}
SPECTACULAR_SETTINGS = {
"SWAGGER_UI_DIST": "SIDECAR",
"SWAGGER_UI_FAVICON_HREF": "SIDECAR",
"REDOC_DIST": "SIDECAR",
"SERVE_URLCONF": "weblate.api.urls",
"TITLE": "Weblate's REST API",
"DESCRIPTION": """
The API is accessible on the ``/api/`` URL and it is based on [Django REST framework](https://www.django-rest-framework.org/).
The OpenAPI specification is available as feature preview, feedback welcome!
""",
"VERSION": None,
}

# Fonts CDN URL
Expand Down
18 changes: 18 additions & 0 deletions weblate/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@
from django.views.decorators.cache import cache_control, cache_page
from django.views.decorators.vary import vary_on_cookie
from django.views.generic import RedirectView, TemplateView
from drf_spectacular.views import (
SpectacularAPIView,
SpectacularRedocView,
SpectacularSwaggerView,
)

import weblate.accounts.urls
import weblate.accounts.views
Expand Down Expand Up @@ -814,6 +819,19 @@
path("accounts/", include(weblate.accounts.urls)),
# Auth
path("api/", include((weblate.api.urls, "weblate.api"), namespace="api")),
# YOUR PATTERNS
path("api/schema/", SpectacularAPIView.as_view(), name="schema"),
# Optional UI:
path(
"api/schema/swagger-ui/",
SpectacularSwaggerView.as_view(url_name="schema"),
name="swagger-ui",
),
path(
"api/schema/redoc/",
SpectacularRedocView.as_view(url_name="schema"),
name="redoc",
),
# Static pages
path("contact/", weblate.accounts.views.contact, name="contact"),
path("hosting/", weblate.accounts.views.hosting, name="hosting"),
Expand Down
1 change: 1 addition & 0 deletions weblate/utils/requirements.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
"python-redis-lock",
"charset-normalizer",
"cyrtranslit",
"drf_spectacular",
]

OPTIONAL = [
Expand Down

0 comments on commit ba3cb4c

Please sign in to comment.