Source code for pydantic_openapi_helper.core

from typing import List, Any, Dict

# Pydantic V2: Use models_json_schema instead of schema
from pydantic.json_schema import models_json_schema

from .helper import clean_schemas
from .inheritance import get_schemas_inheritance


"""base open api dictionary for all schemas."""
_base_open_api = {
    "openapi": "3.0.2",
    "servers": [],
    "info": {},
    "externalDocs": {},
    "tags": [],
    "x-tagGroups": [
        {
            "name": "Models",
            "tags": []
        }
    ],
    "paths": {},
    "components": {"schemas": {}}
}


[docs] def get_openapi( base_object: List[Any], title: str = None, version: str = None, openapi_version: str = "3.0.2", description: str = None, info: dict = None, external_docs: dict = None, inheritance: bool = False, add_discriminator: bool = True ) -> Dict: """Get openapi compatible dictionary from a list of Pydantic objects. Args: base_objects: A list of Pydantic model objects to be included in the OpenAPI schema. title: An optional title for OpenAPI title in info field. version: Schema version to set the version in info. openapi_version: Version for OpenAPI schema. Default is 3.0.2. description: A short description for schema info. info: Schema info as a dictionary. You can use this input to provide title, version and description together. external_docs: Link to external docs for schema. inheritance: A boolean to whether the OpenAPI specification should be modified to use polymorphism. We use Pydantic to generate the initial version and then post-process the output dictionary to generate the new schema. Returns: Dict -- OpenAPI schema as a dictionary. """ open_api = dict(_base_open_api) open_api['openapi'] = openapi_version if info: open_api['info'] = info if title: if 'info' not in open_api: open_api['info'] = {} open_api['info']['title'] = title if not version: raise ValueError( 'Schema version must be specified as argument or from distribution metadata' ) if version: if 'info' not in open_api: open_api['info'] = {} open_api['info']['version'] = version if description: if 'info' not in open_api: open_api['info'] = {} open_api['info']['description'] = description if external_docs: open_api['externalDocs'] = external_docs if not inheritance: # Pydantic V2 Change: # schema() is removed. models_json_schema takes a list of (model, mode) tuples. # It returns (schema, definitions). # ref_prefix is replaced by ref_template. inputs = [(m, 'validation') for m in base_object] _, schemas = models_json_schema(inputs, ref_template='#/components/schemas/{model}') # Pydantic V2 Compatibility Fix: # If the returned definitions are wrapped in a '$defs' key, extract them. # This ensures 'schemas' is a flat dict of {ModelName: Schema} schemas = schemas.get('$defs', schemas) else: schemas = get_schemas_inheritance(base_object) # Ensure inheritance schemas also strip $defs if present schemas = schemas.get('$defs', schemas) schemas, tags, tag_names = clean_schemas( schemas, add_tags=True, add_discriminator=inheritance and add_discriminator, add_type=True ) open_api['tags'] = tags open_api['x-tagGroups'][0]['tags'] = tag_names open_api['components']['schemas'] = schemas return open_api