diff --git a/.github/contributors.json b/.github/contributors.json
index ab1575605..86ccf42a6 100644
--- a/.github/contributors.json
+++ b/.github/contributors.json
@@ -1217,5 +1217,10 @@
"name": "Pedro Campos",
"github_login": "pcampos119104",
"twitter_username": ""
+ },
+ {
+ "name": "Vikas Yadav",
+ "github_login": "vik-y",
+ "twitter_username": ""
}
]
\ No newline at end of file
diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md
index fe69a718a..4d1a505a9 100644
--- a/CONTRIBUTORS.md
+++ b/CONTRIBUTORS.md
@@ -1636,6 +1636,13 @@ Listed in alphabetical order.
Vitaly Babiy |
diff --git a/hooks/post_gen_project.py b/hooks/post_gen_project.py
index 7e1374c2e..adb0f894d 100644
--- a/hooks/post_gen_project.py
+++ b/hooks/post_gen_project.py
@@ -391,6 +391,11 @@ def remove_drf_starter_files():
"{{cookiecutter.project_slug}}", "users", "tests", "test_drf_views.py"
)
)
+ os.remove(
+ os.path.join(
+ "{{cookiecutter.project_slug}}", "users", "tests", "test_swagger_ui.py"
+ )
+ )
def remove_storages_module():
diff --git a/requirements.txt b/requirements.txt
index 426091f9e..763fe10e3 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -8,7 +8,7 @@ black==21.12b0
isort==5.10.1
flake8==4.0.1
flake8-isort==4.1.1
-pre-commit==2.16.0
+pre-commit==2.17.0
# Testing
# ------------------------------------------------------------------------------
diff --git a/{{cookiecutter.project_slug}}/config/settings/base.py b/{{cookiecutter.project_slug}}/config/settings/base.py
index afae0ec4f..0cf82e157 100644
--- a/{{cookiecutter.project_slug}}/config/settings/base.py
+++ b/{{cookiecutter.project_slug}}/config/settings/base.py
@@ -90,6 +90,7 @@ THIRD_PARTY_APPS = [
"rest_framework",
"rest_framework.authtoken",
"corsheaders",
+ "drf_spectacular",
{%- endif %}
]
@@ -340,6 +341,18 @@ REST_FRAMEWORK = {
# django-cors-headers - https://github.com/adamchainz/django-cors-headers#setup
CORS_URLS_REGEX = r"^/api/.*$"
+# By Default swagger ui is available only to admin user. You can change permission classs to change that
+# See more configuration options at https://drf-spectacular.readthedocs.io/en/latest/settings.html#settings
+SPECTACULAR_SETTINGS = {
+ "TITLE": "{{ cookiecutter.project_name }} API",
+ "DESCRIPTION": "Documentation of API endpoiints of {{ cookiecutter.project_name }}",
+ "VERSION": "1.0.0",
+ "SERVE_PERMISSIONS": ["rest_framework.permissions.IsAdminUser"],
+ "SERVERS": [
+ {"url": "https://127.0.0.1:8000", "description": "Local Development server"},
+ {"url": "https://{{ cookiecutter.domain_name }}", "description": "Production server"},
+ ],
+}
{%- endif %}
# Your stuff...
# ------------------------------------------------------------------------------
diff --git a/{{cookiecutter.project_slug}}/config/urls.py b/{{cookiecutter.project_slug}}/config/urls.py
index 168d77a8b..ab42cc103 100644
--- a/{{cookiecutter.project_slug}}/config/urls.py
+++ b/{{cookiecutter.project_slug}}/config/urls.py
@@ -8,6 +8,7 @@ from django.urls import include, path
from django.views import defaults as default_views
from django.views.generic import TemplateView
{%- if cookiecutter.use_drf == 'y' %}
+from drf_spectacular.views import SpectacularAPIView, SpectacularSwaggerView
from rest_framework.authtoken.views import obtain_auth_token
{%- endif %}
@@ -35,6 +36,12 @@ urlpatterns += [
path("api/", include("config.api_router")),
# DRF auth token
path("auth-token/", obtain_auth_token),
+ path("api/schema/", SpectacularAPIView.as_view(), name="api-schema"),
+ path(
+ "api/docs/",
+ SpectacularSwaggerView.as_view(url_name="api-schema"),
+ name="api-docs",
+ ),
]
{%- endif %}
diff --git a/{{cookiecutter.project_slug}}/requirements/base.txt b/{{cookiecutter.project_slug}}/requirements/base.txt
index e371135cf..d9dbb83e3 100644
--- a/{{cookiecutter.project_slug}}/requirements/base.txt
+++ b/{{cookiecutter.project_slug}}/requirements/base.txt
@@ -43,4 +43,6 @@ django-redis==5.2.0 # https://github.com/jazzband/django-redis
# Django REST Framework
djangorestframework==3.13.1 # https://github.com/encode/django-rest-framework
django-cors-headers==3.11.0 # https://github.com/adamchainz/django-cors-headers
+# DRF-spectacular for api documentation
+drf-spectacular==0.21.1
{%- endif %}
diff --git a/{{cookiecutter.project_slug}}/requirements/local.txt b/{{cookiecutter.project_slug}}/requirements/local.txt
index ee99e04e9..f1f271cbc 100644
--- a/{{cookiecutter.project_slug}}/requirements/local.txt
+++ b/{{cookiecutter.project_slug}}/requirements/local.txt
@@ -41,7 +41,7 @@ pylint-django==2.5.0 # https://github.com/PyCQA/pylint-django
{%- if cookiecutter.use_celery == 'y' %}
pylint-celery==0.3 # https://github.com/PyCQA/pylint-celery
{%- endif %}
-pre-commit==2.16.0 # https://github.com/pre-commit/pre-commit
+pre-commit==2.17.0 # https://github.com/pre-commit/pre-commit
# Django
# ------------------------------------------------------------------------------
diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_swagger_ui.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_swagger_ui.py
new file mode 100644
index 000000000..b0c24d91b
--- /dev/null
+++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_swagger_ui.py
@@ -0,0 +1,16 @@
+import pytest
+from django.urls import reverse
+
+pytestmark = pytest.mark.django_db
+
+
+def test_swagger_accessible_by_admin(admin_client):
+ url = reverse("api-docs")
+ response = admin_client.get(url)
+ assert response.status_code == 200
+
+
+def test_swagger_ui_not_accessible_by_normal_user(client):
+ url = reverse("api-docs")
+ response = client.get(url)
+ assert response.status_code == 403
|