OpenAPI¶
enable_openapi ¶
Set
ServiceAutoSchema
as the schema on every library view class.
Call once from AppConfig.ready() (or anywhere after Django apps are
loaded) to make drf-spectacular see a spec's request bodies, response
bodies, success statuses, and 422 contracts, a kernel ServiceSpec or
SelectorSpec read off its Validator and presenter, on:
ServiceCreateView,ServiceUpdateView,ServiceDeleteViewSelectorListView,SelectorRetrieveViewServiceViewSet,SelectorViewSetServiceCreateMixin,ServiceUpdateMixin,ServiceDestroyMixin,SelectorListMixin,SelectorRetrieveMixin
The function-local imports keep drf-spectacular an optional
dependency: importing
django_spec_rest.openapi does not require it, and only
this call brings in the schema-generator code.
User subclasses inherit schema = ServiceAutoSchema() automatically;
classes that set schema = ... explicitly keep their own choice. A
project's GenericViewSet composed of the mixins inherits it only where
a mixin comes before GenericViewSet in its bases, since DRF's
APIView carries a schema of its own
(test_the_documented_setup's
test_a_mixin_listed_first_documents_its_spec_with_no_schema_of_its_own).
Where a mixin does come first, its ServiceAutoSchema also wins over a
project's DEFAULT_SCHEMA_CLASS, even a subclass of it; setting
schema = ProjectSchema() on the class keeps the subclass
(test_the_documented_setup's
test_a_mixin_listed_first_overrides_a_project_s_default_schema_class).
It also inserts
reserved_components_hook
first in drf-spectacular's POSTPROCESSING_HOOKS, before the project's
own hooks and once however often it is called, so a component of the
project's under a name the package documents its refusals by is refused
on any view. It recognises the package's own references by the identity
of their $ref strings, so a project hook that rebuilds those strings
(a JSON round trip) must run after it, not before.
ServiceAutoSchema ¶
Bases: AutoSchema
AutoSchema that derives its request / response from a kernel spec.
A kernel ServiceSpec or SelectorSpec is read off its seats, as the
route serves it, on every surface: the standalone Service*View and
Selector*View classes, the ServiceViewSet and SelectorViewSet
action mixins, and @service_action / @selector_action:
- The request body is a
SerializerValidator's serializer, built partial exactly where the route dispatches the spec's partial variant (kernel_spec_variant): an update route'sPATCH, unless the Validator cannot take a partial call, and a spec declaringpartial. A@service_actionPATCHdispatches its spec as declared, so it is validated, and documented, whole (_dispatched). Its component is drf-spectacular's name for the author's class, except where the spec'sinput_datareaches a field: then a subclass less the fields it fills, with those it may fill not required, under a name of its own (caller_serializer_class). Amanyspec takes a list of those rows. Any other Validator is the kernel'sspec_caller_input_schemaless what the body does not carry (_parameters_body): what the server fills is not asked for, and a key a provider may fill is not required. It is read under thereststamp with no request, so a field a Validator declares to this transport is offered and one declared to another is not (_caller_schema). A body the wire refuses to go without saysrequired, which drf-spectacular leaves off a schema given whole (_DemandedBody). Every schema the kernel writes reaches the document throughlowered_for_the_document, so under OpenAPI 3.0 a nullable or labelled one isnullableandenum, in a request body, a response body and a parameter alike. - The response body is a
SerializerPresenter's serializer, or any other presenter'soutput_schema, a list of rows where the spec presents rows (_presents_rows). A spec with no presenter documents no body, at the statuses_kernel_responseslists, and a selector spec with none keeps the base's reading of the view'sserializer_class, which renders it. - The status is the view's
success_statusfor the action, per action where one is declared, where it is anint, since a kernel spec declares none, over the action's default; a body is documented as the200it is served as where that is204, and the204beside it wherecan_present_nothing. With no presenter and nosuccess_statusboth the action's default and the204are listed, since the service's return decides between them (a destroy's default is the204, so it lists that alone). - A
400is documented wherever the spec declares a Validator: its refusal is DRF's field errors, whichever seat refused, so the body is theValidationErrorscomponent. Beside it, any of what else the edge sends as a 400: adetailsentence (the body is no object), and the bare list of messages a service'sServiceValidationErrorover a sentence or a list answers with. - A
422is documented where the spec declares that it can answer one,metadata={"document_service_error": True}(documents_service_error): the edge answers a plainServiceError422, from the service, the selector, a precondition or a provider, with or without a Validator, and which specs raise one the schema cannot see. A selector spec taking a parameter (a read, a shape or a filter) documents the400its refusal is, with the body of a Validator's. - A
403is documented wherever the spec declares a permission check, any check butUnrestricted: a check's denial and a principal who cannot act are both answered 403 with adetail. A401beside it where the view's first authenticator sends aWWW-Authenticate: DRF answers such a check's denial of a caller nobody authenticated 401 there, and 403 where the authenticator sends none (_caller_refusals). - A
DiscriminatedActionis one request component,{View}_{action}_Request, ananyOfover the body of each variant that takes one (_discriminated_request_body), and its responses are the variants' merged per status: one body where they agree, an inlineanyOfwhere they differ, each status any variant answers, and a400always, since the discriminator may refuse (_discriminated_responses). - A FilterSet's query parameters are the kernel's
filter_set_parameters, on a list operation only. - A viewset method answered 405 for want of a spec is no operation:
the schema leaves out what
Allowleaves out (is_excluded).
A refusal a service raises is the project's to declare, with
@extend_schema(responses={404: ServiceNotFoundSerializer}) and the
other serializers django_spec_rest.openapi exports. A mapping of
statuses is added to what the spec documents, each status declared
replacing the spec's own at that status and any 2xx declared replacing
every success status the spec documents; any other responses= is the
success body at the spec's own status (_get_response_bodies). Every
other @extend_schema argument wins whole, and
@extend_schema(parameters=...) merges over the filter parameters
exactly as it does for a view-level FilterSet.
is_excluded ¶
Whether this method is left out, as Allow leaves it out, or as drf-spectacular does.
drf-spectacular documents every method the router's action map binds,
so a ServiceViewSet route serving some spec documented a create,
update, partial update or destroy whose handler answers 405 with no
spec behind it. Such a method is asked of the view's own
_refuses_without_a_spec, the predicate its allowed_methods
reads, never of allowed_methods itself: the generator binds no
handler to the view it builds, so DRF's half of that list is empty
there (test_spec_less_actions). A view with no such predicate, a
standalone view or one of DRF's, is not asked.
documents_service_error ¶
Whether this operation documents the 422 a plain ServiceError is answered with.
Where spec, the one the route serves, declares it:
metadata={"document_service_error": True}
(SERVICE_ERROR_METADATA_KEY), on a service spec and on a selector
spec alike (test_service_error_declared). A spec declaring nothing, or
False, documents none: the edge answers 422 for a plain
ServiceError from the service, the selector, a precondition or a
provider, and nothing the schema can read says which specs raise one.
Only the served spec's metadata is read, never that of its target
or re-read selector. A value other than True or False is
refused, naming the view, rather than read as either.
A project's subclass may override it to answer for many operations at
once (every spec, or a predicate over spec, self.view and
self.method), and an @extend_schema(responses={422: ...})
documents it on one view whatever this answers.
reserved_components_hook ¶
reserved_components_hook(
result: dict[str, Any], generator: Any, request: Any, public: bool, **kwargs: Any
) -> dict[str, Any]
Refuse a $ref to a component name the package reserves that the package did not write.
ValidationErrors, PermissionDenied and NotAuthenticated document
the bodies of a spec's 400, 403 and 401. drf-spectacular keeps the first
component registered under a name and answers it for every later one, with
a warning only, so a project's serializer of the same name on a view this
package does not document (drf-spectacular's own AutoSchema) would be
documented by the package's body. Where the package registered one of these
names, every $ref to it outside the places the package rendered it raises
ImproperlyConfigured, naming the operation, component or webhook that
holds it.
A name the package never registered is a project's to use (test_a_project_s_own_reserved_name_is_documented_without_the_package_s).
Raises:
| Type | Description |
|---|---|
ImproperlyConfigured
|
a reserved name documents something of the project's. |
ServiceErrorSerializer ¶
Bases: Serializer
The service could not complete the call. Why is under detail, and the values still needed under schema where it asks for more input.
SERVICE_ERROR_METADATA_KEY
module-attribute
¶
metadata={"document_service_error": True} documents the 422 on that spec's operations.
The edge answers a plain ServiceError 422, from the service, the selector,
a precondition or a provider; the schema cannot tell which specs raise one, so
it documents the 422 only where a spec says so. Read by
ServiceAutoSchema.documents_service_error off the spec the route serves,
never off a nested target or re-read spec. The name is drfs' own
document_service_error, so a drfs spec carrying document_service_error=True
moves by putting the flag in its metadata. The value is True or
False; any other is refused when the schema is generated.
ServiceValidationErrorSerializer ¶
Bases: Serializer
The call was refused as invalid. The messages are a list, or an object by name whose values are a message, a list or an object of the same shape.
ServiceNotFoundSerializer ¶
Bases: Serializer
The service found nothing to act on. Why is under detail.
ServiceConflictSerializer ¶
Bases: Serializer
The call conflicts with the state of what it acts on. Why is under detail.
ActionUnavailableSerializer ¶
Bases: ServiceConflictSerializer
The action is unavailable in the state of what it acts on. Why is under detail, and the action's stable code under code.
PermissionDeniedSerializer ¶
Bases: Serializer
The caller may not run this operation. Why is under detail.
NotAuthenticatedSerializer ¶
Bases: Serializer
No caller was authenticated. Why is under detail.