Skip to main content

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 typing import Any

from django.contrib.auth.models import User
from rest_framework.decorators import action
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 .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

        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]) -> Any:
        """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 rest_framework.routers import DefaultRouter

from drf_apischema.urls import api_docs_path

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.

@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

drf_apischema-0.3.3.tar.gz (11.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

drf_apischema-0.3.3-py3-none-any.whl (16.2 kB view details)

Uploaded Python 3

File details

Details for the file drf_apischema-0.3.3.tar.gz.

File metadata

  • Download URL: drf_apischema-0.3.3.tar.gz
  • Upload date:
  • Size: 11.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.24 {"installer":{"name":"uv","version":"0.9.24","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

Hashes for drf_apischema-0.3.3.tar.gz
Algorithm Hash digest
SHA256 8f1e60851ec72dbee9ebfa6e6682ed7d4ede23d254a46dd819b070290d65348e
MD5 265b853111fe223a1a4ad0431d765523
BLAKE2b-256 449570ba30c170fe020e8ccd9cf331c2793bc06b8fdc96c64583a2b4e34c3f70

See more details on using hashes here.

File details

Details for the file drf_apischema-0.3.3-py3-none-any.whl.

File metadata

  • Download URL: drf_apischema-0.3.3-py3-none-any.whl
  • Upload date:
  • Size: 16.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.24 {"installer":{"name":"uv","version":"0.9.24","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

Hashes for drf_apischema-0.3.3-py3-none-any.whl
Algorithm Hash digest
SHA256 6edf2d2dfd60f632679cf01f6fe9ba78d42ec1b4822569a8f470b192b6d8f24f
MD5 c93eeee681be9d6a46b8c33f02d50b96
BLAKE2b-256 40dab942b6aed24c6edcaf0213ceab6e7aefd834a7e975028254be45319c1b70

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page