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

drf_apischema-0.3.5.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.5-py3-none-any.whl (16.7 kB view details)

Uploaded Python 3

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

Hashes for drf_apischema-0.3.5.tar.gz
Algorithm Hash digest
SHA256 dc85f1226a1daee665c4ed190f3d48abd127172d7cc52cf89eef55d49863c0b4
MD5 19e3bd1dc807e8b0cb95ca5d9fa335f5
BLAKE2b-256 b039acc3b637f8e5f5f68cbad03af5e9ced0be4b80a8c365f13264e992556dcb

See more details on using hashes here.

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

Hashes for drf_apischema-0.3.5-py3-none-any.whl
Algorithm Hash digest
SHA256 8e54d871d25d89b1b606935601500c72225ca11090b0266b87f0a739098bddd6
MD5 808abd419107a7aae94efc81031565af
BLAKE2b-256 ea9731070f85b9f3c44dfe921f4358722dc094d15a9ccfccdafa83053d074104

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