Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 13 additions & 6 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ Openapi-schema-validator is a Python library that validates schema against:

* `OpenAPI Schema Specification v3.0 <https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#schemaObject>`__ which is an extended subset of the `JSON Schema Specification Wright Draft 00 <http://json-schema.org/>`__.
* `OpenAPI Schema Specification v3.1 <https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#schemaObject>`__ which is an extended superset of the `JSON Schema Specification Draft 2020-12 <http://json-schema.org/>`__.
* `OpenAPI Schema Specification v3.2 <https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.2.0.md#schemaObject>`__ which uses the same JSON Schema dialect as v3.1.
* `OpenAPI Schema Specification v3.2 <https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.2.0.md#schemaObject>`__ using the published OAS 3.2 JSON Schema dialect resources.


Documentation
Expand Down Expand Up @@ -100,25 +100,32 @@ To validate an OpenAPI v3.1 schema:

By default, the latest OpenAPI schema syntax is expected.

The OpenAPI 3.1 base dialect URI is registered for
The OpenAPI 3.1 and 3.2 base dialect URIs are registered for
``jsonschema.validators.validator_for`` resolution.
Schemas declaring
``"$schema": "https://spec.openapis.org/oas/3.1/dialect/base"``
resolve directly to ``OAS31Validator`` without unresolved-metaschema
fallback warnings.
Schemas declaring ``"$schema"`` as either
``"https://spec.openapis.org/oas/3.1/dialect/base"`` or
``"https://spec.openapis.org/oas/3.2/dialect/2025-09-17"`` resolve
directly to ``OAS31Validator`` and ``OAS32Validator`` without
unresolved-metaschema fallback warnings.

.. code-block:: python

from jsonschema.validators import validator_for

from openapi_schema_validator import OAS31Validator
from openapi_schema_validator import OAS32Validator

schema = {
"$schema": "https://spec.openapis.org/oas/3.1/dialect/base",
"type": "object",
}
schema32 = {
"$schema": "https://spec.openapis.org/oas/3.2/dialect/2025-09-17",
"type": "object",
}

assert validator_for(schema) is OAS31Validator
assert validator_for(schema32) is OAS32Validator


Strict vs Pragmatic Validators
Expand Down
2 changes: 1 addition & 1 deletion docs/format.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,4 @@ You can check format for predefined OAS primitive types
...
ValidationError: '-12' is not a 'date'
For OpenAPI 3.2, use ``oas32_format_checker`` (behaves identically to ``oas31_format_checker``, since 3.2 uses the same JSON Schema dialect).
For OpenAPI 3.2, use ``oas32_format_checker``.
2 changes: 1 addition & 1 deletion docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ Openapi-schema-validator is a Python library that validates schema against:

* `OpenAPI Schema Specification v3.0 <https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#schemaObject>`__ which is an extended subset of the `JSON Schema Specification Wright Draft 00 <http://json-schema.org/>`__.
* `OpenAPI Schema Specification v3.1 <https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#schemaObject>`__ which is an extended superset of the `JSON Schema Specification Draft 2020-12 <http://json-schema.org/>`__.
* `OpenAPI Schema Specification v3.2 <https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.2.0.md#schemaObject>`__ which uses the same JSON Schema dialect as v3.1.
* `OpenAPI Schema Specification v3.2 <https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.2.0.md#schemaObject>`__ using the published OAS 3.2 JSON Schema dialect resources.

Installation
------------
Expand Down
17 changes: 12 additions & 5 deletions docs/validation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -67,26 +67,33 @@ if you want to disambiguate the expected schema version, import and use ``OAS31V

validate({"name": "John", "age": 23}, schema, cls=OAS31Validator)

The OpenAPI 3.1 base dialect URI is registered for
The OpenAPI 3.1 and 3.2 base dialect URIs are registered for
``jsonschema.validators.validator_for`` resolution.
If your schema declares
``"$schema": "https://spec.openapis.org/oas/3.1/dialect/base"``,
``validator_for`` resolves directly to ``OAS31Validator`` without
unresolved-metaschema fallback warnings.
``"$schema": "https://spec.openapis.org/oas/3.1/dialect/base"`` or
``"$schema": "https://spec.openapis.org/oas/3.2/dialect/2025-09-17"``,
``validator_for`` resolves directly to ``OAS31Validator`` or
``OAS32Validator`` without unresolved-metaschema fallback warnings.

.. code-block:: python

from jsonschema.validators import validator_for

from openapi_schema_validator import OAS31Validator
from openapi_schema_validator import OAS32Validator

