Skip to content

Enhancement: Generate models for inline (anonymous) object schemas #108

@dougborg

Description

@dougborg

Summary

Inline object schemas specified directly inside requestBody or responses (without a named component under #/components/schemas) are currently emitted as untyped Dict[str, Any] (or raw structures). This reduces type safety, IDE assistance, and validation.

Current Behavior

Example: a request body with

{"type": "object", "properties": {"name": {"type": "string"}}}

produces a function signature like:

async def create_item(..., data: Dict[str, Any]) -> Dict[str, Any]:

No generated Pydantic model captures required fields or property types.

Desired Behavior

Automatically materialize inline object schemas as Pydantic models, reusing identical shapes across operations, and reference those models in request/response signatures.

Proposed Approach

  1. Traverse operations (request bodies + primary 2xx response) collecting inline object schemas (no $ref).
  2. Canonicalize & hash each schema (properties, required, additionalProperties, etc.) to deduplicate.
  3. Name derivation strategy:
    • <OperationId>RequestBody, <OperationId>ResponseBody for top-level bodies.
    • <ParentName><PropertyName> for nested inline objects.
    • Fallback: InlineModel<N> for collisions/overly long names.
  4. Generate Pydantic models before service rendering; merge with existing component models so imports are uniform.
  5. Arrays of inline objects become List[GeneratedInlineModel].
  6. Optional CLI flag --inline-models/--no-inline-models (default enabled) to preserve current minimalist behavior if desired.

Edge Cases / Phase 2

  • oneOf/anyOf/allOf compositions (initial pass can leave as Dict[str, Any] or unions; separate issue)
  • Inline enums -> Python Enum classes
  • Configurable naming template

Acceptance Criteria

  • Duplicate identical inline schemas produce a single generated class reused across operations.
  • New tests cover: simple inline schema, reused schema, nested inline schema, array of inline objects.
  • No regression in existing coverage.

Rationale

Brings parity with other generators (openapi-generator, datamodel-code-generator) and significantly improves usability for specs that favor inline definitions (e.g., Karakeep). Adds strong typing with minimal user effort.

If approved, I can submit a PR implementing steps 1–5.

Thoughts / preferences on naming or file placement (single inline_models.py vs grouped) welcome.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions