
Research
Security News
The Landscape of Malicious Open Source Packages: 2025 Mid‑Year Threat Report
A look at the top trends in how threat actors are weaponizing open source packages to deliver malware and persist across the software supply chain.
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.
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
Install drf-apischema
from PyPI
pip install drf-apischema
Configure your project settings.py
like this
INSTALLED_APPS = [
# ...
"rest_framework",
"drf_spectacular",
# ...
]
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',
}
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_path
from .views import *
router = DefaultRouter()
router.register("test", TestViewSet, basename="test")
urlpatterns = [
# Auto-generate /api/schema/, /api/schema/swagger/ and /api/schema/redoc/ for documentation
api_path("api/", [path("", include(router.urls))])
]
settings.py
DRF_APISCHEMA_SETTINGS = {
# Enable transaction wrapping for APIs
"TRANSACTION": True,
# Enable SQL logging
"SQL_LOGGING": True,
# 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": True,
}
See branch drf-yasg, it is not longer supported
permission_classes
Wrap the view with apischema_view
.
@apischema_view()
class XxxViewSet(GenericViewSet):
permissions_classes = [IsAuthenticated]
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:
...
FAQs
API schema generator and validator for Django REST framework
We found that drf-apischema demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
A look at the top trends in how threat actors are weaponizing open source packages to deliver malware and persist across the software supply chain.
Security News
ESLint now supports HTML linting with 48 new rules, expanding its language plugin system to cover more of the modern web development stack.
Security News
CISA is discontinuing official RSS support for KEV and cybersecurity alerts, shifting updates to email and social media, disrupting automation workflows.