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 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.

@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.4.tar.gz (11.6 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.4-py3-none-any.whl (16.5 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: drf_apischema-0.3.4.tar.gz
  • Upload date:
  • Size: 11.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.26 {"installer":{"name":"uv","version":"0.9.26","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.4.tar.gz
Algorithm Hash digest
SHA256 4fa9f5e7c2c17c9d45b0b7861c413a3894f779dae9904e98b1ed1e078eee3142
MD5 80f1c896cbd4de155141439b35f906bb
BLAKE2b-256 40e27db7579ebb055d9fc5dafb25298b5ac269f8c3072a351dbc3506a006e332

See more details on using hashes here.

File details

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

File metadata

  • Download URL: drf_apischema-0.3.4-py3-none-any.whl
  • Upload date:
  • Size: 16.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.26 {"installer":{"name":"uv","version":"0.9.26","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.4-py3-none-any.whl
Algorithm Hash digest
SHA256 be770a0a9dec82d296275e34a498f8a2e52dd8501fc3cfd71edef4dc7873e27f
MD5 495098e62fbb9df4724c53e228bc00f3
BLAKE2b-256 b5a836840ea7487e5f983a75ef81dbfc477f25aac916d7361aa9f4d854462c06

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