mrkeyoor.com_
Sun 20 Sept 13:40 UTC
PyPIUtilsupdated 20 Sept 2026

openapi-pydantic review

Our Python 3.12 install of openapi-pydantic 0.5.1 completed in 0.6 seconds, and its import took 0.56 seconds. The package maps OpenAPI 3.1.1 and 3.0.4 objects to Pydantic classes, letting Python code construct or parse a specification with field validation. A helper can turn application Pydantic models into component schemas and replace placeholders with references. Release 0.5.1 changed generated reference names so invalid `$ref` characters become underscores; it does not add routing, request validation, documentation hosting, or client generation.

Verdict

openapi-pydantic is useful when Python code owns an OpenAPI 3.1.1 or 3.0.4 document and typed construction is worth the alias rules. Do not add it beside framework-generated specs or expect it to create clients, routes, or a docs UI.

We installed it

Lab card: what happened when we installed openapi-pydanticScreenshot of openapi-pydantic documentation
Install✓ · 0.6s6 packages on disk · 8 MB
Importimport openapi_pydantic in 0.56s · pure Python · py.typed · requires Python >=3.8,<4.0
Known vulns0(pip-audit)

Answers from our run

Does openapi-pydantic install cleanly?

Yes. In a fresh container with an empty cache, pip install openapi-pydantic finished in 0.6s, leaving 6 packages and 8 MB on disk. pip-audit reported no known vulnerabilities.

What does openapi-pydantic need to run?

Python >=3.8,<4.0, and nothing compiled: it is pure Python. In our run import openapi_pydantic succeeded in 0.56s, and the package ships py.typed for type checkers.

openapi-pydantic or fastapi: which should you use?

fastapi: Choose it when route declarations should drive both request handling and automatic OpenAPI generation. openapi-pydantic is useful when Python code owns an OpenAPI 3.1.1 or 3.0.4 document and typed construction is worth the alias rules.

When should you not use openapi-pydantic?

FastAPI already derives the document from routes and Pydantic models. A second hand-built model tree creates another source of truth.

API stability3/5The classes follow published OpenAPI object names, and 0.5.1 supports both Pydantic 1.8+ and 2.x through one package. It is still pre-1.0, and 0.5.0 made breaking changes: explicit version imports moved to v3_0 and v3_1 directories, OpenAPI targets advanced to 3.0.4 and 3.1.1, and Parameter.explode changed from False to None. The latest patch also changes generated reference strings when model names contain invalid characters.
Docs3/5The README covers object construction, parsing with version inference, mixed dictionary and model input, Pydantic schema conversion, dump flags, versioned imports, and Pydantic compatibility. Version-specific READMEs list aliases and the four container types implemented as dictionaries. There is no hosted searchable reference for every class and field, and one README link for OpenAPI 3.0 is malformed, so detailed work often requires reading source files.
Maintenance2/5PyPI dates version 0.5.1 to 2025-01-08, and GitHub reports the last push on 2025-11-24. The repository is not archived or disabled and has 13 open issues and pull requests, but it has gone more than a year without a package release. The latest release contains one functional `$ref` fix and one test adjustment, leaving future Pydantic and OpenAPI compatibility dependent on a small project with a slow cadence.
Ecosystem3/5The supplied registry count is 13533890 weekly downloads, while GitHub shows 122 stars. The package supports both current Pydantic families and both OpenAPI 3.0.4 and 3.1.1, which makes it easy for other tools to depend on quietly. Its own extension ecosystem is small: it has one schema-construction helper, no framework adapters in the README, no client generator, and no hosted renderer.

Use it if

  • A Python build step assembles OpenAPI documents and nested dictionaries have made field names, required values, or object shapes too easy to get wrong.
  • Request and response bodies already use Pydantic classes and should be collected into components/schemas with generated references.
  • A linter, converter, or diff tool needs typed access to OpenAPI 3.1.1 or 3.0.4 documents after parsing JSON or YAML.
  • The web framework does not produce an OpenAPI document and the team wants to keep spec construction in Python.
Skip it if

Setup reality

We installed openapi-pydantic 0.5.1 in a fresh Python 3.12 container in 0.6 seconds. Six packages occupied 8 MB afterward. The distribution is pure Python, declares one direct dependency, supports Python >=3.8,<4.0, ships py.typed, and uses the MIT license. pip-audit found zero known vulnerabilities. import openapi_pydantic succeeded in 0.56 seconds.

There are no credentials, plugins, native build tools, or config files. Pydantic >=1.8 is the only declared dependency, and the package contains a compatibility layer for Pydantic 1 and 2. README examples use model_validate and model_dump_json for Pydantic 2; Pydantic 1 callers use parse_obj and json. The compatibility module is internal and is not presented as an API for downstream imports.

Serialization needs two flags every time: by_alias=True writes $ref, in, schema, and other OpenAPI names instead of Python-safe field names, while exclude_none=True removes absent optional values. Parameter uses param_in for in, Reference and PathItem use ref for $ref, and Schema renames format, not, if, and else fields. The models allow population by either the field name or alias, but a dump without aliases is not a valid OpenAPI document.

Top-level imports select OpenAPI 3.1.1. OpenAPI 3.0.4 lives under openapi_pydantic.v3.v3_0, including its separate util module. Mixing objects from both trees produces validation failures. The 0.5.0 release changed the explicit version paths and made Parameter.explode default to None. Version 0.5.1 sanitizes characters in generated component reference names, so code comparing exact $ref strings should test the substituted form.