schema = {
"$schema": "https://spec.openapis.org/oas/3.1/dialect/base",
"type": "object",
}
schema32 = {
"$schema": "https://spec.openapis.org/oas/3.2/dialect/2025-09-17",
"type": "object",
}
assert validator_for(schema) is OAS31Validator
assert validator_for(schema32) is OAS32Validator

For OpenAPI 3.2, use ``OAS32Validator`` (behaves identically to ``OAS31Validator``, since 3.2 uses the same JSON Schema dialect).
For OpenAPI 3.2, use ``OAS32Validator``.

In order to validate OpenAPI 3.0 schema, import and use ``OAS30Validator`` instead of ``OAS31Validator``.

Expand Down
4 changes: 4 additions & 0 deletions openapi_schema_validator/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from openapi_schema_validator._dialects import OAS31_BASE_DIALECT_ID
from openapi_schema_validator._dialects import OAS32_BASE_DIALECT_ID
from openapi_schema_validator._format import oas30_format_checker
from openapi_schema_validator._format import oas30_strict_format_checker
from openapi_schema_validator._format import oas31_format_checker
Expand Down Expand Up @@ -28,4 +30,6 @@
"oas31_format_checker",
"OAS32Validator",
"oas32_format_checker",
"OAS31_BASE_DIALECT_ID",
"OAS32_BASE_DIALECT_ID",
]
6 changes: 6 additions & 0 deletions openapi_schema_validator/_dialects.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,19 @@
__all__ = [
"OAS31_BASE_DIALECT_ID",
"OAS31_BASE_DIALECT_METASCHEMA",
"OAS32_BASE_DIALECT_ID",
"OAS32_BASE_DIALECT_METASCHEMA",
"register_openapi_dialect",
]

OAS31_BASE_DIALECT_ID = "https://spec.openapis.org/oas/3.1/dialect/base"
OAS31_BASE_DIALECT_METASCHEMA = OPENAPI_SPECIFICATIONS.contents(
OAS31_BASE_DIALECT_ID,
)
OAS32_BASE_DIALECT_ID = "https://spec.openapis.org/oas/3.2/dialect/2025-09-17"
OAS32_BASE_DIALECT_METASCHEMA = OPENAPI_SPECIFICATIONS.contents(
OAS32_BASE_DIALECT_ID,
)

_REGISTERED_VALIDATORS: dict[tuple[str, str], Any] = {}

Expand Down
25 changes: 25 additions & 0 deletions openapi_schema_validator/schemas/oas3.2/dialect/2025-09-17.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"$id": "https://spec.openapis.org/oas/3.2/dialect/2025-09-17",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "OpenAPI 3.2 Schema Object Dialect",
"description": "A JSON Schema dialect describing schemas found in OpenAPI v3.2.x Descriptions",
"$dynamicAnchor": "meta",
"$vocabulary": {
"https://json-schema.org/draft/2020-12/vocab/applicator": true,
"https://json-schema.org/draft/2020-12/vocab/content": true,
"https://json-schema.org/draft/2020-12/vocab/core": true,
"https://json-schema.org/draft/2020-12/vocab/format-annotation": true,
"https://json-schema.org/draft/2020-12/vocab/meta-data": true,
"https://json-schema.org/draft/2020-12/vocab/unevaluated": true,
"https://json-schema.org/draft/2020-12/vocab/validation": true,
"https://spec.openapis.org/oas/3.2/vocab/base": false
},
"allOf": [
{
"$ref": "https://json-schema.org/draft/2020-12/schema"
},
{
"$ref": "https://spec.openapis.org/oas/3.2/meta/2025-09-17"
}
]
}
114 changes: 114 additions & 0 deletions openapi_schema_validator/schemas/oas3.2/meta/2025-09-17.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
{
"$id": "https://spec.openapis.org/oas/3.2/meta/2025-09-17",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "OAS Base Vocabulary",
"description": "A JSON Schema Vocabulary used in the OpenAPI JSON Schema Dialect",
"$dynamicAnchor": "meta",
"$vocabulary": {
"https://spec.openapis.org/oas/3.2/vocab/base": true
},
"type": [
"object",
"boolean"
],
"properties": {
"discriminator": {
"$ref": "#/$defs/discriminator"
},
"example": {
"deprecated": true
},
"externalDocs": {
"$ref": "#/$defs/external-docs"
},
"xml": {
"$ref": "#/$defs/xml"
}
},
"$defs": {
"discriminator": {
"$ref": "#/$defs/extensible",
"properties": {
"mapping": {
"additionalProperties": {
"type": "string"
},
"type": "object"
},
"defaultMapping": {
"type": "string"
},
"propertyName": {
"type": "string"
}
},
"type": "object",
"unevaluatedProperties": false
},
"extensible": {
"patternProperties": {
"^x-": true
}
},
"external-docs": {
"$ref": "#/$defs/extensible",
"properties": {
"description": {
"type": "string"
},
"url": {
"format": "uri-reference",
"type": "string"
}
},
"required": [
"url"
],
"type": "object",
"unevaluatedProperties": false
},
"xml": {
"$ref": "#/$defs/extensible",
"properties": {
"nodeType": {
"type": "string",
"enum": [
"element",
"attribute",
"text",
"cdata",
"none"
]
},
"name": {
"type": "string"
},
"namespace": {
"format": "iri",
"type": "string"
},
"prefix": {
"type": "string"
},
"attribute": {
"type": "boolean",
"deprecated": true
},
"wrapped": {
"type": "boolean",
"deprecated": true
}
},
"type": "object",
"dependentSchemas": {
"nodeType": {
"properties": {
"attribute": false,
"wrapped": false
}
}
},
"unevaluatedProperties": false
}
}
}
13 changes: 7 additions & 6 deletions openapi_schema_validator/shortcuts.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,15 @@
from jsonschema.protocols import Validator

