openapi-core
Validates and unmarshals HTTP requests and responses against OpenAPI 3.0, 3.1, and 3.2 specifications for Python web frameworks.
Repository Health
Technical Analysis
openapi-core is a Python library that turns an OpenAPI 3.0, 3.1, or 3.2 specification into an enforceable contract for both sides of an HTTP exchange. Given a spec and a request or response object, it validates the payload against the schema and unmarshals it into typed Python values — parameters, body, and security data — in a single pass, so application code works with checked, coerced data instead of raw strings and dictionaries.
The library ships native integrations for Django, Flask, FastAPI, Falcon, Starlette, aiohttp, Werkzeug, and Requests, each implemented as a thin adapter against a Request/Response Protocol rather than a framework-specific fork, so the same validation core backs middleware, decorators, and low-level classes across the whole matrix. It also validates webhook requests and responses (OpenAPI 3.1+) and supports pluggable format validators, media-type deserializers, and security providers for teams with custom conventions.
What You Get
- A single
OpenAPIentrypoint class withfrom_dict/from_path/from_file_path/from_fileconstructors for loading a spec from memory or disk. - Version-aware validators and unmarshallers for OpenAPI 3.0, 3.1, and 3.2, selected automatically from the spec’s declared version.
- Native request/response adapters for Django, Flask, FastAPI, Falcon, Starlette, aiohttp, Werkzeug, and Requests.
- Webhook request/response validation and unmarshalling for OpenAPI 3.1+ specs.
- Pluggable factories for style deserializers, media-type deserializers, schema casters/validators/unmarshallers, and security providers.
Common Use Cases
- Rejecting malformed API requests before they reach business logic, using the OpenAPI spec as the single source of truth.
- Unmarshalling validated request/response data into typed Python objects instead of hand-parsing query strings and JSON bodies.
- Contract-testing a service’s real responses against its published OpenAPI spec in CI.
- Validating inbound webhook payloads against a documented webhook schema before processing them.
Under The Hood
Architecture
The OpenAPI class in app.py is the facade: it wraps a parsed spec, lazily builds version-specific validator/unmarshaller instances via cached_property, and resolves each one from a SpecVersion-keyed dict (REQUEST_VALIDATORS, RESPONSE_UNMARSHALLERS, etc.) unless a Config override is supplied. Configuration (configurations.py) is entirely dependency-injected — style deserializer, media-type deserializer, schema caster, schema validator, schema unmarshaller, and security-provider factories are all swappable. The validation pipeline is layered: templating/paths resolves the matching path template, deserializing/media_types and deserializing/styles decode the raw request into primitives per the OpenAPI parameter-style rules, casting/schemas coerces values to the declared schema type, and validation/schemas or unmarshalling/schemas checks and (optionally) converts them, with security/ evaluating auth schemes alongside. Every framework integration in contrib/ is a thin adapter that satisfies the Request/Response Protocol defined in protocols.py, so adding support for a new framework never touches the validation core.
Tech Stack
A Python 3.10+ library built with Poetry. Core dependencies are jsonschema-path for spec/ref loading, jsonschema for schema validation, sibling projects openapi-spec-validator and openapi-schema-validator for spec/schema conformance, isodate for date/duration parsing, and typing-extensions for the Annotated/Doc-based typed public API. Framework integrations (Django 4-6, Flask 2/3, FastAPI 0.11x-0.13x, Falcon 4, Starlette 0.4x-1.x, aiohttp 3.x, Requests, Werkzeug) are all optional extras rather than hard dependencies. Tooling includes mypy --strict, black, isort, pre-commit, deptry, and a tox matrix that runs each contrib integration against multiple framework version ranges independently of the core test suite. Docs are built with mkdocs-material and mkdocstrings, generated directly from the typed docstrings.
Code Quality
Tests are split into unit/ (isolated logic, heavily parametrized with pytest) and integration/ (real spec validation/unmarshalling round-trips plus per-framework contrib tests), with a separate benchmarks/ suite. mypy --strict is enforced across the whole openapi_core package, and the public API is annotated with typing_extensions.Doc() on every parameter, which both documents and type-checks the interface. CI runs the core suite across Python 3.10-3.14 and a second workflow runs the full tox contrib matrix, so a new Django or FastAPI release can’t silently break an integration. Errors use an explicit OpenAPIError/SpecError hierarchy, and app.py raises TypeError immediately when a caller passes an object that doesn’t satisfy the Request/Response Protocol rather than failing later with an unclear error.
What Makes It Unique
Most JSON Schema validators stop at the schema; openapi-core operates on the full HTTP semantics an OpenAPI spec describes — path-template parameter extraction, per-parameter style deserialization (form/simple/matrix/label), media-type-aware body decoding, and security-scheme evaluation — then validates and unmarshals in one pass, returning typed data instead of a pass/fail result. The Protocol-based Request/Response interface decouples the validation core from any specific web framework, which is how a single library ends up with native adapters for eight different Python frameworks and HTTP clients. It’s also an early adopter of the (at time of writing) unreleased OpenAPI 3.2 draft alongside full 3.0/3.1 support.