Code Generation#
Code generation utilities for extracting route metadata and generating type-safe route definitions.
Features#
Extract route metadata from Litestar applications
Generate Ziggy-compatible routes.json
Generate TypeScript route definitions with type safety
Support for path and query parameters with OpenAPI type enrichment
Inertia page props metadata extraction
Public code generation API.
This package provides code generation utilities for:
Unified asset export (
export_integration_assets)Route metadata export (
routes.json+ Ziggy-compatible TS)Inertia page props metadata export
Internal implementation details (OpenAPI integration, TypeScript conversion) are kept in private submodules to keep the public API clean.
- class litestar_vite.codegen.AsyncAPIChannel[source]#
Bases:
objectAsyncAPI 3.0 Channel Object.
- to_dict() dict[str, Any][source]#
Convert the channel object to a dictionary.
- Returns:
Dictionary representation of the channel object.
- __init__(address: str, title: str | None = None, summary: str | None = None, description: str | None = None, parameters: dict[str, ~litestar_vite.codegen._asyncapi.AsyncAPIParameter]=<factory>, messages: dict[str, ~litestar_vite.codegen._asyncapi.AsyncAPIMessage]=<factory>, bindings: dict[str, ~typing.Any]=<factory>) None#
- class litestar_vite.codegen.AsyncAPIComponents[source]#
Bases:
objectAsyncAPI 3.0 Components Object.
- class litestar_vite.codegen.AsyncAPIDocument[source]#
Bases:
objectRoot AsyncAPI 3.0 Document.
- to_dict() dict[str, Any][source]#
Serialize the complete document to an AsyncAPI 3.0 specification dictionary.
- Returns:
Deterministic dictionary representation of the AsyncAPI 3.0 specification.
- __init__(info: AsyncAPIInfo, asyncapi: str = '3.0.0', id: str | None = None, servers: dict[str, ~litestar_vite.codegen._asyncapi.AsyncAPIServer]=<factory>, channels: dict[str, ~litestar_vite.codegen._asyncapi.AsyncAPIChannel]=<factory>, operations: dict[str, ~litestar_vite.codegen._asyncapi.AsyncAPIOperation]=<factory>, components: AsyncAPIComponents | None = None) None#
- class litestar_vite.codegen.AsyncAPIInfo[source]#
Bases:
objectAsyncAPI 3.0 Info Object.
- class litestar_vite.codegen.AsyncAPIMessage[source]#
Bases:
objectAsyncAPI 3.0 Message Object.
- class litestar_vite.codegen.AsyncAPIOperation[source]#
Bases:
objectAsyncAPI 3.0 Operation Object.
- class litestar_vite.codegen.AsyncAPIParameter[source]#
Bases:
objectAsyncAPI 3.0 Parameter Object.
- class litestar_vite.codegen.AsyncAPIServer[source]#
Bases:
objectAsyncAPI 3.0 Server Object.
- class litestar_vite.codegen.ExportResult[source]#
Bases:
objectResult of the export operation.
- class litestar_vite.codegen.InertiaPageMetadata[source]#
Bases:
objectMetadata for a single Inertia page component.
- litestar_vite.codegen.app_has_realtime_surface(app: Litestar) bool[source]#
Return whether the Litestar application defines any realtime surface.
A realtime surface includes: - Any plugin in
app.pluginsthat provides AsyncAPI schemas. - Any route inapp.routesthat is alitestar.routes.WebSocketRoute. - Any plugin inapp.pluginsthat is alitestar.channels.ChannelsPlugin. - Any HTTP route handler whose return annotation represents a Server-Sent Event (SSE).- Parameters:
app¶ – The Litestar application instance.
- Returns:
True if any realtime route, plugin, or SSE handler is detected, otherwise False.
- litestar_vite.codegen.asyncapi_docs_paths(app: Litestar) tuple[str, ...][source]#
Return reserved AsyncAPI documentation route prefixes.
When an AsyncAPI plugin is registered, returns a deduplicated tuple containing the default AsyncAPI documentation path (‘/asyncapi’) and any custom documentation path configured on the plugin. When no plugin is registered, returns an empty tuple.
- Parameters:
app¶ – The Litestar application instance.
- Returns:
Tuple of reserved documentation path strings.
- litestar_vite.codegen.create_asyncapi_document(app: Litestar, title: str = 'Litestar Realtime API', version: str = '1.0.0', description: str | None = None) AsyncAPIDocument[source]#
Generate an AsyncAPI 3.0 document from a Litestar application.
- litestar_vite.codegen.encode_deterministic_json(data: dict[str, Any], *, indent: int = 2, serializer: Callable[[Any], bytes] | None = None) bytes[source]#
Encode JSON with sorted keys for deterministic output.
This is a wrapper that ensures all nested dict keys are sorted before serialization, producing byte-identical output for the same input data regardless of insertion order.
- litestar_vite.codegen.export_asyncapi(*, app: Litestar, types_config: TypeGenConfig, serializer: Callable[[Any], bytes] | None = None, result: ExportResult) None[source]#
Export AsyncAPI 3.0 schema to file.
- litestar_vite.codegen.export_integration_assets(app: Litestar, config: ViteConfig, *, serializer: Callable[[Any], bytes] | None = None) ExportResult[source]#
Export all integration artifacts with deterministic output.
This is the single source of truth for code generation. Both CLI commands and Plugin startup should call this function to ensure byte-identical output.
AsyncAPI export is independent of OpenAPI availability when channels are enabled and a realtime surface is present on the application (WebSocket routes, ChannelsPlugin, or SSE handlers). The configuration flag generate_channels=True is an opt-in ceiling rather than a mandate, so a REST-only application produces no AsyncAPI artifacts even when generate_channels is true. OpenAPI schema, route metadata, route definitions, and Inertia page prop artifacts require an active OpenAPI configuration.
The export order is critical: 1. Register Inertia page prop types in OpenAPI schema (mutates schema_dict) 2. Export openapi.json (now includes session prop types) 3. Export routes.json (uses schema for component refs) 4. Export routes.ts (if enabled) 5. Export inertia-pages.json (if enabled) 6. Export asyncapi.json (if enabled)
- litestar_vite.codegen.extract_channels_plugin_channels(app: Litestar, components_schemas: dict[str, Any] | None = None, *, context: AsyncAPISchemaContext | None = None, allocator: _ChannelKeyAllocator | None = None, operation_ids: set[str] | None = None) tuple[dict[str, AsyncAPIChannel], dict[str, AsyncAPIOperation]][source]#
Extract channels and operations defined in Litestar ChannelsPlugin.
Fallback payload schema is unconstrained ({}) rather than {“type”: “object”} because a ChannelsPlugin topic may carry arrays, strings, numbers, or bytes.
- Parameters:
app¶ – The Litestar application instance.
components_schemas¶ – Optional dictionary to collect named component schemas.
context¶ – Optional schema context coordinating OpenAPI and DTO support.
allocator¶ – Optional allocator to ensure unique channel keys across sources.
operation_ids¶ – Optional set to ensure unique operation ids across sources.
- Returns:
Tuple of (channels_mapping, operations_mapping). When ChannelsPlugin is not registered on the application, channel extraction returns an empty result.
- litestar_vite.codegen.extract_inertia_pages(app: Litestar, *, openapi_schema: dict[str, Any] | None = None, fallback_type: str = 'unknown', openapi_support: OpenAPISupport | None = None) list[InertiaPageMetadata][source]#
Extract Inertia page metadata from an application.
When multiple handlers map to the same component, GET handlers are preferred since Inertia pages are typically loaded via GET requests.
- Parameters:
- Returns:
List of InertiaPageMetadata for each discovered page.
- litestar_vite.codegen.extract_payload_schema(annotation: Any, components_schemas: dict[str, Any] | None = None) dict[str, Any][source]#
Convert a Python type annotation to a JSON Schema for AsyncAPI message payloads.
Supports primitives, containers, unions, msgspec.Struct, dataclasses, Pydantic models, TypedDicts, and Enums. Registers complex schemas in components_schemas when provided.
- litestar_vite.codegen.extract_realtime_channels(app: Litestar, components_schemas: dict[str, Any] | None = None, *, context: AsyncAPISchemaContext | None = None) tuple[dict[str, AsyncAPIChannel], dict[str, AsyncAPIOperation]][source]#
Extract all real-time channels from WebSocket routes, ChannelsPlugin, and SSE routes.
- litestar_vite.codegen.extract_route_metadata(app: Litestar, *, only: list[str] | None = None, exclude: list[str] | None = None, openapi_schema: dict[str, Any] | None = None) list[RouteMetadata][source]#
Extract route metadata from a Litestar application.
Note
openapi_schemais used to resolve accurate type component references. If not provided, it will be generated from the application automatically.- Returns:
A list of RouteMetadata objects.
- litestar_vite.codegen.extract_sse_routes(app: Litestar, components_schemas: dict[str, Any] | None = None, *, context: AsyncAPISchemaContext | None = None, allocator: _ChannelKeyAllocator | None = None, operation_ids: set[str] | None = None) tuple[dict[str, AsyncAPIChannel], dict[str, AsyncAPIOperation]][source]#
Extract Server-Sent Event (SSE) routes from a Litestar application.
- Parameters:
app¶ – The Litestar application instance.
components_schemas¶ – Optional dictionary to collect named component schemas.
context¶ – Optional schema context coordinating OpenAPI and DTO support.
allocator¶ – Optional allocator to ensure unique channel keys across sources.
operation_ids¶ – Optional set to ensure unique operation ids across sources.
- Returns:
Tuple of (channels_mapping, operations_mapping).
- litestar_vite.codegen.extract_websocket_routes(app: Litestar, components_schemas: dict[str, Any] | None = None, *, context: AsyncAPISchemaContext | None = None, allocator: _ChannelKeyAllocator | None = None, operation_ids: set[str] | None = None) tuple[dict[str, AsyncAPIChannel], dict[str, AsyncAPIOperation]][source]#
Extract WebSocket routes from a Litestar application into AsyncAPI channels and operations.
- Parameters:
app¶ – The Litestar application instance.
components_schemas¶ – Optional dictionary to collect named component schemas.
context¶ – Optional schema context coordinating OpenAPI and DTO support.
allocator¶ – Optional allocator to ensure unique channel keys across sources.
operation_ids¶ – Optional set to ensure unique operation ids across sources.
- Returns:
Tuple of (channels_mapping, operations_mapping).
- litestar_vite.codegen.find_asyncapi_plugin(app: Litestar) Any | None[source]#
Find an AsyncAPI plugin registered on the Litestar application.
Queries Litestar’s plugin registry for a registered
AsyncAPIPlugin, guarded byASYNCAPI_INSTALLED.- Parameters:
app¶ – The Litestar application instance.
- Returns:
The registered AsyncAPI plugin instance if found, otherwise None.
- litestar_vite.codegen.generate_inertia_pages_json(app: Litestar, *, openapi_schema: dict[str, Any] | None = None, include_default_auth: bool = True, include_default_flash: bool = True, inertia_config: InertiaConfig | None = None, types_config: TypeGenConfig | None = None) dict[str, Any][source]#
Generate Inertia pages metadata JSON.
The output is deterministic: all dict keys are sorted alphabetically to produce byte-identical output for the same input data.
A single OpenAPISupport instance is shared across both page extraction and shared props building to ensure consistent schema registration and naming. This eliminates non-determinism from split schema registries.
- Returns:
An Inertia pages metadata payload as a dictionary with sorted keys.
- litestar_vite.codegen.generate_routes_json(app: Litestar, *, only: list[str] | None = None, exclude: list[str] | None = None, include_components: bool = False, openapi_schema: dict[str, Any] | None = None, routes_metadata: list[RouteMetadata] | None = None) dict[str, Any][source]#
Generate Ziggy-compatible routes JSON.
The output is deterministic: routes are sorted by name to produce byte-identical output for the same input data.
- Returns:
A Ziggy-compatible routes payload as a dictionary with sorted keys.
- litestar_vite.codegen.generate_routes_ts(app: Litestar, *, only: list[str] | None = None, exclude: list[str] | None = None, openapi_schema: dict[str, Any] | None = None, global_route: bool = False, routes_metadata: list[RouteMetadata] | None = None) str[source]#
Generate typed routes TypeScript file (Ziggy-style).
The output is deterministic: routes are sorted by name to produce byte-identical output for the same input data.
- Returns:
The generated TypeScript source.
- litestar_vite.codegen.normalize_asyncapi_document(document: dict[str, Any]) dict[str, Any][source]#
Normalize an AsyncAPI document into a consistent internal shape.
Guarantees that:
The asyncapi version string is present (‘3.0.0’ or ‘3.1.0’).
Channels are re-keyed into collision-safe litestar-vite format using _ChannelKeyAllocator with protocol-aware source selection.
Every channel has an explicit bindings dictionary with protocol markers.
Operation channel and message $ref pointers match the allocated channel keys.
Root document metadata, servers, and components are preserved intact.
- Parameters:
document¶ – Raw AsyncAPI document dictionary.
- Returns:
A normalized AsyncAPI document dictionary.
- litestar_vite.codegen.resolve_asyncapi_document(app: Litestar, title: str | None = None, version: str | None = None) tuple[dict[str, Any], str][source]#
Resolve and normalize the AsyncAPI document for a Litestar application.
Probes for a registered AsyncAPI plugin via find_asyncapi_plugin. When found, attempts to retrieve the schema from the plugin via get_asyncapi_schema (or get_asyncapi_json if a non-dict is returned). On any exception or malformed return, or when no plugin is present, falls back seamlessly to create_asyncapi_document.
Both sources are passed through normalize_asyncapi_document to ensure identical internal channel keying and binding semantics for frontend code generation.
- litestar_vite.codegen.strip_timestamp_for_comparison(content: bytes) bytes[source]#
Remove generatedAt and other timestamp fields for content comparison.
This allows comparing file content while ignoring fields that change on every generation (like timestamps).
- Parameters:
content¶ – JSON content as bytes.
- Returns:
JSON content with timestamp fields removed, sorted keys.
- litestar_vite.codegen.typegen_outputs_requested(types_config: TypeGenConfig) bool[source]#
Return whether the typegen config asks for any generated artifact.
- litestar_vite.codegen.write_if_changed(path: Path, content: bytes | str, *, normalize_for_comparison: Callable[[bytes], bytes] | None = None, encoding: str = 'utf-8') bool[source]#
Write content to file only if it differs from the existing content.
Uses hash comparison to avoid unnecessary writes that would trigger file watchers and unnecessary rebuilds. Optionally normalizes content before comparison (e.g., to strip timestamps).
- Parameters:
path¶ – The file path to write to.
content¶ – The content to write (bytes or str).
normalize_for_comparison¶ – Optional callback to normalize content before comparison (e.g., strip timestamps). The file is written with the original content, not the normalized version.
encoding¶ – Encoding for string content.
- Returns:
True if file was written (content changed), False if skipped (unchanged).