API schema generator and validator for Django REST framework
Project description
DRF APISchema
Based on drf-spectacular, automatically generate API documentation, validate queries, bodies, and permissions, handle transactions, and log SQL queries.
This can greatly speed up development and make the code more readable.
Features
-
Auto generate API documentation and routes
-
Validate queries, bodies, and permissions
-
Handle transactions
-
Log SQL queries
-
Simple to use
@apischema(permissions=[IsAdminUser], body=UserIn, response=UserOut)
def create(self, request: ASRequest[UserIn]):
"""Description"""
print(request.serializer, request.validated_data)
return UserOut(request.serializer.save()).data
Installation
Install drf-apischema from PyPI
pip install drf-apischema
Configure your project settings.py like this
INSTALLED_APPS = [
# ...
"rest_framework",
"drf_spectacular",
"drf_apischema.scalar,
# ...
]
REST_FRAMEWORK = {
"DEFAULT_SCHEMA_CLASS": "drf_spectacular.openapi.AutoSchema",
}
SPECTACULAR_SETTINGS = {
"TITLE": "Your Project API",
"DESCRIPTION": "Your project description",
"VERSION": "1.0.0",
"SERVE_INCLUDE_SCHEMA": False,
'SCHEMA_PATH_PREFIX': '/api-docs',
}
Usage
serializers.py
from django.contrib.auth.models import User
from rest_framework import serializers
class UserOut(serializers.ModelSerializer):
class Meta:
model = User
fields = ["id", "username"]
class SquareOut(serializers.Serializer):
result = serializers.IntegerField()
class SquareQuery(serializers.Serializer):
n = serializers.IntegerField(default=2)
views.py
from django.contrib.auth.models import User
from rest_framework.mixins import ListModelMixin, RetrieveModelMixin
from rest_framework.permissions import IsAdminUser, IsAuthenticated
from rest_framework.viewsets import GenericViewSet
from drf_apischema import ASRequest, apischema, apischema_view
from drf_apischema.decorator import action
from .serializers import SquareOut, SquareQuery, UserOut
# Create your views here.
@apischema_view(
retrieve=apischema(summary="Retrieve a user"),
)
class UserViewSet(GenericViewSet, ListModelMixin, RetrieveModelMixin):
"""User management"""
queryset = User.objects.all()
serializer_class = UserOut
# permission_classes = [IsAuthenticated]
# Define a view that requires permissions
@apischema(permissions=[IsAdminUser])
def list(self, request):
"""List all users
Document here
xxx
"""
return super().list(request)
# will auto wrap it with `apischema` in `apischema_view`
@action(methods=["post"], detail=True)
def echo(self, request, pk):
"""Echo the request"""
return self.get_serializer(self.get_object()).data
@apischema(query=SquareQuery, response=SquareOut)
@action(methods=["get"], detail=False)
def square(self, request: ASRequest[SquareQuery]):
"""The square of a number"""
# The request.serializer is an instance of SquareQuery that has been validated
# print(request.serializer)
# The request.validated_data is the validated data of the serializer
n: int = request.validated_data["n"]
# Note that apischema won't automatically process the response with the declared response serializer,
# but it will wrap it with rest_framework.response.Response
# So you don't need to manually wrap it with Response
return SquareOut({"result": n * n}).data
urls.py
from django.urls import include, path
from drf_apischema.urls import api_docs_path
from rest_framework.routers import DefaultRouter
from .views import *
router = DefaultRouter()
router.register("test", TestViewSet, basename="test")
urlpatterns = [
path("/api", include(router.urls)),
# Auto-generate /api-docs/xxx, include /api-docs/scalar/
api_docs_path(),
]
settings
settings.py
DRF_APISCHEMA_SETTINGS = {
# Enable transaction wrapping for APIs
"TRANSACTION": True,
# Enable SQL logging
"SQL_LOGGING": settings.DEBUG,
# Indent SQL queries
"SQL_LOGGING_REINDENT": True,
# Use method docstring as summary and description
"SUMMARY_FROM_DOC": True,
# Show permissions in description
"SHOW_PERMISSIONS": True,
# If True, request_body and response will be empty by default if the view is action decorated
"ACTION_DEFAULTS_EMPTY": False,
# OpenAPI URL name
"OPENAPI_URL_NAME" = "openapi.json"
}
drf-yasg version
See branch drf-yasg, it is not longer supported
Troubleshooting
Doesn't showed permissions description of permission_classes
Wrap the view with apischema_view.
@apischema_view()
class XxxViewSet(GenericViewSet):
permissions_classes = [IsAuthenticated]
TypeError: cannot be assigned to parameter of type "_View@action"
Just annotate the return type to Any, as apischema will wrap it with Response.
Or use drf_apischema.decorator.action instead of rest_framework's action
@apischema()
@action(methods=["get"], detail=False)
def xxx(self, request) -> Any:
...
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file drf_apischema-0.3.5.tar.gz.
File metadata
- Download URL: drf_apischema-0.3.5.tar.gz
- Upload date:
- Size: 11.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.27 {"installer":{"name":"uv","version":"0.9.27","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Arch Linux","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
dc85f1226a1daee665c4ed190f3d48abd127172d7cc52cf89eef55d49863c0b4
|
|
| MD5 |
19e3bd1dc807e8b0cb95ca5d9fa335f5
|
|
| BLAKE2b-256 |
b039acc3b637f8e5f5f68cbad03af5e9ced0be4b80a8c365f13264e992556dcb
|
File details
Details for the file drf_apischema-0.3.5-py3-none-any.whl.
File metadata
- Download URL: drf_apischema-0.3.5-py3-none-any.whl
- Upload date:
- Size: 16.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.27 {"installer":{"name":"uv","version":"0.9.27","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Arch Linux","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8e54d871d25d89b1b606935601500c72225ca11090b0266b87f0a739098bddd6
|
|
| MD5 |
808abd419107a7aae94efc81031565af
|
|
| BLAKE2b-256 |
ea9731070f85b9f3c44dfe921f4358722dc094d15a9ccfccdafa83053d074104
|