Models
Shared Pydantic model base classes, the RFC 9457 ErrorDetails model, response-header schemas and the Server-Sent Event types. Import from fastapi_views.models.
Exports
fastapi_views.models re-exports:
| Name | Kind |
|---|---|
BaseSchema |
base model |
CamelCaseSchema, IdSchema, CreatedUpdatedSchema, IdCreatedUpdatedSchema |
common models |
ErrorDetails, ErrorDetailsType, const_type, create_error_model |
error model + helpers |
ResponseHeaders |
OpenAPI response-header schema |
BaseServerSentEvent, IdBaseServerSentEvent, AnyServerSentEvent |
SSE event models |
Two more model modules are not re-exported and must be imported from their submodule:
fastapi_views.models.base.OpenAPIBase— the self-documenting schema basefastapi_views.models.jsonpatch—JsonPatchModel,JsonPatch,PatchOperation,apply()(see JSON Patch)fastapi_views.models.streaming—ResponseStarted/ResponseResult/ResponseError/ResponseCancelled/ResponseFinishedand theResponseEventunion used for streaming responses (see Server Side Events)
Base schemas
| Class | Description |
|---|---|
BaseSchema |
Pydantic BaseModel with use_enum_values, populate_by_name, and from_attributes enabled |
OpenAPIBase |
BaseSchema that can render itself as OpenAPI content, keyed by its __content_type__ |
CamelCaseSchema |
BaseSchema with alias_generator = to_camel for camelCase JSON keys |
IdSchema |
BaseSchema with a UUID id field |
CreatedUpdatedSchema |
BaseSchema with created_at and updated_at datetime fields |
IdCreatedUpdatedSchema |
Combines IdSchema and CreatedUpdatedSchema |
OpenAPIBase
OpenAPIBase declares the media type a schema is documented and served under, and turns itself into an OpenAPI response entry. It is the base of ErrorDetails, ResponseHeaders and the SSE event models.
| Member | Description |
|---|---|
__content_type__ |
media type used when rendering OpenAPI content (default application/json) |
get_openapi_schema(title=None) |
JSON schema in serialization mode, with $refs pointing at #/components/schemas/{model} and nested models in $defs; title overrides the schema title |
get_openapi_content(title=None) |
{__content_type__: {"schema": ...}}, ready to drop into a route's responses |
$defs produced this way are relocated into the application's components/schemas by custom_openapi, which configure_app installs, so the references stay resolvable.
Error model
ErrorDetails is the base model for all RFC 9457 problem-details responses; its __content_type__ is application/problem+json.
| Field | Type | Default |
|---|---|---|
type |
Url \| Literal["about:blank"] |
"about:blank" |
title |
str |
required |
status |
int |
required |
detail |
str |
required |
instance |
str \| None |
None |
correlation_id |
str \| None |
declared only when opentelemetry-instrumentation-fastapi is importable; default_factory=get_correlation_id, i.e. the active trace id at construction time |
errors |
list[Any] |
[] |
ErrorDetails.new(detail, **kwargs) is a convenience constructor that takes detail positionally. ErrorDetailsType is the alias type[ErrorDetails].
correlation_id is omitted, not null
When the field exists but no OpenTelemetry span is active, get_correlation_id() returns
None and the key is dropped from the serialized payload rather than rendered as
"correlation_id": null. ErrorDetails overrides model_dump and model_dump_json to
add "correlation_id" to exclude in that case, merging with whatever exclude the
caller passed (set, dict or None all work). The field is still advertised in the OpenAPI
schema, so clients can rely on it being documented while treating it as optional.
>>> details = ErrorDetails(title="Test", status=400, detail="detail")
>>> details.correlation_id is None
True
>>> "correlation_id" in details.model_dump()
False
>>> details.model_dump(exclude={"instance"}).keys() # user exclude preserved
dict_keys(['type', 'title', 'status', 'detail', 'errors'])
Without the OpenTelemetry extra installed the field does not exist at all, and neither the body nor the schema mentions it.
Two helpers build error models dynamically — they are what APIError subclassing uses internally:
const_type(value, description=None, **kwargs)returns a(Literal[value], Field(value, ...))tuple, i.e. a constant field definition forcreate_model.create_error_model(status, type="about:blank", name=None, title=None, detail=None, **kwargs)builds anErrorDetailssubclass whosetitle,statusandtypeare constants.titledefaults to theHTTPStatusphrase,nameto that phrase without spaces, anddetailto theHTTPStatusdescription — or to the phrase when that description is empty, so the defaultdetailis never an empty string. Extra keyword arguments are passed tocreate_modelas field definitions;__base__selects a differentErrorDetailssubclass to inherit from.
from fastapi_views.models import create_error_model
NotFoundModel = create_error_model(404) # name "NotFound", title "Not Found"
Custom = create_error_model(400, name="QuotaExceeded", title="Quota Exceeded")
create_error_model(422)().detail # "Unprocessable Entity", not ""
Response headers
ResponseHeaders is a schema whose fields describe HTTP response headers. get_openapi_headers() renders it as a mapping of OpenAPI Header Objects: description is lifted to the top level, the remaining JSON schema is nested under schema, required fields get required: true, and nullable unions (X | None) are collapsed to X since a response header is never null.
from pydantic import Field
from fastapi_views.models import ResponseHeaders
class LocationHeaders(ResponseHeaders):
location: str = Field(description="URL of the created resource")
x_request_id: str | None = None
>>> LocationHeaders.get_openapi_headers()
{'location': {'description': 'URL of the created resource',
'required': True,
'schema': {'type': 'string'}},
'x_request_id': {'schema': {'type': 'string'}}}
Note that the field name is used verbatim as the header name, so declare headers exactly as they should appear.
Three places consume a ResponseHeaders subclass:
| Where | How |
|---|---|
| Route decorators | @get(...), @post(...), @route(...), @action(...) accept response_headers= — see Decorators |
ViewRouter |
ViewRouter(prefix="/items", response_headers=...) documents them on every route it registers |
| Views | override get_response_headers(action) to return the class per action; the headers are documented on that action's success status code |
Both CacheHeaders (from the caching view mixin) and ConditionalHeaders (ETag/Last-Modified support) are ResponseHeaders subclasses.
Server-Sent Events
| Class | Fields |
|---|---|
BaseServerSentEvent |
retry: int \| None; __content_type__ = "text/event-stream" |
IdBaseServerSentEvent |
adds id: UUID (defaults to uuid4()) |
AnyServerSentEvent |
adds id: str (random UUID string), event: str, data: Any |
Subclass BaseServerSentEvent (or IdBaseServerSentEvent) with a literal event and a typed data field for a strongly typed stream. get_openapi_schema() — inherited from OpenAPIBase — is what ServerSentEventsAPIView uses when registering the route. See Server Side Events.
ErrorDetails
Bases: OpenAPIBase
Base Model for https://www.rfc-editor.org/rfc/rfc9457.html
Source code in fastapi_views/models/errors.py
ResponseHeaders
Bases: OpenAPIBase
Class used to specify OpenAPI for response headers.
get_openapi_headers renders each field as an OpenAPI Header Object
<https://spec.openapis.org/oas/v3.1.0#header-object>_: description is
lifted to the top level, the remaining JSON schema is nested under
schema, and required fields are flagged with required: true.
Referenced models travel in $defs, relocated to the application
components by custom_openapi.
Source code in fastapi_views/models/headers.py
OpenAPIBase
Bases: BaseSchema
Schema which can render itself as an OpenAPI schema.
__content_type__ declares the media type under which the schema
is documented (and served). Nested models are referenced via
#/components/schemas/ and shipped in the $defs key, which
custom_openapi merges into the application components.
Source code in fastapi_views/models/base.py
get_openapi_content(title: str | None = None) -> dict[str, Any]
classmethod
Render the schema as OpenAPI response content keyed by __content_type__.