from openapi_schema_validator._dialects import OAS31_BASE_DIALECT_ID
from openapi_schema_validator.validators import OAS31Validator
from openapi_schema_validator._dialects import OAS32_BASE_DIALECT_ID
from openapi_schema_validator.validators import OAS32Validator
from openapi_schema_validator.validators import check_openapi_schema


def validate(
instance: Any,
schema: Mapping[str, Any],
cls: type[Validator] = OAS31Validator,
cls: type[Validator] = OAS32Validator,
*args: Any,
**kwargs: Any
) -> None:
Expand All @@ -24,11 +25,11 @@ def validate(

meta_schema = getattr(cls, "META_SCHEMA", None)
# jsonschema's default check_schema path does not accept a custom
# registry, so for the OAS 3.1 dialect we use the package registry
# registry, so for OAS dialects we use the package registry
# explicitly to keep metaschema resolution local and deterministic.
if (
isinstance(meta_schema, dict)
and meta_schema.get("$id") == OAS31_BASE_DIALECT_ID
if isinstance(meta_schema, dict) and meta_schema.get("$id") in (
OAS31_BASE_DIALECT_ID,
OAS32_BASE_DIALECT_ID,
):
check_openapi_schema(cls, schema_dict)
else:
Expand Down
28 changes: 19 additions & 9 deletions openapi_schema_validator/validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
from openapi_schema_validator import _types as oas_types
from openapi_schema_validator._dialects import OAS31_BASE_DIALECT_ID
from openapi_schema_validator._dialects import OAS31_BASE_DIALECT_METASCHEMA
from openapi_schema_validator._dialects import OAS32_BASE_DIALECT_ID
from openapi_schema_validator._dialects import OAS32_BASE_DIALECT_METASCHEMA
from openapi_schema_validator._dialects import register_openapi_dialect
from openapi_schema_validator._specifications import (
REGISTRY as OPENAPI_SPECIFICATIONS,
Expand Down Expand Up @@ -134,6 +136,20 @@ def _build_oas31_validator() -> Any:
)


def _build_oas32_validator() -> Any:
validator = extend(
OAS31Validator,
{},
format_checker=oas_format.oas32_format_checker,
)
return register_openapi_dialect(
validator=validator,
dialect_id=OAS32_BASE_DIALECT_ID,
version_name="oas32",
metaschema=OAS32_BASE_DIALECT_METASCHEMA,
)


OAS30Validator = _build_oas30_validator()
OAS30StrictValidator = extend(
OAS30Validator,
Expand Down Expand Up @@ -162,13 +178,7 @@ def _build_oas31_validator() -> Any:
)

OAS31Validator = _build_oas31_validator()
OAS32Validator = _build_oas32_validator()

# OAS 3.2 uses JSON Schema Draft 2020-12 as its base dialect, same as
# OAS 3.1. The OAS-specific vocabulary differs slightly (e.g. xml keyword
# changes), but since xml is not_implemented in the current validators,
# the behavior is equivalent.
OAS32Validator = extend(
OAS31Validator,
{},
format_checker=oas_format.oas32_format_checker,
)
OAS31Validator.check_schema = classmethod(check_openapi_schema)
OAS32Validator.check_schema = classmethod(check_openapi_schema)
Loading
Loading