Skip to content

Controllers and operations

Everything a controller, an operation decorator, routes and mount() accept. Options merge in this order, later layers winning: NINJA_DEVX["DEFAULT_OPTIONS"], Controller.options along the MRO, as_router(**options), operation options. See the Controllers guide.

Controller class attributes

Base class for class-based Django Ninja controllers.

Name Type Default Description
scope Scope Scope.REQUEST Scope.REQUEST: a controller per request (inside the DI scope); Scope.SINGLETON: one per as_router() call.
mode Literal['sync', 'async', 'auto'] 'sync' Which implementation to register when an operation has an async_variant; "auto" follows NINJA_DEVX["ASYNC_MODE"].
routes Mapping[str, RouteOptions] MappingProxyType({}) Overrides per operation name: {"bulk_create": {"path": "/batch"}, "destroy": {"enabled": False}, "list": {"summary": "Posts"}}. Unknown names fail at startup.
options ControllerOptions ControllerOptions() Merged along the MRO over NINJA_DEVX["DEFAULT_OPTIONS"], then as_router(**options).

Controller.as_router()

def as_router(*, container: ContainerLike | None = None, scope: Scope | None = None, **options: Unpack[ControllerOptions]) -> Router: ...

Build a new native Ninja Router exposing this controller's operations.

Parameter Type Default Description
container ContainerLike \| None None Builds controllers and Inject[...] values: a Container, a dishka/svcs resolver, or any Resolver/RequestScopeProvider.
scope Scope \| None None Overrides the class's scope for this router.
**options Unpack[ControllerOptions] — ControllerOptions over the class's options.

ControllerOptions

Defaults for every operation of a controller.

Name Type Default Description
auth AuthSpec — Ninja authentication for every operation (django_auth, JWTAuth(), a list, or None).
throttle ThrottleSpec — Ninja throttles for every operation (UserRateThrottle("100/min") or a list).
tags Sequence[str] — OpenAPI tags.
permissions Sequence[AnyPermission] — Permissions checked before each operation (see Also for adding at operation level).
decorators Sequence[ViewDecorator] — View decorators (paginate(...), conditional()); the first item is outermost.
hooks Sequence[OperationHook \| AsyncOperationHook] — Operation hooks wrapping each call (sync around or async around_async).
atomic bool \| Literal['durable'] — Run sync operations in transaction.atomic(); "durable" must be the outermost.
database str — Database alias for atomic.
errors ErrorMap — Exception rules for every operation (see ninja_devx.http.errors).
meta Sequence[object] — Typed metadata read with get_operation(request).meta(Kind).
plugins Sequence[ControllerPlugin] — ControllerPlugin objects applied to every operation.
middleware Sequence[Middleware] — Router middleware around every operation, including auth and throttling (RequestIDMiddleware(), DeprecationMiddleware(sunset=...)).
allow_mixed_path bool — Silence the warning for a path served by both sync and async operations.
deprecated bool — Mark every operation deprecated in OpenAPI.
document_errors bool — Document 401/403/404/422 responses in OpenAPI (default from settings).
by_alias bool — Serialize responses by field alias (Ninja).
exclude_unset bool — Leave unset fields out of responses (Ninja).
exclude_defaults bool — Leave fields equal to their default out of responses (Ninja).
exclude_none bool — Leave None fields out of responses (Ninja).
operation_id_prefix str — Prepended to every operation id (mount(prefix=...) sets it for versions).
url_name_prefix str — Prepended (with _) to explicit url_name values.

api_operation()

def api_operation(methods: str | Sequence[str], path: str = '/', **options: Unpack[OperationOptions]) -> Callable[[OperationMethod[C, RequestT, P, R]], OperationMethod[C, RequestT, P, R]]: ...

Mark a controller method as an operation for the given HTTP methods.

Parameter Type Default Description
methods str \| Sequence[str] — HTTP methods, e.g. ["GET", "HEAD"].
path str '/' Path relative to the router; {name} segments become parameters.
**options Unpack[OperationOptions] — OperationOptions: Ninja's operation keywords plus ninja-devx's.

get(path="/", **options), post(...), put(...), patch(...) and delete(...) take the same path and options as api_operation.

OperationOptions

Keyword arguments accepted by every operation decorator.

Name Type Default Description
auth AuthSpec — Ninja authentication for this operation; overrides the controller's.
throttle ThrottleSpec — Ninja throttles for this operation.
response ResponseSpec — Response schema, or {status: schema} (Ninja).
operation_id str \| None — OpenAPI operation id (default <controller>_<method>).
summary str \| None — OpenAPI summary.
description str \| None — OpenAPI description (default: the method docstring).
tags list[str] \| None — OpenAPI tags.
deprecated bool \| None — Mark the operation deprecated in OpenAPI.
by_alias bool \| None — Serialize the response by field alias (Ninja).
exclude_unset bool \| None — Leave unset fields out of the response (Ninja).
exclude_defaults bool \| None — Leave fields equal to their default out of the response (Ninja).
exclude_none bool \| None — Leave None fields out of the response (Ninja).
url_name str \| None — Django URL name for reverse().
include_in_schema bool — Show the operation in OpenAPI.
openapi_extra dict[str, JSONValue] \| None — Merged into the operation's OpenAPI object.
permissions Sequence[AnyPermission] — Replaces the controller's permissions; Also(...) adds to them instead.
decorators Sequence[ViewDecorator] — View decorators applied inside the controller's ones; the first item is outermost.
hooks Sequence[OperationHook \| AsyncOperationHook] — Operation hooks run inside the controller's hooks.
atomic bool \| Literal['durable'] — Run the operation in transaction.atomic() ("durable": must be the outermost).
database str — Database alias for atomic.
errors ErrorMap — Exception rules for this operation, over the controller's.
raises Sequence[type[BaseException]] — Exceptions this operation may raise: documented in OpenAPI, checked against the rules.
meta Sequence[object] — Typed metadata read by permissions and hooks via get_operation(request).meta(Kind).
document_errors bool — Document 401/403/404/422 responses in OpenAPI (default from settings).