Patterns

Construct a small OpenAPI document build-document

from openapi_pydantic import Info, OpenAPI, Operation, PathItem, Response

spec = OpenAPI(
    info=Info(title="Billing API", version="1.0.0"),
    paths={
        "/health": PathItem(
            get=Operation(responses={"200": Response(description="healthy")})
        )
    },
)

The top-level import builds an OpenAPI 3.1.1 document. Paths and response maps are dictionaries with dynamic keys.

Serialize valid OpenAPI keys dump-json

document = spec.model_dump_json(
    by_alias=True,
    exclude_none=True,
    indent=2,
)

This is the Pydantic 2 form. Use spec.json with the same flags on Pydantic 1; omitting by_alias writes Python-safe names instead of OpenAPI keys.

Produce a dictionary for YAML dump-dictionary

payload = spec.model_dump(by_alias=True, exclude_none=True)
# yaml.safe_dump(payload, sort_keys=False)

Use dict(by_alias=True, exclude_none=True) on Pydantic 1. A YAML serializer is outside this package.

Infer the OpenAPI model version parse-version

from openapi_pydantic import parse_obj

spec = parse_obj({
    "openapi": "3.1.1",
    "info": {"title": "Billing API", "version": "1.0.0"},
    "paths": {},
})

parse_obj inspects the document version. Use an explicit versioned class when the accepted OpenAPI line must be fixed by application policy.

Create a path parameter set-parameter-alias

from openapi_pydantic import Parameter, ParameterLocation, Schema

account_id = Parameter(
    name="account_id",
    param_in=ParameterLocation.PATH,
    required=True,
    param_schema=Schema(type="string"),
)

param_in and param_schema serialize as in and schema only when by_alias=True is used.

Point to a component schema reference-component

from openapi_pydantic import Reference

account_ref = Reference(ref="#/components/schemas/Account")

ref is the Python field for `$ref`. The alias appears in serialized output when alias dumping is enabled.

Register a reusable schema add-components

from openapi_pydantic import Components, Schema

spec.components = Components(
    schemas={
        "Account": Schema(
            type="object",
            properties={"id": {"type": "string"}},
            required=["id"],
        )
    }
)

Schema properties may contain model objects or dictionaries. Validation catches known outer fields but cannot turn every free-form nested keyword into a dedicated class.

Collect application schemas convert-pydantic-models

from pydantic import BaseModel
from openapi_pydantic.util import PydanticSchema, construct_open_api_with_schema_class

class Account(BaseModel):
    id: str

placeholder = PydanticSchema(schema_class=Account)
# place placeholder in request or response content first
spec = construct_open_api_with_schema_class(spec)

The helper walks placeholders, adds generated schemas under components, and substitutes references. Release 0.5.1 replaces invalid reference-name characters with underscores.

Describe a JSON request body add-request-body

from openapi_pydantic import MediaType, RequestBody
from openapi_pydantic.util import PydanticSchema

body = RequestBody(
    required=True,
    content={
        "application/json": MediaType(
            media_type_schema=PydanticSchema(schema_class=Account)
        )
    },
)

media_type_schema is aliased to schema. Run construct_open_api_with_schema_class after the placeholder is attached to the document.

Describe header API-key authentication define-api-key

from openapi_pydantic import Components, SecurityScheme

components = Components(
    securitySchemes={
        "ApiKey": SecurityScheme(
            type="apiKey",
            name="X-API-Key",
            security_scheme_in="header",
        )
    }
)

security_scheme_in is the Python-safe form of in. This documents authentication and does not enforce it at runtime.

Build an OpenAPI 3.0.4 document target-openapi-30

from openapi_pydantic.v3.v3_0 import Info, OpenAPI

spec_30 = OpenAPI(
    info=Info(title="Legacy API", version="1.0.0"),
    paths={},
)

Import every related model and utility from v3.v3_0. Mixing 3.0 and 3.1 model trees leads to confusing validation errors.

Validate raw input with Pydantic 2 validate-dictionary

from openapi_pydantic import OpenAPI
from pydantic import ValidationError

try:
    spec = OpenAPI.model_validate(raw_document)
except ValidationError as error:
    print(error.errors())

Use OpenAPI.parse_obj on Pydantic 1. Validation checks the modeled structure; dedicated semantic spec validators may enforce additional cross-field OpenAPI rules.

Alternatives

PackageRegistryPick it when
fastapiPyPIChoose it when route declarations should drive both request handling and automatic OpenAPI generation.
apispecPyPIChoose it for plugin-based document generation, especially around Marshmallow schemas and framework integrations.
datamodel-code-generatorPyPIChoose it when an existing OpenAPI document must become Python and Pydantic source code.
openapi-spec-validatorPyPIChoose it when the job is validating a completed OpenAPI file rather than constructing and editing it as Python objects.

More utils guides

lru-cache · ajv · type-fest · p-limit · find-up · js-yaml · the whole shelf →

How this guide is made: grounded in the library's documentation, release notes, changelog, and issue history, on a fixed rubric — not a hands-on install of every release. The 50 most-downloaded entries are additionally install-verified in clean containers. Corrections: contact the desk.