Skip to content

Commit 3e9cf27

Browse files
committed
TG-162 Add API Documentation
1 parent e581e39 commit 3e9cf27

File tree

7 files changed

+108
-0
lines changed

7 files changed

+108
-0
lines changed

{{cookiecutter.project_dirname}}/.env_template

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,5 @@ [email protected]
1515
DJANGO_SUPERUSER_PASSWORD={{ cookiecutter.project_slug }}
1616
DJANGO_SUPERUSER_USERNAME=${USER}
1717
EMAIL_URL=console:///
18+
DJANGO_ENABLE_API_DOCS=True
1819
PYTHONBREAKPOINT=ipdb.set_trace

{{cookiecutter.project_dirname}}/docker-compose.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ services:
2626
- DJANGO_SUPERUSER_PASSWORD
2727
- DJANGO_SUPERUSER_USERNAME
2828
- EMAIL_URL
29+
- ENABLE_API_DOCS
2930
- PYTHONBREAKPOINT
3031
- SERVICE_PORT
3132
ports:
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,5 @@
11
# pip-compile --output-file common.txt common.in
22
-r base.in
3+
djangorestframework-camel-case~=1.3.0
4+
djangorestframework~=3.13.0
5+
drf-spectacular~=0.22.0

{{cookiecutter.project_dirname}}/terraform/main.tf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ resource "kubernetes_secret_v1" "env" {
9191
{
9292
DJANGO_SECRET_KEY = random_password.django_secret_key.result
9393
EMAIL_URL = var.email_url
94+
ENABLE_API_DOCS = var.environment_slug == "prod" ? "False" : "True"
9495
SENTRY_DSN = var.sentry_dsn
9596
},
9697
local.use_s3 ? {

{{cookiecutter.project_dirname}}/{{cookiecutter.django_settings_dirname}}/settings.py

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ class ProjectDefault(Configuration):
4747
"django.contrib.sessions",
4848
"django.contrib.messages",
4949
"django.contrib.staticfiles",
50+
"drf_spectacular",
5051
]
5152

5253
MIDDLEWARE = [
@@ -181,6 +182,51 @@ class ProjectDefault(Configuration):
181182

182183
SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https")
183184

185+
# API Documentation
186+
187+
ENABLE_API_DOCS = values.BooleanValue(False)
188+
189+
# Django REST Framework
190+
# https://www.django-rest-framework.org/api-guide/settings/
191+
192+
REST_FRAMEWORK: dict = {
193+
"DEFAULT_AUTHENTICATION_CLASSES": [
194+
"rest_framework.authentication.TokenAuthentication"
195+
],
196+
"DEFAULT_FILTER_BACKENDS": [
197+
"django_filters.rest_framework.DjangoFilterBackend"
198+
],
199+
"DEFAULT_PARSER_CLASSES": [
200+
"djangorestframework_camel_case.parser.CamelCaseMultiPartParser",
201+
"djangorestframework_camel_case.parser.CamelCaseJSONParser",
202+
],
203+
"DEFAULT_PERMISSION_CLASSES": ["rest_framework.permissions.IsAuthenticated"],
204+
"DEFAULT_RENDERER_CLASSES": [
205+
"djangorestframework_camel_case.render.CamelCaseJSONRenderer",
206+
],
207+
"DEFAULT_SCHEMA_CLASS": "drf_spectacular.openapi.AutoSchema",
208+
}
209+
210+
# drf-spectacular
211+
# https://drf-spectacular.readthedocs.io/en/latest/
212+
213+
SPECTACULAR_SETTINGS = {
214+
"TITLE": "{{ cookiecutter.project_name }} - API documentation",
215+
"DESCRIPTION": "{{ cookiecutter.project_description }}",
216+
"VERSION": "1.0.0",
217+
"CAMELIZE_NAMES": True,
218+
"SWAGGER_UI_SETTINGS": {
219+
"deepLinking": True,
220+
"displayRequestDuration": True,
221+
"persistAuthorization": True,
222+
"syntaxHighlight.activate": True,
223+
},
224+
"POSTPROCESSING_HOOKS": [
225+
"drf_spectacular.hooks.postprocess_schema_enums",
226+
"drf_spectacular.contrib.djangorestframework_camel_case.camelize_serializer_fields", # noqa
227+
],
228+
}
229+
184230

185231
class Local(ProjectDefault):
186232
"""The local settings."""
@@ -251,6 +297,18 @@ class Local(ProjectDefault):
251297
"verbose_names": True,
252298
}
253299

300+
# Django REST Framework
301+
# https://www.django-rest-framework.org/api-guide/settings/
302+
303+
REST_FRAMEWORK = {
304+
**ProjectDefault.REST_FRAMEWORK,
305+
"DEFAULT_RENDERER_CLASSES": [
306+
*ProjectDefault.REST_FRAMEWORK["DEFAULT_RENDERER_CLASSES"],
307+
"djangorestframework_camel_case.render.CamelCaseBrowsableAPIRenderer",
308+
],
309+
}
310+
311+
254312

255313
class Testing(ProjectDefault):
256314
"""The testing settings."""

{{cookiecutter.project_dirname}}/{{cookiecutter.django_settings_dirname}}/urls.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,21 @@
2323

2424
urlpatterns = [
2525
path("admin/", admin.site.urls),
26+
path(
27+
"api/",
28+
include(
29+
(
30+
[
31+
*(
32+
[path("", include("{{ cookiecutter.project_slug }}.urls_apibrowser"))]
33+
if settings.ENABLE_API_DOCS
34+
else []
35+
),
36+
],
37+
"api",
38+
)
39+
),
40+
),
2641
]
2742

2843
if settings.DEBUG: # pragma: no cover
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
"""API browser URL configuration."""
2+
3+
from django.urls import include, path
4+
from drf_spectacular.views import SpectacularAPIView, SpectacularSwaggerView
5+
6+
urlpatterns = [
7+
path(
8+
"browser/",
9+
include(
10+
(
11+
[
12+
path(
13+
"schema/",
14+
SpectacularAPIView.as_view(
15+
urlconf="{{ cookiecutter.project_slug }}.urls"
16+
),
17+
name="schema",
18+
),
19+
path(
20+
"docs/",
21+
SpectacularSwaggerView.as_view(url_name="api:browser:schema"),
22+
name="docs",
23+
),
24+
],
25+
"browser",
26+
),
27+
),
28+
)
29+
]

0 commit comments

Comments
 (0)