RouteOptions

Per-operation overrides in Controller.routes (paths and options are not hard-coded).

Also accepts every OperationOptions key.

Name Type Default Description
path str — Replaces the declared path, e.g. {"restore": {"path": "/{pk}/undelete"}}.
enabled bool — False removes the operation from the router.

async_variant()

def async_variant(sync_method: Callable[..., object]) -> Callable[[AsyncF], AsyncF]: ...

Declare the async implementation of an operation, used when the controller runs async.

Parameter Type Default Description
sync_method Callable[..., object] — The sync operation this async method implements.

use_case()

def use_case(decorator: Callable[[Method], Method], handler: Callable[..., UseCase[CommandT, ResultT] | UseCase[CommandT, Awaitable[ResultT]]], *, command: Callable[[PayloadT], CommandT], status: int | None = None) -> Method: ...

An operation method: map the payload with command and call the resolved handler.

Parameter Type Default Description
decorator Callable[[Method], Method] — The operation decorator, e.g. post("/", response={201: OrderOut}).
handler Callable[..., UseCase[CommandT, ResultT] \| UseCase[CommandT, Awaitable[ResultT]]] — A class with __call__(command) (sync or async), resolved from the container.
command Callable[[PayloadT], CommandT] — Maps the validated payload to the command; its parameter type is the request body.
status int \| None None Status code of the response (default: the operation's first response).

use_query()

def use_query(decorator: Callable[[Method], Method], handler: Callable[..., QueryHandler[CommandT, ResultT] | QueryHandler[CommandT, Awaitable[ResultT]]], *, query: Callable[[PayloadT], CommandT], status: int | None = None) -> Method: ...

A read operation: map the query parameters and call the resolved handler.

Parameter Type Default Description
decorator Callable[[Method], Method] — The operation decorator, e.g. get("/stats", response=StatsOut).
handler Callable[..., QueryHandler[CommandT, ResultT] \| QueryHandler[CommandT, Awaitable[ResultT]]] — A class with __call__(query) (sync or async), resolved from the container.
query Callable[[PayloadT], CommandT] — Maps the validated payload to the query; its parameter type is the query schema.
status int \| None None Status code of the response (default: the operation's first response).

CQRS building blocks

Class Arguments Description
Message — Base for an application message.
Command — A request that changes state, handled by a use_case handler.
Query — A request that reads state, handled by a use_query handler.
DomainEvent — Base for a domain event; use a frozen dataclass subclass.
EventBus tasks: TaskQueue A registry that delivers domain events after the current transaction commits.
UnitOfWork *, using: str \| None = None, durable: bool = False Wrap a block in one transaction.atomic.

Application plugins

Class Arguments Description
APIPlugin — Base class for an application plugin. Override the parts you need.

install()

def install(api: NinjaAPI, plugins: Sequence[APIPlugin]) -> None: ...

Install plugins on api: error rules, middleware, then setup.

Parameter Type Default Description
api NinjaAPI — The NinjaAPI to configure.
plugins Sequence[APIPlugin] — Plugins applied in order.

mount()

def mount(target: NinjaAPI | Router, routes: Mapping[str, type[Controller] | Mount], *, prefix: str = '', container: ContainerLike | None = None, scope: Scope | None = None, **options: Unpack[ControllerOptions]) -> dict[str, Router]: ...

Build and add a router per route; shared container, scope and options.

Parameter Type Default Description
target NinjaAPI \| Router — The NinjaAPI or Router to mount on.
routes Mapping[str, type[Controller] \| Mount] — {prefix: Controller} or {prefix: Mount(Controller, ...)}.
prefix str '' Prepended to every route; also prefixes operation ids and URL names (versioning).
container ContainerLike \| None None Shared container for every entry.
scope Scope \| None None Shared scope for every entry.
**options Unpack[ControllerOptions] — ControllerOptions for every entry; errors= is also installed on a NinjaAPI.

Mount

Per-route overrides for mount.

Name Type Default Description
controller type[Controller] — The controller class.
container ContainerLike \| None None Container for this entry (default: the mount() container).
scope Scope \| None None Scope for this entry (default: the mount() scope).
options ControllerOptions field(default_factory=lambda: ControllerOptions()) ControllerOptions for this entry, over the mount() options.

OperationInfo

Static description of an operation, built once per registration.

Name Type Default Description
controller type[Controller] — The controller class.
method_name str — The Python method implementing the operation.
operation_id str — The OpenAPI operation id.
http_methods tuple[str, ...] — HTTP methods of the operation.
path str — The path as declared on the router.
is_async bool — Whether the registered implementation is async.
metadata tuple[object, ...] () Typed metadata from meta= (controller and operation), for permissions and hooks.
database str \| None None Explicit operation/controller database alias, if configured.

LoggingHook

Logs one structured record per operation call with its duration and outcome.

Name Type Default Description
logger logging.Logger field(default_factory=lambda: logging.getLogger('ninja_devx')) Logger receiving one record per call.
level int logging.INFO Log level of the record.