openapi-core Documentation

repository·master·Indexed 18 days ago

https://github.com/python-openapi/openapi-core

A Python library providing client-side and server-side support for OpenAPI Specification v3.0, v3.1, and v3.2. It enables validation and unmarshalling of request and response data with integrations for frameworks including FastAPI, Flask, Django, Starlette, AIOHTTP, Falcon, Requests, and Werkzeug. Features include customizable Config objects for validator and unmarshaller classes, support for custom media type deserializers, and extensions like x-model and x-model-path for custom model unmarshalling.

Tokens
20.5K
Snippets
67
Records
82
Agent score
62%

What's inside openapi-core

  1. What is unmarshalling in openapi-core

    master

    Unmarshalling is the process of converting primitive schema type values into higher-level Python objects based on the format keyword in an OpenAPI specification.

    Before unmarshalling, the data is first validated against the provided schema.

    Built-in format unmarshallers include:

    • date: converts a string into a date object
    • date-time: converts a string into a datetime object
    • binary: converts a string into a byte object
    • uuid: converts a string into a UUID object
    • byte: decodes a Base64-encoded string

    Note: For backward compatibility, OpenAPI 3.1 unmarshalling currently supports byte and binary format handling.

  2. Use x-model to unmarshal objects to dynamically created dataclasses

    master

    By default, openapi-core unmarshals OpenAPI objects into standard Python dictionaries. To unmarshal objects into dynamically created dataclasses instead, add the x-model property to your schema definition in your OpenAPI specification. The value of x-model should be the name of the model class you wish to use.

    # openapi.yaml
    components:
      schemas:
        Coordinates:
          x-model: Coordinates
          type: object
          required:
            - lat
            - lon
          properties:
            lat:
              type: number
            lon:
              type: number

    As a result of the unmarshalling process, you will receive a Coordinates class instance with lat and lon attributes.

  3. How OpenAPI format validation works

    master

    During the validation process, openapi-core uses the format keyword in the OpenAPI specification to check if primitive types conform to specific formats.

    Built-in format validators include:

    • date
    • date-time
    • binary
    • uuid
    • byte

    Note: For backward compatibility, OpenAPI 3.1 validation in openapi-core currently accepts OpenAPI 3.0-style format checker behavior, including byte and binary. Validated formats can be further unmarshalled (see the Unmarshalling guide). You can also define custom format validators in your configuration.

  4. Use x-model-path to unmarshal objects to custom models

    master

    If you want to use your own pre-defined models—such as custom dataclasses, Pydantic models, or models generated by tools like datamodel-code-generator—use the x-model-path property in your OpenAPI schema. The value must be the full Python import path to your class.

    # openapi.yaml
    components:
      schemas:
        Coordinates:
          x-model-path: foo.bar.Coordinates
          type: object
          required:
            - lat
            - lon
          properties:
            lat:
              type: number
            lon:
              type: number
    # foo/bar.py
    from dataclasses import dataclass
    
    @dataclass
    class Coordinates:
        lat: float
        lon: float

    Unmarshalling will now produce an instance of your specific foo.bar.Coordinates class.

  5. Configure the openapi-core Config object

    master

    The Config object allows you to customize the behavior of validation and unmarshalling processes in openapi-core. You can pass a Config instance when initializing an OpenAPI instance to control specification validation, validator classes, unmarshaller classes, and strictness policies.

    from openapi_core import Config, OpenAPI
    
    config = Config(
        # configuration options go here
    )
    openapi = OpenAPI.from_file_path('openapi.json', config=config)
  6. Enable strict additional properties validation

    master

    By default, openapi-core follows JSON Schema behavior where extra keys are allowed if additionalProperties is omitted. To enforce stricter validation (e.g., to prevent data leaks or catch client typos), set additional_properties_default_policy to "forbid" in Config.

    In this mode:

    • Object schemas with omitted additionalProperties will reject unknown fields.
    • Object schemas with additionalProperties: true will still allow unknown fields.
    from openapi_core import Config, OpenAPI
    
    config = Config(
        additional_properties_default_policy="forbid",
    )
    openapi = OpenAPI.from_file_path('openapi.json', config=config)
  7. Disable specification validation for performance

    master

    By default, openapi-core validates the provided OpenAPI specification when creating an OpenAPI instance. If you already have a verified specification and want to improve performance, you can disable this by setting spec_validator_cls=None in the Config object.

    from openapi_core import Config, OpenAPI
    
    config = Config(
        spec_validator_cls=None,
    )
    openapi = OpenAPI.from_file_path('openapi.json', config=config)
  8. Add extra format validators

    master

    You can add support for custom format keywords by passing a dictionary to the extra_format_validators option in Config. The dictionary keys are the format names (e.g., 'usdate'), and the values are functions that return True if the value is valid or False otherwise.

    import re
    from openapi_core import Config, OpenAPI
    
    def validate_usdate(value):
        return bool(re.match(r"^\d{1,2}/\d{1,2}/\d{4}$", value))
    
    extra_format_validators = {
        'usdate': validate_usdate,
    }
    
    config = Config(
        extra_format_validators=extra_format_validators,
    )
    openapi = OpenAPI.from_file_path('openapi.json', config=config)
    
    openapi.validate_response(request, response)
  9. Integrate openapi-core with Starlette using Middleware

    master

    You can apply OpenAPI validation to your entire Starlette application by adding StarletteOpenAPIMiddleware to your middleware list. This middleware validates both incoming requests and outgoing responses against your OpenAPI object.

    To skip response validation (e.g., for performance or if you handle it manually), set response_cls=None in the middleware configuration.

    from openapi_core.contrib.starlette.middlewares import StarletteOpenAPIMiddleware
    from starlette.applications import Starlette
    from starlette.middleware import Middleware
    
    # Standard validation (requests and responses)
    middleware = [
        Middleware(StarletteOpenAPIMiddleware, openapi=openapi),
    ]
    
    # To skip response validation, use response_cls=None
    middleware_no_response_validation = [
        Middleware(StarletteOpenAPIMiddleware, openapi=openapi, response_cls=None),
    ]
    
    app = Starlette(
        # ...
        middleware=middleware,
    )
  10. Add extra format unmarshallers

    master

    To convert values with specific format keywords into Python objects, pass a dictionary to the extra_format_unmarshallers option in Config. The dictionary keys are the format names, and the values are functions that take the raw value and return the converted object.

    from datetime import datetime
    from openapi_core import Config, OpenAPI
    
    def unmarshal_usdate(value):
        return datetime.strptime(value, "%m/%d/%Y").date()
    
    extra_format_unmarshallers = {
        'usdate': unmarshal_usdate,
    }
    
    config = Config(
        extra_format_unmarshallers=extra_format_unmarshallers,
    )
    openapi = OpenAPI.from_file_path('openapi.json', config=config)
    
    result = openapi.unmarshal_response(request, response)
  11. Integrate openapi-core with Flask using view decorators

    master

    You can apply OpenAPI validation to specific Flask routes using the FlaskOpenAPIViewDecorator. This decorator uses an OpenAPI object to validate incoming requests and outgoing responses.

    To skip response validation (validating only the request), set response_cls=None when initializing the decorator.

    For class-based views, add the decorator instance to the decorators list attribute of the class.

    from openapi_core.contrib.flask.decorators import FlaskOpenAPIViewDecorator
    
    # Initialize the decorator with your openapi object
    openapi_validated = FlaskOpenAPIViewDecorator(openapi)
    
    # Use it on a function-based view
    @app.route('/home')
    @openapi_validated
    def home():
        return "Welcome home"
    
    # Or use it on a class-based view
    class MyView(View):
        decorators = [openapi_validated]
    
        def dispatch_request(self):
            return "Welcome home"
    
    app.add_url_rule('/home', view_func=MyView.as_view('home'))
  12. Integrate openapi-core with Falcon via Middleware

    master

    To integrate openapi-core with a Falcon application, use the provided middleware classes. The integration supports Falcon version 4.

    Warning: This integration does not support multipart form body requests.

    Depending on your application type, choose the appropriate middleware class:

    • For falcon.App (WSGI), use FalconWSGIOpenAPIMiddleware.
    • For falcon.asgi.App (ASGI), use FalconASGIOpenAPIMiddleware.
    • FalconOpenAPIMiddleware is a base class that supports both, but explicit classes are recommended for clarity.
    from openapi_core.contrib.falcon.middlewares import FalconWSGIOpenAPIMiddleware
    
    # Initialize middleware from an OpenAPI spec
    openapi_middleware = FalconWSGIOpenAPIMiddleware.from_spec(spec)
    
    app = falcon.App(
        # ...
        middleware=[openapi_middleware],
    )