Cookie parameters¶
You can define Cookies parameters
the same way you define Headers,
Path and
Query parameters.
Note
Parsed Cookie parameter must be named parsed_cookies.
This is how you can parse Cookies parameters:
1import msgspec
2
3from dmr import Controller, Cookies
4from dmr.plugins.msgspec import MsgspecSerializer
5
6
7class _CookiesModel(msgspec.Struct):
8 cache: str
9 client_id: int
10
11
12class ApiController(Controller[MsgspecSerializer]):
13 def get(self, parsed_cookies: Cookies[_CookiesModel]) -> _CookiesModel:
14 return parsed_cookies
15
Run result
$ curl http://127.0.0.1:8000/api/users/ -X GET --cookie cache=yes --cookie client_id=1
{"cache":"yes","client_id":1}
$ curl http://127.0.0.1:8000/api/users/ -D - -X GET --cookie cache=yes --cookie client_id=wrong
HTTP/1.1 400 Bad Request
date: Thu, 09 Apr 2026 14:41:12 GMT
server: uvicorn
Content-Type: application/json
X-Frame-Options: DENY
Vary: Accept-Language
Content-Language: en
Content-Length: 103
X-Content-Type-Options: nosniff
Referrer-Policy: same-origin
Cross-Origin-Opener-Policy: same-origin
{"detail":[{"msg":"Expected `int`, got `str` - at `$.parsed_cookies.client_id`","type":"value_error"}]}
OpenAPI Schema
Preview openapi.json
{
"components": {
"schemas": {
"ErrorDetail": {
"description": "Base schema for error details description.",
"properties": {
"loc": {
"items": {
"anyOf": [
{
"type": "integer"
},
{
"type": "string"
}
]
},
"type": "array"
},
"msg": {
"type": "string"
},
"type": {
"type": "string"
}
},
"required": [
"msg"
],
"title": "ErrorDetail",
"type": "object"
},
"ErrorModel": {
"description": "Default error response schema.\n\nCan be customized.\nSee :ref:`customizing-error-messages` for more details.",
"properties": {
"detail": {
"items": {
"$ref": "#/components/schemas/ErrorDetail"
},
"type": "array"
}
},
"required": [
"detail"
],
"title": "ErrorModel",
"type": "object"
},
"_CookiesModel": {
"properties": {
"cache": {
"type": "string"
},
"client_id": {
"type": "integer"
}
},
"required": [
"cache",
"client_id"
],
"title": "_CookiesModel",
"type": "object"
}
},
"securitySchemes": {}
},
"info": {
"title": "Django Modern Rest",
"version": "0.1.0"
},
"openapi": "3.2.0",
"paths": {
"/api/apicontroller/": {
"get": {
"deprecated": false,
"operationId": "getApicontrollerApiApicontroller",
"parameters": [
{
"deprecated": false,
"in": "cookie",
"name": "cache",
"required": true,
"schema": {
"type": "string"
}
},
{
"deprecated": false,
"in": "cookie",
"name": "client_id",
"required": true,
"schema": {
"type": "integer"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/_CookiesModel"
}
}
},
"description": "OK"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorModel"
}
}
},
"description": "Raised when request components cannot be parsed"
},
"406": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorModel"
}
}
},
"description": "Raised when provided `Accept` header cannot be satisfied"
},
"422": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorModel"
}
}
},
"description": "Raised when returned response does not match the response schema"
}
}
}
}
}
}
1import pydantic
2
3from dmr import Controller, Cookies
4from dmr.plugins.pydantic import PydanticSerializer
5
6
7class _CookiesModel(pydantic.BaseModel):
8 cache: str
9 client_id: int
10
11
12class ApiController(Controller[PydanticSerializer]):
13 def get(self, parsed_cookies: Cookies[_CookiesModel]) -> _CookiesModel:
14 return parsed_cookies
15
Run result
$ curl http://127.0.0.1:8000/api/users/ -X GET --cookie cache=yes --cookie client_id=1
{"cache":"yes","client_id":1}
$ curl http://127.0.0.1:8000/api/users/ -D - -X GET --cookie cache=yes --cookie client_id=wrong
HTTP/1.1 400 Bad Request
date: Thu, 09 Apr 2026 14:41:13 GMT
server: uvicorn
Content-Type: application/json
X-Frame-Options: DENY
Vary: Accept-Language
Content-Language: en
Content-Length: 150
X-Content-Type-Options: nosniff
Referrer-Policy: same-origin
Cross-Origin-Opener-Policy: same-origin
{"detail":[{"msg":"Input should be a valid integer, unable to parse string as an integer","loc":["parsed_cookies","client_id"],"type":"value_error"}]}
OpenAPI Schema
Preview openapi.json
{
"components": {
"schemas": {
"ErrorDetail": {
"description": "Base schema for error details description.",
"properties": {
"loc": {
"items": {
"anyOf": [
{
"type": "integer"
},
{
"type": "string"
}
]
},
"title": "Loc",
"type": "array"
},
"msg": {
"title": "Msg",
"type": "string"
},
"type": {
"title": "Type",
"type": "string"
}
},
"required": [
"msg"
],
"title": "ErrorDetail",
"type": "object"
},
"ErrorModel": {
"description": "Default error response schema.\n\nCan be customized.\nSee :ref:`customizing-error-messages` for more details.",
"properties": {
"detail": {
"items": {
"$ref": "#/components/schemas/ErrorDetail"
},
"title": "Detail",
"type": "array"
}
},
"required": [
"detail"
],
"title": "ErrorModel",
"type": "object"
},
"_CookiesModel": {
"properties": {
"cache": {
"title": "Cache",
"type": "string"
},
"client_id": {
"title": "Client Id",
"type": "integer"
}
},
"required": [
"cache",
"client_id"
],
"title": "_CookiesModel",
"type": "object"
}
},
"securitySchemes": {}
},
"info": {
"title": "Django Modern Rest",
"version": "0.1.0"
},
"openapi": "3.2.0",
"paths": {
"/api/apicontroller/": {
"get": {
"deprecated": false,
"operationId": "getApicontrollerApiApicontroller",
"parameters": [
{
"deprecated": false,
"in": "cookie",
"name": "cache",
"required": true,
"schema": {
"title": "Cache",
"type": "string"
}
},
{
"deprecated": false,
"in": "cookie",
"name": "client_id",
"required": true,
"schema": {
"title": "Client Id",
"type": "integer"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/_CookiesModel"
}
}
},
"description": "OK"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorModel"
}
}
},
"description": "Raised when request components cannot be parsed"
},
"406": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorModel"
}
}
},
"description": "Raised when provided `Accept` header cannot be satisfied"
},
"422": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorModel"
}
}
},
"description": "Raised when returned response does not match the response schema"
}
}
}
}
}
}
What happens in this example?
We define a
Cookiesmodel usingmsgspec.Structorpydantic.BaseModel. Other types are also supported:typing.TypedDict,dataclasses.dataclass(), etcNext, we use
Cookiescomponent, provide the model as a type parameter, and subclass it when definingControllertypeThen we use
self.parsed_cookiesthat will have the correct model type
Cookies are case-sensitive.
Customizing OpenAPI metadata for Cookies¶
API Reference¶
- dmr.components.Cookies¶
Annotated alias for parsing cookie parameters.
alias of
Annotated[_CookiesT, <dmr.components.CookiesComponent object at 0x79bd5a37e3a0>]
- class dmr.components.CookiesComponent[source]¶
Bases:
ComponentParserParses the cookies from
django.http.HttpRequest.COOKIES.For example:
>>> import pydantic >>> from dmr import Cookies, Controller >>> from dmr.plugins.pydantic import PydanticSerializer >>> class UserSession(pydantic.BaseModel): ... session_id: int >>> class UserUpdateController(Controller[PydanticSerializer]): ... def get(self, parsed_cookies: Cookies[UserSession]) -> int: ... return parsed_cookies.session_id
Will parse a request header like
Cookie: session_id=123into a modelUserSession.Parameter for
Cookiescomponent must be namedparsed_cookies.- context_name: ClassVar[str] = 'parsed_cookies'¶
All subtypes must provide a unique name that will be used to parse context.
We use a single context for all parsing, this component will live under a dict field with this name.
- get_schema(model: Any, model_meta: tuple[Any, ...], metadata: EndpointMetadata, serializer: type[BaseSerializer], context: OpenAPIContext) → list[Parameter | Reference] | RequestBody[source]¶
Generate OpenAPI spec for component.
- provide_context_data(endpoint: Endpoint, controller: Controller[BaseSerializer], *, field_model: Any) → Any[source]¶
Return unstructured raw values for
serializer.from_python().It must return the same number of elements that has type vars. Basically, each type var is a model. Each element in a tuple is the corresponding data for that model.
When this method returns not a tuple and there’s only one type variable, it also works.