### Install django-modern-rest with uv, poetry, or pip Source: https://django-modern-rest.readthedocs.io/en/latest/pages/getting-started Demonstrates how to install the django-modern-rest library using three different package managers: uv, poetry, and pip. Ensure you have Python 3.11+ and Django 4.2+ installed. ```shell uv add django-modern-rest ``` ```shell poetry add django-modern-rest ``` ```shell pip install django-modern-rest ``` -------------------------------- ### Run Benchmark Script - Python Source: https://django-modern-rest.readthedocs.io/en/latest/pages/deep-dive/performance This script installs dependencies and runs the benchmark suite for django-modern-rest. It requires a virtual environment and specific requirements to be installed. ```bash python3 -m venv .venv source .venv/bin/activate pip install -r requirements.txt make bench ``` -------------------------------- ### OpenAPI Example Object Definition Source: https://django-modern-rest.readthedocs.io/en/latest/pages/openapi Represents an example value for a schema property. The example value must be compatible with the associated schema type. Tooling may optionally validate this compatibility. ```python from typing import Any class Example( _id : str | None = None, _summary : str | None = None, _description : str | None = None, _value : Any | None = None, _external_value : str | None = None_ ): """Example Object.""" pass ``` -------------------------------- ### POST /users and GET /users with Blueprints Source: https://django-modern-rest.readthedocs.io/en/latest/pages/using-controller Demonstrates how to use Blueprints to define different request body requirements for the same URL based on the HTTP method. GET /users returns a list without a body, while POST /users requires a UserInput body to create a new user. ```APIDOC ## Composing Blueprints into Controllers When modeling your endpoints and data, you might find yourself in a situation when you would need to have different data parsing rules for different endpoints on the same URL: * `GET /users` does not a body and just returns the list of users * `POST /users` requires a request body of some `UserInput` type to create a new user with the pre-defined set of fields To achieve that we have a special composition primitive called `Blueprint`. It is used to define parsing rules / error handling for a set of endpoints that share the same logic. ### Example: views.py ```python import pydantic import uuid from typing import final from django_modern_rest import Blueprint, Body, PydanticSerializer, Controller, BlueprintsT class _UserInput(pydantic.BaseModel): email: str age: int @final class _UserOutput(_UserInput): uid: uuid.UUID @final class UserCreateBlueprint( Body[_UserInput], # <- needs a request body Blueprint[PydanticSerializer], ): def post(self) -> _UserOutput: return _UserOutput( uid=uuid.uuid4(), email=self.parsed_body.email, age=self.parsed_body.age, ) @final class UserListBlueprint( # Does not need a request body. Blueprint[PydanticSerializer], ): def get(self) -> list[_UserInput]: return [ _UserInput(email='first@mail.ru', age=1), _UserInput(email='second@mail.ru', age=2), ] class ComposedController(Controller[PydanticSerializer]): blueprints: ClassVar[BlueprintsT] = [ UserListBlueprint, UserCreateBlueprint, ] ``` ### Request Example - GET /api/composedcontroller/ ```bash curl http://127.0.0.1:8000/api/composedcontroller/ -X GET ``` ### Response Example - GET /api/composedcontroller/ ```json [{"email":"first@mail.ru","age":1},{"email":"second@mail.ru","age":2}] ``` ### Request Example - POST /api/composedcontroller/ ```bash curl http://127.0.0.1:8000/api/composedcontroller/ -X POST -d {"email": "user@wms.org", "age": 10} -H Content-Type: application/json ``` ### Response Example - POST /api/composedcontroller/ ```json {"email":"user@wms.org","age":10,"uid":"9cdea45c-8b1a-4d81-aca2-9dd84272b0b4"} ``` ``` -------------------------------- ### Short-Circuiting with Rate Limiting Example Source: https://django-modern-rest.readthedocs.io/en/latest/pages/middleware This example demonstrates how a middleware can short-circuit a request by returning a response directly, without calling the view. It simulates rate limiting by checking a header and returning a 429 Too Many Requests response if the limit is exceeded. ```APIDOC ## POST /api/example ### Description This endpoint simulates a rate-limited resource. The middleware intercepts the request and returns a `429 Too Many Requests` response if the `X-Rate-Limited` header is set to `true`. ### Method POST ### Endpoint /api/example ### Parameters #### Query Parameters - None #### Request Body - None ### Request Example ```json { "message": "Simulating a request" } ``` ### Response #### Success Response (200) - **message** (str) - A success message indicating the request was processed. #### Error Response (429) - **detail** (str) - A message indicating that the rate limit has been exceeded. #### Response Example (Success) ```json { "message": "Request processed" } ``` #### Response Example (Rate Limited) ```json { "detail": "Rate limit exceeded" } ``` ``` -------------------------------- ### Set Settings Example - django-modern-rest Source: https://django-modern-rest.readthedocs.io/en/latest/pages/configuration Illustrates how to set configuration values by defining the DMR_SETTINGS dictionary. This dictionary should contain keys from the Settings enum. ```python >>> DMR_SETTINGS = {Settings.responses: []} ``` -------------------------------- ### Rate Limit Controller Example Source: https://django-modern-rest.readthedocs.io/en/latest/pages/middleware This example demonstrates how to apply the rate limiting middleware to a Django REST controller. The `rate_limit_json` function is used as a wrapper, and the `RateLimitedController` class is decorated with it, ensuring that requests hitting this controller are subject to the defined rate limiting logic. ```python 1 return_type=dict[str, str], 2 status_code=HTTPStatus.TOO_MANY_REQUESTS, 3 ), 4) 5def rate_limit_json(response: HttpResponse) -> HttpResponse: 6 """Pass through the rate limit response.""" 7 return response 8 9 10@rate_limit_json 11class RateLimitedController(Controller[PydanticSerializer]): 12 """Example controller with custom rate limit middleware.""" 13 14 responses: ClassVar[list[ResponseSpec]] = rate_limit_json.responses 15 16 def post(self) -> dict[str, str]: 17 return {'message': 'Request processed'} ``` -------------------------------- ### Resolve Setting Example - django-modern-rest Source: https://django-modern-rest.readthedocs.io/en/latest/pages/configuration Demonstrates how to retrieve a setting using the resolve_setting function and the Settings enum. This is the primary method for accessing configuration values in django-modern-rest. ```python >>> from django_modern_rest.settings import Settings, resolve_setting >>> resolve_setting(Settings.responses) [] ``` -------------------------------- ### Configure Django URLs for django-modern-rest API Source: https://django-modern-rest.readthedocs.io/en/latest/pages/getting-started Integrates the UserController into the Django project's URL routing using django_modern_rest.routing.Router. This snippet shows how to include the router's URLs into the main urlpatterns. ```python 1 2from django.urls import include, path 3 4from django_modern_rest.routing import Router 5 6 7# Router is just a collection of regular Django urls: 8router = Router([ 9 path( 10 'user/', 11 UserController.as_view(), 12 name='users', 13 ), 14]) 15 16# Just a regular `urlpatterns` definition. 17urlpatterns = [ 18 path('api/', include((router.urls, 'rest_app'), namespace='api')), 19] ``` -------------------------------- ### User API Controller with PydanticSerializer in Django Source: https://django-modern-rest.readthedocs.io/en/latest/pages/getting-started Implements a user controller using PydanticSerializer for request data and headers, leveraging pydantic.BaseModel for data validation. This example showcases typed models for request body and headers in a Django REST API. ```python 1import uuid 2from typing import final 3 4import pydantic 5 6from django_modern_rest import Body, Controller, Headers 7from django_modern_rest.plugins.pydantic import PydanticSerializer 8 9 10class UserCreateModel(pydantic.BaseModel): 11 email: str 12 13 14class UserModel(UserCreateModel): 15 uid: uuid.UUID 16 17 18class HeaderModel(pydantic.BaseModel): 19 consumer: str = pydantic.Field(alias='X-API-Consumer') 20 21 22@final 23class UserController( 24 Controller[PydanticSerializer], 25 Body[UserCreateModel], 26 Headers[HeaderModel], 27): 28 def post(self) -> UserModel: 29 """All added props have the correct runtime and static types.""" 30 assert self.parsed_headers.consumer == 'my-api' 31 return UserModel(uid=uuid.uuid4(), email=self.parsed_body.email) ``` -------------------------------- ### Optimized URL Routing Setup with Django-Modern-REST Router Source: https://django-modern-rest.readthedocs.io/en/latest/pages/routing Illustrates setting up an optimized URL router using `django-modern-rest`'s `Router` and `path` function. This approach aims to improve routing performance by pre-filtering requests based on URL prefixes before applying Django's regex engine. ```python from django_modern_rest.routing import Router, path router = Router( [ path('api/v1/users/', views.UserList.as_view()), path('api/v1/posts/', views.PostList.as_view()), path('api/v1/users//', views.UserDetail.as_view()), ], ) ``` -------------------------------- ### User API Controller with MsgspecSerializer in Django Source: https://django-modern-rest.readthedocs.io/en/latest/pages/getting-started Defines a user controller using MsgspecSerializer for request body and headers, and msgspec.Struct for data modeling. This snippet illustrates runtime and static type checking for request data and headers. ```python 1import uuid 2from typing import final 3 4import msgspec 5 6from django_modern_rest import Body, Controller, Headers 7from django_modern_rest.plugins.msgspec import MsgspecSerializer 8 9 10class UserCreateModel(msgspec.Struct): 11 email: str 12 13 14class UserModel(UserCreateModel): 15 uid: uuid.UUID 16 17 18class HeaderModel(msgspec.Struct): 19 consumer: str = msgspec.field(name='X-API-Consumer') 20 21 22@final 23class UserController( 24 Controller[MsgspecSerializer], 25 Body[UserCreateModel], 26 Headers[HeaderModel], 27): 28 def post(self) -> UserModel: 29 """All added props have the correct runtime and static types.""" 30 assert self.parsed_headers.consumer == 'my-api' 31 return UserModel(uid=uuid.uuid4(), email=self.parsed_body.email) ``` -------------------------------- ### Example of Custom Serializer with Pydantic in Django Modern REST Source: https://django-modern-rest.readthedocs.io/en/latest/pages/deep-dive/public-api This example demonstrates how to create a custom controller (`MyController`) that utilizes Pydantic for serialization. It shows the basic structure, including subclassing `Controller` and specifying `PydanticSerializer` as the serializer type. ```python from http import HTTPStatus from django_modern_rest import Controller, validate from django_modern_rest.plugins.pydantic import ( PydanticSerializer, ) class MyController(Controller[PydanticSerializer]): @validate( ResponseSpec( None, ``` -------------------------------- ### Test User API Endpoint with Curl Source: https://django-modern-rest.readthedocs.io/en/latest/pages/getting-started Provides a curl command to test the POST endpoint of the user API. It sends a JSON payload with an email address and specifies the Content-Type and a custom X-API-Consumer header. ```shell $ curl http://127.0.0.1:8000/api/user/ -X POST -d {"email": "user@wms.org"} -H Content-Type: application/json -H X-API-Consumer: my-api ``` -------------------------------- ### Compose Blueprints into Controller (Python) Source: https://django-modern-rest.readthedocs.io/en/latest/pages/using-controller Demonstrates how to define reusable 'Blueprints' for specific data parsing and error handling logic, and then compose them into a 'Controller'. This allows different request/response schemas for endpoints sharing a URL, like separate handling for GET and POST requests to '/users'. ```python import uuid from typing import final import pydantic from django_modern_rest import (Body, Blueprint, Controller, BlueprintsT, PydanticSerializer) class _UserInput(pydantic.BaseModel): email: str age: int @final class _UserOutput(_UserInput): uid: uuid.UUID @final class UserCreateBlueprint( Body[_UserInput], # <- needs a request body Blueprint[PydanticSerializer], ): def post(self) -> _UserOutput: return _UserOutput( uid=uuid.uuid4(), email=self.parsed_body.email, age=self.parsed_body.age, ) @final class UserListBlueprint( # Does not need a request body. Blueprint[PydanticSerializer], ): def get(self) -> list[_UserInput]: return [ _UserInput(email='first@mail.ru', age=1), _UserInput(email='second@mail.ru', age=2), ] class ComposedController(Controller[PydanticSerializer]): blueprints: ClassVar[BlueprintsT] = [ UserListBlueprint, UserCreateBlueprint, ] ``` -------------------------------- ### Parse Request Body with Body Component Source: https://django-modern-rest.readthedocs.io/en/latest/pages/components Explains how to utilize the `Body` component to parse the request's body into a Pydantic model. The example shows creating an input model for user creation and integrating it with a `Controller`. ```python import pydantic from django_modern_rest import Body, Controller from django_modern_rest.plugins.pydantic import PydanticSerializer class UserCreateInput(pydantic.BaseModel): email: str age: int class UserCreateController( Body[UserCreateInput], Controller[PydanticSerializer], ): ... ``` -------------------------------- ### Testing Pydantic Controllers with Polyfactory and DMRRequestFactory Source: https://django-modern-rest.readthedocs.io/en/latest/pages/testing An example of a pytest test function that utilizes Polyfactory for generating Pydantic model instances and django-modern-rest's DMRRequestFactory to create mock requests. It demonstrates how to test a controller by sending a POST request with generated data and asserting the response. ```python import json from http import HTTPStatus from typing import final from dirty_equals import IsUUID from django.http import HttpResponse from polyfactory.factories.pydantic_factory import ModelFactory from django_modern_rest.test import DMRRequestFactory from examples.testing.pydantic_controller import UserController, UserCreateModel @final class UserCreateModelFactory(ModelFactory[UserCreateModel]): """Will create structured random request data for you.""" __check_model__ = True def test_create_user(dmr_rf: DMRRequestFactory) -> None: request_data = UserCreateModelFactory.build().model_dump(mode='json') request = dmr_rf.post('/url/', data=request_data) response = UserController.as_view()(request) assert isinstance(response, HttpResponse) assert response.status_code == HTTPStatus.CREATED assert response.headers == {'Content-Type': 'application/json'} assert json.loads(response.content) == { 'uid': IsUUID, **request_data, } ``` -------------------------------- ### Rate Limiting Middleware Example Source: https://django-modern-rest.readthedocs.io/en/latest/pages/middleware This Python middleware simulates rate limiting by checking for a specific header. If the 'X-Rate-Limited' header is 'true', it returns a '429 Too Many Requests' response. Otherwise, it proceeds to call the next middleware or view. It utilizes `build_response` for constructing the HTTP response. ```python 1 """Middleware that simulates rate limiting.""" 2 3 def decorator(request: HttpRequest) -> HttpResponse: 4 if request.headers.get('X-Rate-Limited') == 'true': 5 return build_response( 6 PydanticSerializer, 7 raw_data={'detail': 'Rate limit exceeded'}, 8 status_code=HTTPStatus.TOO_MANY_REQUESTS, 9 ) 10 return get_response(request) 11 12 return decorator 13 14 15@wrap_middleware( ``` -------------------------------- ### Use MetaMixin for Default OPTIONS Method Handling Source: https://django-modern-rest.readthedocs.io/en/latest/pages/deep-dive/public-api Demonstrates how to use the 'MetaMixin' from 'django_modern_rest.options_mixins' to automatically provide a default implementation for the OPTIONS HTTP method. This approach simplifies controller definitions by inheriting the default behavior. ```python >>> from django_modern_rest.options_mixins import MetaMixin >>> class ControllerWithMeta( ... MetaMixin, ... Controller[PydanticSerializer], ... ): ... ``` -------------------------------- ### Complete CSRF Protection Setup in Django REST API Source: https://django-modern-rest.readthedocs.io/en/latest/pages/middleware This Python code demonstrates a full CSRF protection setup for a Django REST API. It utilizes `django-modern-rest` and Django's built-in CSRF functionalities. The setup includes a decorator to ensure CSRF cookies are set for GET requests and a controller that requires CSRF protection for POST requests. Dependencies include `django`, `django-modern-rest`, and `uvicorn` for running the server. ```python from http import HTTPStatus from typing import ClassVar from django.http import HttpResponse from django.views.decorators.csrf import ensure_csrf_cookie from django_modern_rest import Controller, ResponseSpec from django_modern_rest.decorators import wrap_middleware from django_modern_rest.plugins.pydantic import PydanticSerializer from examples.middleware.csrf_protect_json import csrf_protect_json # CSRF cookie for GET requests @wrap_middleware( ensure_csrf_cookie, ResponseSpec( return_type=dict[str, str], status_code=HTTPStatus.OK, ), ) def ensure_csrf_cookie_json(response: HttpResponse) -> HttpResponse: """Return response ensuring CSRF cookie is set.""" return response @csrf_protect_json class ProtectedController(Controller[PydanticSerializer]): """Protected API controller requiring CSRF token.""" responses: ClassVar[list[ResponseSpec]] = csrf_protect_json.responses def get(self) -> dict[str, str]: """Get CSRF token.""" return {'message': 'Use this endpoint to get CSRF token'} def post(self) -> dict[str, str]: """Protected endpoint requiring CSRF token.""" return {'message': 'Successfully created resource'} @ensure_csrf_cookie_json class PublicController(Controller[PydanticSerializer]): responses: ClassVar[list[ResponseSpec]] = ensure_csrf_cookie_json.responses def get(self) -> dict[str, str]: """Public endpoint that sets CSRF cookie.""" return {'message': 'CSRF cookie set'} ``` -------------------------------- ### Benchmark Routing Replacement - Make Source: https://django-modern-rest.readthedocs.io/en/latest/pages/deep-dive/performance This command uses 'make' to benchmark the routing replacement feature of django-modern-rest. It specifically targets the 'bench-resolver' target within the benchmarks directory. ```bash make -C benchmarks bench-resolver ``` -------------------------------- ### Define OpenAPI Media Type Object - Python Source: https://django-modern-rest.readthedocs.io/en/latest/pages/openapi Defines the structure for a Media Type Object, which provides schema and examples for a specific media type. It includes optional fields for schema, example, examples, and encoding. ```python class MediaType(_*_, _schema : Reference | Schema | None = None_, _example : Any | None = None_, _examples : dict[str, Example | Reference] | None = None_, _encoding : dict[str, Encoding] | None = None_): """Media Type Object.""" pass ``` -------------------------------- ### Defining OPTIONS or meta method Source: https://django-modern-rest.readthedocs.io/en/latest/pages/using-controller Explains how to handle the OPTIONS HTTP method using the `meta` controller method as a replacement for Django's default `options()` to avoid signature conflicts. It covers defining a custom `meta` implementation and using `MetaMixin`. ```APIDOC ## Defining OPTIONS or meta method RFC 9110 defines the `OPTIONS` HTTP method, but sadly Django’s `View` which we use as a base class for all controllers, already have `django.views.generic.base.View.options()` method. It would generate a typing error to redefine it with a different signature that we need for our endpoints. That’s why we created `meta` controller method as a replacement for older `options` name. ### Option 1: Define a custom `meta` endpoint To use it you have two options: 1. Define the `meta` endpoint yourself and provide an implementation 2. Use `MetaMixin` or `AsyncMetaMixin` with the default implementation: which provides `Allow` header with all the allowed HTTP methods in this controller #### Example: Custom `meta` implementation ```python from http import HTTPStatus from typing import final from django.http import HttpResponse from django_modern_rest import ( Controller, HeaderSpec, ResponseSpec, validate, ) from django_modern_rest.plugins.msgspec import MsgspecSerializer @final class SettingsController(Controller[MsgspecSerializer]): def get(self) -> str: return 'default get setting' def post(self) -> str: return 'default post setting' # `meta` response is also validated, schema is required: @validate( ResponseSpec( None, status_code=HTTPStatus.NO_CONTENT, headers={'Allow': HeaderSpec()}, ), ) def meta(self) -> HttpResponse: # Handles `OPTIONS` http method return self.to_response( None, status_code=HTTPStatus.NO_CONTENT, headers={ 'Allow': ', '.join( method for method in sorted(self.api_endpoints.keys()) ), }, ) ``` ### Request Example - OPTIONS /api/settings/ ```bash curl http://127.0.0.1:8000/api/settings/ -D - -X OPTIONS ``` ### Response Example - OPTIONS /api/settings/ ``` HTTP/1.1 204 No Content date: Wed, 07 Jan 2026 09:29:56 GMT server: uvicorn Allow: GET, OPTIONS, POST Content-Type: application/json ``` See how you can use Handling meta endpoint with `compose_blueprints()`. ``` -------------------------------- ### MsgspecSerializer Plugin for Serialization Source: https://django-modern-rest.readthedocs.io/en/latest/pages/deep-dive/public-api The MsgspecSerializer plugin offers serialization and deserialization capabilities using the msgspec library for django-modern-rest. This feature is optional and can be enabled by installing with 'pip install "django-modern-rest[msgspec]"'. ```python from django_modern_rest.plugins.msgspec import MsgspecSerializer # Example usage would involve instantiating and using the serializer # serializer = MsgspecSerializer() # data = serializer.serialize(my_object) # obj = serializer.deserialize(data, target_type) ``` -------------------------------- ### Dynamic Route Matching with Prefix Pre-filtering in Django-Modern-REST Source: https://django-modern-rest.readthedocs.io/en/latest/pages/routing Demonstrates the optimized matching process for dynamic routes in `django-modern-rest`. It highlights how prefix checking filters out non-matching URLs before resorting to Django's regex engine for parameter extraction. ```python path('api/v1/users//', view) ``` -------------------------------- ### PydanticSerializer Plugin for Serialization Source: https://django-modern-rest.readthedocs.io/en/latest/pages/deep-dive/public-api The PydanticSerializer plugin enables serialization and deserialization of objects using the Pydantic library within django-modern-rest. Pydantic support is optional and can be installed by running 'pip install "django-modern-rest[pydantic]"'. ```python from django_modern_rest.plugins.pydantic import PydanticSerializer # Example usage would involve instantiating and using the serializer # serializer = PydanticSerializer() # data = serializer.serialize(my_object) # obj = serializer.deserialize(data, target_model) ``` -------------------------------- ### Plugins API Source: https://django-modern-rest.readthedocs.io/en/latest/pages/deep-dive/public-api Information on available serialization plugins. ```APIDOC ## Plugins API ### Serialization Plugins - `PydanticSerializer` - `MsgspecSerializer` ``` -------------------------------- ### Decorators and Testing API Source: https://django-modern-rest.readthedocs.io/en/latest/pages/deep-dive/public-api Information on decorators for request handling and utilities for testing API endpoints. ```APIDOC ## Decorators and Testing API ### Decorators - `dispatch_decorator()` - `endpoint_decorator()` - `wrap_middleware()` ### Testing - `DMRRequestFactory`: Factory for creating test requests. - `DMRAsyncRequestFactory`: Factory for creating asynchronous test requests. - `DMRClient`: Client for making test requests. - `DMRAsyncClient`: Asynchronous client for making test requests. ``` -------------------------------- ### MsgspecSerializer Source: https://django-modern-rest.readthedocs.io/en/latest/pages/deep-dive/public-api A plugin for serializing and deserializing objects using Msgspec. Msgspec support is optional and requires a separate installation. ```APIDOC ## MsgspecSerializer ### Description Serialize and deserialize objects using msgspec. ### Installation Msgspec support is optional. To install it run: ```bash pip install 'django-modern-rest[msgspec]' ``` ### Class `django_modern_rest.plugins.msgspec.MsgspecSerializer` ### Usage (Specific usage details would typically follow, e.g., how to integrate it with views or serializers. This is a placeholder.) ``` -------------------------------- ### Implement Async OPTIONS HTTP Method with AsyncMetaMixin (Django) Source: https://django-modern-rest.readthedocs.io/en/latest/pages/deep-dive/public-api This mixin provides a default meta method or OPTIONS HTTP method for async controllers. It returns the list of allowed methods and is used as a mixin with django_modern_rest.controller.Controller. It requires importing Controller and PydanticSerializer. ```python from django_modern_rest import Controller from django_modern_rest.options_mixins import AsyncMetaMixin from django_modern_rest.plugins.pydantic import PydanticSerializer class SupportsOptionsHttpMethod( AsyncMetaMixin, Controller[PydanticSerializer], ): ... ``` -------------------------------- ### Implement OPTIONS HTTP Method with MetaMixin (Django) Source: https://django-modern-rest.readthedocs.io/en/latest/pages/deep-dive/public-api This mixin provides a default meta method or OPTIONS HTTP method for sync controllers. It returns the list of allowed methods and is used as a mixin with django_modern_rest.controller.Controller. It requires importing Controller and PydanticSerializer. ```python from django_modern_rest import Controller from django_modern_rest.options_mixins import MetaMixin from django_modern_rest.plugins.pydantic import PydanticSerializer class SupportsOptionsHttpMethod( MetaMixin, Controller[PydanticSerializer], ): ... ``` -------------------------------- ### PydanticSerializer Source: https://django-modern-rest.readthedocs.io/en/latest/pages/deep-dive/public-api A plugin for serializing and deserializing objects using Pydantic models. Pydantic support is optional and can be installed separately. ```APIDOC ## PydanticSerializer ### Description Serialize and deserialize objects using pydantic. ### Installation Pydantic support is optional. To install it run: ```bash pip install 'django-modern-rest[pydantic]' ``` ### Class `django_modern_rest.plugins.pydantic.PydanticSerializer` ### Usage (Specific usage details would typically follow, e.g., how to integrate it with views or serializers. This is a placeholder.) ``` -------------------------------- ### POST /api/user/ Source: https://django-modern-rest.readthedocs.io/en/latest/pages/returning-responses Creates a new user with the provided email. It validates the 'X-API-Consumer' header and returns either the user model or an error. ```APIDOC ## POST /api/user/ ### Description This endpoint creates a new user. It expects an 'X-API-Consumer' header to be 'my-api'. If the header is incorrect, it returns a 406 Not Acceptable error. Otherwise, it returns the created user object. ### Method POST ### Endpoint /api/user/ ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **email** (string) - Required - The email address of the user. ### Request Example ```json { "email": "user@wms.org" } ``` ### Headers - **X-API-Consumer** (string) - Required - The consumer identifier for the API. ### Response #### Success Response (200) - **email** (string) - The email address of the created user. #### Error Response (406 Not Acceptable) - **detail** (string) - Description of the error, e.g., 'Wrong API consumer'. #### Response Example (Success) ```json { "email": "user@wms.org" } ``` #### Response Example (Error) ```json { "detail": "Wrong API consumer" } ``` ``` -------------------------------- ### Manual Benchmark - ApacheBench (ab) Source: https://django-modern-rest.readthedocs.io/en/latest/pages/deep-dive/performance This command uses ApacheBench to perform load testing on a django-modern-rest API endpoint. It specifies concurrency, number of requests, payload, headers, and content type. ```bash ab -c 20 -n 1000 -l -p payload.json \ -H 'X-API-Token: some-token-example' \ -H 'X-Request-Origin: some-origin' \ -T 'application/json' \ 'http://127.0.0.1:8000/async/user/?per_page=1&count=2&page=3&filter=abc' ``` -------------------------------- ### Define Response Header Specification - Python Source: https://django-modern-rest.readthedocs.io/en/latest/pages/deep-dive/public-api Specifies an existing header in `django.http.HttpResponse` for documentation and validation purposes. It includes description, deprecation status, example, and a flag for whether it's required. ```python class HeaderSpec( _*, _description : str | None = None, _deprecated : bool = False, _example : str | None = None, _required : bool = True ): """Existing header that `django.http.HttpResponse` already has.""" pass ``` -------------------------------- ### Middleware Wrappers Source: https://django-modern-rest.readthedocs.io/en/latest/pages/deep-dive/internal-api Enables applying decorators with response specifications to classes. ```APIDOC ## Class: DecoratorWithResponses ### Description Type for a decorator with a 'responses' attribute, intended for applying to classes. ### Method __call__ ### Parameters - **klass** (_TypeT) - The class to which the decorator is applied. ### Description Applies the decorator to the provided class. ``` -------------------------------- ### Routing and Meta Mixins API Source: https://django-modern-rest.readthedocs.io/en/latest/pages/deep-dive/public-api Information on how to define routes and use meta mixins for endpoint configuration. ```APIDOC ## Routing and Meta Mixins API ### Routing - `Router`: Class for defining API routing. - `compose_blueprints(blueprints)`: Composes multiple blueprints into a single router. - `path(url, methods, endpoint)`: Decorator to define a path for an endpoint. ``` -------------------------------- ### Define New Response Header - Python Source: https://django-modern-rest.readthedocs.io/en/latest/pages/deep-dive/public-api Defines a new header to be added to `django.http.HttpResponse`. This class is used to specify the header's description, deprecation status, example, and its value. It is not used for validation. ```python class NewHeader( _*, _description : str | None = None, _deprecated : bool = False, _example : str | None = None, _value : str ): """New header that will be added to `django.http.HttpResponse` by us.""" def to_spec(self) -> HeaderSpec: """Convert header type.""" pass ``` -------------------------------- ### Customizing `login_required` for REST APIs Source: https://django-modern-rest.readthedocs.io/en/latest/pages/middleware This example shows how to wrap Django's `login_required` decorator to convert its default 302 redirect into a JSON 401 Unauthorized response, making it compatible with REST APIs. ```APIDOC ## GET /api/protected ### Description This endpoint requires user authentication. If the user is not logged in, the middleware intercepts the `FOUND` status code from `login_required` and returns a JSON response with `401 Unauthorized`. ### Method GET ### Endpoint /api/protected ### Parameters #### Path Parameters - None #### Query Parameters - None #### Request Body - None ### Request Example ```json { "example": "No request body needed for this GET request" } ``` ### Response #### Success Response (200) - **username** (str) - The username of the authenticated user. - **message** (str) - A confirmation message indicating successful access. #### Error Response (401) - **detail** (str) - A message indicating that authentication credentials were not provided. #### Response Example (Success) ```json { "username": "testuser", "message": "Successfully accessed protected resource" } ``` #### Response Example (Unauthorized) ```json { "detail": "Authentication credentials were not provided" } ``` ``` -------------------------------- ### compose_blueprints Source: https://django-modern-rest.readthedocs.io/en/latest/pages/deep-dive/public-api Combines multiple blueprints with different HTTP methods into a single controller for use in a URL route. ```APIDOC ## Function: compose_blueprints ### Description Combines several blueprints with different http methods into one controller. This can be used as a single URL route. ### Parameters - `first_blueprint` (_BlueprintT[_SerializerT]): The first required blueprint class to compose. - `extra` (*BlueprintT[_SerializerT]): Other optional blueprint classes to compose. - `meta_mixin` (type[MetaMixin | AsyncMetaMixin] | None): Type to add to support `OPTIONS` method. ### Raises - `EndpointMetadataError`: When blueprint validation fails. ### Returns - `type[Controller[_SerializerT]]`: A new controller class that has all the endpoints from all composed blueprints. ``` -------------------------------- ### Compose Controllers with AsyncMetaMixin in Django-Modern-REST Source: https://django-modern-rest.readthedocs.io/en/latest/pages/routing Demonstrates how to compose multiple controllers, such as UserPut and UserPatch, into a single routed endpoint. It shows the use of `meta_mixin` to handle meta endpoints, specifically with `AsyncMetaMixin` for asynchronous controllers. This prevents import-time errors from duplicate meta methods. ```python from django_modern_rest import AsyncMetaMixin composed = compose_blueprints( UserPut, UserPatch, # If controllers are sync, use `MetaMixin` meta_mixin=AsyncMetaMixin, ) ``` -------------------------------- ### Parse Query String with Query Component Source: https://django-modern-rest.readthedocs.io/en/latest/pages/components Illustrates using the `Query` component to parse URL query parameters into a Pydantic model. It provides an example of defining a query model and associating it with a `Controller` for automatic parsing. ```python import pydantic from django_modern_rest import Query, Controller from django_modern_rest.plugins.pydantic import PydanticSerializer class ProductQuery(pydantic.BaseModel): category: str reversed: bool class ProductListController( Query[ProductQuery], Controller[PydanticSerializer], ): ... ``` -------------------------------- ### Controller Initialization and Blueprint Collection in Django Source: https://django-modern-rest.readthedocs.io/en/latest/pages/deep-dive/public-api This method is called during subclass initialization and is responsible for collecting any associated blueprints. It's a crucial step for setting up the controller's structure based on defined blueprints. ```python _classmethod ___init_subclass__() -> None ``` -------------------------------- ### Curl POST Request with Valid Headers Source: https://django-modern-rest.readthedocs.io/en/latest/pages/returning-responses Example of using curl to send a POST request to the user API endpoint with valid JSON body and the correct 'X-API-Consumer' header. This demonstrates a successful API interaction. ```bash curl http://127.0.0.1:8000/api/user/ -X POST -d {"email": "user@wms.org"} -H Content-Type: application/json -H X-API-Consumer: my-api {"email":"user@wms.org"} ``` -------------------------------- ### Global Response Specification - django-modern-rest Source: https://django-modern-rest.readthedocs.io/en/latest/pages/configuration Configures global response specifications for all endpoints in django-modern-rest. This example sets a global 500 Internal Server Error response schema, allowing for consistent error handling across the API. ```python >>> from http import HTTPStatus >>> from typing_extensions import TypedDict >>> from django_modern_rest.response import ResponseSpec >>> class Error(TypedDict): ... detail: str >>> # If our API can always return a 500 response with `{\"detail\": str}` >>> # error message: >>> DMR_SETTINGS = { ... Settings.responses: [ ... ResponseSpec( ... Error, ... status_code=HTTPStatus.INTERNAL_SERVER_ERROR, ... ), ... ], ... } ``` -------------------------------- ### DMRAsyncClient Source: https://django-modern-rest.readthedocs.io/en/latest/pages/deep-dive/public-api An asynchronous version of DMRClient, designed for testing applications within an ASGI environment. It requires awaiting calls to methods like .get(), .post(), etc., providing a seamless testing experience for async APIs. ```APIDOC ## DMRAsyncClient ### Description Async version of `DMRClient`. Uses `async` API. Requires you to `await` calls to `.get`, `.post`, etc. ### Class `django_modern_rest.test.DMRAsyncClient` ### Parameters - `enforce_csrf_checks` (bool) - Optional - Whether to enforce CSRF checks. Defaults to `False`. - `raise_request_exception` (bool) - Optional - Whether to raise exceptions during request processing. Defaults to `True`. - `headers` (dict) - Optional - Default headers to include in requests. - `query_params` (dict) - Optional - Default query parameters to include in requests. - `**defaults` - Arbitrary keyword arguments for further customization. ### Usage Example ```python import asyncio from django.test import TestCase from django_modern_rest.test import DMRAsyncClient class MyAsyncClientTests(TestCase): def setUp(self): self.async_client = DMRAsyncClient() async def test_async_post_data(self): response = await self.async_client.post('/async-api/resource/', data={'data': 'example'}) self.assertEqual(response.status_code, 200) ``` ``` -------------------------------- ### Define OpenAPI Path Item Object - Python Source: https://django-modern-rest.readthedocs.io/en/latest/pages/openapi Describes the operations available on a single path in an API. It can define operations like GET, POST, PUT, DELETE, etc., and also associate parameters with the path. ```python class PathItem(_*_, _ref : str | None = None_, _summary : str | None = None_, _description : str | None = None_, _get : Operation | None = None_, _put : Operation | None = None_, _post : Operation | None = None_, _delete : Operation | None = None_, _options : Operation | None = None_, _head : Operation | None = None_, _patch : Operation | None = None_, _trace : Operation | None = None_, _servers : list[Server] | None = None_, _parameters : list[Parameter | Reference] | None = None_): """Describes the operations available on a single path.""" pass ``` -------------------------------- ### Controller API Source: https://django-modern-rest.readthedocs.io/en/latest/pages/deep-dive/public-api Details on the `Blueprint` and `Controller` classes, including their attributes and methods for defining API endpoints and handling requests. ```APIDOC ## Controller API ### Blueprint Class Provides a blueprint for defining API endpoints. #### Attributes - `endpoint_cls` (type): The endpoint class to use. - `serializer` (type): The default serializer. - `serializer_context_cls` (type): The serializer context class. - `blueprint_validator_cls` (type): The validator class for the blueprint. - `no_validate_http_spec` (bool): Whether to skip HTTP spec validation. - `validate_responses` (bool): Whether to validate responses. - `responses` (dict): Defined responses. - `responses_from_components` (list): Responses defined in components. - `http_methods` (list): Allowed HTTP methods. - `request` (type): The request object. - `args` (tuple): Positional arguments. - `kwargs` (dict): Keyword arguments. ### Controller Class Manages a collection of blueprints and handles request dispatching. #### Attributes - `endpoint_cls` (type): The endpoint class to use. - `serializer` (type): The default serializer. - `serializer_context_cls` (type): The serializer context class. - `blueprint_validator_cls` (type): The validator class for blueprints. - `controller_validator_cls` (type): The validator class for the controller. - `api_endpoints` (dict): Dictionary of API endpoints. - `no_validate_http_spec` (bool): Whether to skip HTTP spec validation. - `validate_responses` (bool): Whether to validate responses. - `responses` (dict): Defined responses. - `responses_from_components` (list): Responses defined in components. - `http_methods` (list): Allowed HTTP methods. - `request` (type): The request object. - `args` (tuple): Positional arguments. - `kwargs` (dict): Keyword arguments. - `blueprints` (list): List of blueprints. #### Methods - `as_view()`: Returns the view function for the controller. - `dispatch()`: Dispatches the incoming request. - `handle_async_error()`: Handles asynchronous errors. - `handle_error()`: Handles errors. - `handle_method_not_allowed()`: Handles method not allowed errors. - `http_method_not_allowed()`: Handles HTTP method not allowed. - `options()`: Handles OPTIONS requests. - `semantic_responses()`: Returns semantic responses. - `setup()`: Sets up the controller. - `to_error()`: Converts an exception to an error response. - `to_response()`: Converts data to a response. ``` -------------------------------- ### Runtime Response Validation Error - django-modern-rest Source: https://django-modern-rest.readthedocs.io/en/latest/pages/configuration Illustrates a scenario where runtime response validation in django-modern-rest would catch an error. The `get` method is typed to return a list of strings, but it returns a list of integers, triggering both static and runtime errors. ```python >>> from django_modern_rest import Controller >>> from django_modern_rest.plugins.pydantic import PydanticSerializer >>> class MyController(Controller[PydanticSerializer]): ... def get(self) -> list[str]: ... return [1, 2] # <- both static typing and runtime error ``` -------------------------------- ### path Source: https://django-modern-rest.readthedocs.io/en/latest/pages/deep-dive/public-api Utility function to create URL patterns for routing, supporting different view types and configurations. ```APIDOC ## Function: path ### Description Creates URL pattern using prefix-based matching for faster routing. ### Parameters - `_route` (str): The URL route pattern. - `_view` (Callable | tuple | Sequence): The view function, tuple, or sequence defining the view. - `_kwargs` (dict[str, Any] | None): Optional keyword arguments for the view. - `_name` (str | None): Optional name for the URL pattern. ### Returns - `URLPattern | URLResolver`: A URL pattern or resolver object. ``` -------------------------------- ### Example Usage of @modify Decorator in Django Controller Source: https://django-modern-rest.readthedocs.io/en/latest/pages/deep-dive/public-api This Python code snippet demonstrates a practical application of the `@modify` decorator within a Django controller. It shows how to set a specific HTTP status code for a POST endpoint that returns a list of integers, customizing the API response behavior. ```python from http import HTTPStatus from django_modern_rest import Controller, modify from django_modern_rest.plugins.pydantic import PydanticSerializer class TaskController(Controller[PydanticSerializer]): @modify(status_code=HTTPStatus.ACCEPTED) def post(self) -> list[int]: return [1, 2] # id of tasks you have started ``` -------------------------------- ### Curl POST Request with Invalid Headers and Response Source: https://django-modern-rest.readthedocs.io/en/latest/pages/returning-responses Example of using curl to send a POST request to the user API endpoint with a JSON body but an incorrect 'X-API-Consumer' header. This demonstrates how the API returns a 406 Not Acceptable error with a specific JSON response. ```bash curl http://127.0.0.1:8000/api/user/ -D - -X POST -d {"email": "user@wms.org"} -H Content-Type: application/json -H X-API-Consumer: not-my-api HTTP/1.1 406 Not Acceptable date: Wed, 07 Jan 2026 09:29:56 GMT server: uvicorn Content-Type: application/json Transfer-Encoding: chunked {"detail":"Wrong API consumer"} ``` -------------------------------- ### wrap_middleware Source: https://django-modern-rest.readthedocs.io/en/latest/pages/deep-dive/public-api Factory function to create a decorator with pre-configured middleware and response handling. ```APIDOC ## wrap_middleware ### Description Factory function that creates a decorator with pre-configured middleware and response handling. This allows creating reusable decorators with specific middleware and response handling. ### Method Factory Function ### Endpoint N/A (Used to create decorators) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters (of the decorator created by wrap_middleware) #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```python from django.views.decorators.csrf import csrf_protect from django.http import HttpResponse from http import HTTPStatus from django_modern_rest import Controller, ResponseSpec from django_modern_rest.response import build_response from django_modern_rest.plugins.pydantic import PydanticSerializer from django_modern_rest.decorators import wrap_middleware @wrap_middleware( csrf_protect, ResponseSpec( return_type=dict[str, str], status_code=HTTPStatus.FORBIDDEN, ), ) def csrf_protect_json(response: HttpResponse) -> HttpResponse: return build_response( PydanticSerializer, raw_data={ 'detail': 'CSRF verification failed. Request aborted.' }, status_code=HTTPStatus(response.status_code), ) @csrf_protect_json class MyController(Controller[PydanticSerializer]): responses = [ *csrf_protect_json.responses, ] def post(self) -> dict[str, str]: return {'message': 'ok'} ``` ### Response #### Success Response (200) Depends on the controller's methods and any applied decorators. #### Response Example (Depends on the controller's methods and applied decorators.) ```