Adding upstream version 0.5.1.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
303fa6e9d8
commit
97e6d74bac
110 changed files with 12006 additions and 0 deletions
38
openapi_pydantic/__init__.py
Normal file
38
openapi_pydantic/__init__.py
Normal file
|
@ -0,0 +1,38 @@
|
|||
import logging
|
||||
|
||||
from .v3 import XML as XML
|
||||
from .v3 import Callback as Callback
|
||||
from .v3 import Components as Components
|
||||
from .v3 import Contact as Contact
|
||||
from .v3 import DataType as DataType
|
||||
from .v3 import Discriminator as Discriminator
|
||||
from .v3 import Encoding as Encoding
|
||||
from .v3 import Example as Example
|
||||
from .v3 import ExternalDocumentation as ExternalDocumentation
|
||||
from .v3 import Header as Header
|
||||
from .v3 import Info as Info
|
||||
from .v3 import License as License
|
||||
from .v3 import Link as Link
|
||||
from .v3 import MediaType as MediaType
|
||||
from .v3 import OAuthFlow as OAuthFlow
|
||||
from .v3 import OAuthFlows as OAuthFlows
|
||||
from .v3 import OpenAPI as OpenAPI
|
||||
from .v3 import Operation as Operation
|
||||
from .v3 import Parameter as Parameter
|
||||
from .v3 import ParameterLocation as ParameterLocation
|
||||
from .v3 import PathItem as PathItem
|
||||
from .v3 import Paths as Paths
|
||||
from .v3 import Reference as Reference
|
||||
from .v3 import RequestBody as RequestBody
|
||||
from .v3 import Response as Response
|
||||
from .v3 import Responses as Responses
|
||||
from .v3 import Schema as Schema
|
||||
from .v3 import SecurityRequirement as SecurityRequirement
|
||||
from .v3 import SecurityScheme as SecurityScheme
|
||||
from .v3 import Server as Server
|
||||
from .v3 import ServerVariable as ServerVariable
|
||||
from .v3 import Tag as Tag
|
||||
from .v3 import parse_obj as parse_obj
|
||||
from .v3 import schema_validate as schema_validate
|
||||
|
||||
logging.getLogger(__name__).addHandler(logging.NullHandler())
|
119
openapi_pydantic/compat.py
Normal file
119
openapi_pydantic/compat.py
Normal file
|
@ -0,0 +1,119 @@
|
|||
"""Compatibility layer to make this package usable with Pydantic 1 or 2"""
|
||||
|
||||
from typing import TYPE_CHECKING, Dict, List, Optional, Tuple
|
||||
|
||||
from pydantic.version import VERSION as PYDANTIC_VERSION
|
||||
|
||||
__all__ = [
|
||||
"PYDANTIC_V2",
|
||||
"ConfigDict",
|
||||
"JsonSchemaMode",
|
||||
"models_json_schema",
|
||||
"RootModel",
|
||||
"Extra",
|
||||
"v1_schema",
|
||||
"DEFS_KEY",
|
||||
"min_length_arg",
|
||||
]
|
||||
|
||||
PYDANTIC_MAJOR_VERSION = int(PYDANTIC_VERSION.split(".", 1)[0])
|
||||
PYDANTIC_MINOR_VERSION = int(PYDANTIC_VERSION.split(".")[1])
|
||||
PYDANTIC_V2 = PYDANTIC_MAJOR_VERSION >= 2
|
||||
|
||||
if TYPE_CHECKING:
|
||||
# Provide stubs for either version of Pydantic
|
||||
|
||||
from enum import Enum
|
||||
from typing import Any, Literal, Type, TypedDict
|
||||
|
||||
from pydantic import BaseModel
|
||||
from pydantic import ConfigDict as PydanticConfigDict
|
||||
|
||||
def ConfigDict(
|
||||
extra: Literal["allow", "ignore", "forbid"] = "allow",
|
||||
json_schema_extra: Optional[Dict[str, Any]] = None,
|
||||
populate_by_name: bool = True,
|
||||
) -> PydanticConfigDict:
|
||||
"""Stub for pydantic.ConfigDict in Pydantic 2"""
|
||||
...
|
||||
|
||||
class Extra(Enum):
|
||||
"""Stub for pydantic.Extra in Pydantic 1"""
|
||||
|
||||
allow = "allow"
|
||||
ignore = "ignore"
|
||||
forbid = "forbid"
|
||||
|
||||
class RootModel(BaseModel):
|
||||
"""Stub for pydantic.RootModel in Pydantic 2"""
|
||||
|
||||
JsonSchemaMode = Literal["validation", "serialization"]
|
||||
|
||||
def models_json_schema(
|
||||
models: List[Tuple[Type[BaseModel], JsonSchemaMode]],
|
||||
*,
|
||||
by_alias: bool = True,
|
||||
ref_template: str = "#/$defs/{model}",
|
||||
schema_generator: Optional[type] = None,
|
||||
) -> Tuple[Dict, Dict[str, Any]]:
|
||||
"""Stub for pydantic.json_schema.models_json_schema in Pydantic 2"""
|
||||
...
|
||||
|
||||
def v1_schema(
|
||||
models: List[Type[BaseModel]],
|
||||
*,
|
||||
by_alias: bool = True,
|
||||
ref_prefix: str = "#/$defs",
|
||||
) -> Dict[str, Any]:
|
||||
"""Stub for pydantic.schema.schema in Pydantic 1"""
|
||||
...
|
||||
|
||||
DEFS_KEY = "$defs"
|
||||
|
||||
class MinLengthArg(TypedDict):
|
||||
pass
|
||||
|
||||
def min_length_arg(min_length: int) -> MinLengthArg:
|
||||
"""Generate a min_length or min_items parameter for Field(...)"""
|
||||
...
|
||||
|
||||
elif PYDANTIC_V2:
|
||||
from typing import TypedDict
|
||||
|
||||
from pydantic import ConfigDict, RootModel
|
||||
from pydantic.json_schema import JsonSchemaMode, models_json_schema
|
||||
|
||||
# Pydantic 2 renders JSON schemas using the keyword "$defs"
|
||||
DEFS_KEY = "$defs"
|
||||
|
||||
class MinLengthArg(TypedDict):
|
||||
min_length: int
|
||||
|
||||
def min_length_arg(min_length: int) -> MinLengthArg:
|
||||
return {"min_length": min_length}
|
||||
|
||||
# Create V1 stubs. These should not be used when PYDANTIC_V2 is true.
|
||||
Extra = None
|
||||
v1_schema = None
|
||||
|
||||
|
||||
else:
|
||||
from typing import TypedDict
|
||||
|
||||
from pydantic import Extra
|
||||
from pydantic.schema import schema as v1_schema
|
||||
|
||||
# Pydantic 1 renders JSON schemas using the keyword "definitions"
|
||||
DEFS_KEY = "definitions"
|
||||
|
||||
class MinLengthArg(TypedDict):
|
||||
min_items: int
|
||||
|
||||
def min_length_arg(min_length: int) -> MinLengthArg:
|
||||
return {"min_items": min_length}
|
||||
|
||||
# Create V2 stubs. These should not be used when PYDANTIC_V2 is false.
|
||||
ConfigDict = None
|
||||
models_json_schema = None
|
||||
JsonSchemaMode = None
|
||||
RootModel = None
|
1
openapi_pydantic/py.typed
Normal file
1
openapi_pydantic/py.typed
Normal file
|
@ -0,0 +1 @@
|
|||
# Marker file for PEP 561
|
188
openapi_pydantic/util.py
Normal file
188
openapi_pydantic/util.py
Normal file
|
@ -0,0 +1,188 @@
|
|||
import logging
|
||||
import re
|
||||
from typing import Any, Dict, Generic, List, Optional, Set, Type, TypeVar, cast
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
from openapi_pydantic.compat import (
|
||||
DEFS_KEY,
|
||||
PYDANTIC_V2,
|
||||
JsonSchemaMode,
|
||||
models_json_schema,
|
||||
v1_schema,
|
||||
)
|
||||
|
||||
from . import Components, OpenAPI, Reference, Schema, schema_validate
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
PydanticType = TypeVar("PydanticType", bound=BaseModel)
|
||||
ref_prefix = "#/components/schemas/"
|
||||
ref_template = "#/components/schemas/{model}"
|
||||
|
||||
|
||||
class PydanticSchema(Schema, Generic[PydanticType]):
|
||||
"""Special `Schema` class to indicate a reference from pydantic class"""
|
||||
|
||||
schema_class: Type[PydanticType]
|
||||
"""the class that is used for generate the schema"""
|
||||
|
||||
|
||||
def get_mode(
|
||||
cls: Type[BaseModel], default: JsonSchemaMode = "validation"
|
||||
) -> JsonSchemaMode:
|
||||
"""Get the JSON schema mode for a model class.
|
||||
|
||||
The mode can be either "validation" or "serialization". In validation mode,
|
||||
computed fields are dropped and optional fields remain optional. In
|
||||
serialization mode, computed and optional fields are required.
|
||||
"""
|
||||
if not hasattr(cls, "model_config"):
|
||||
return default
|
||||
mode = cls.model_config.get("json_schema_mode", default)
|
||||
if mode not in ("validation", "serialization"):
|
||||
raise ValueError(f"invalid json_schema_mode: {mode}")
|
||||
return cast(JsonSchemaMode, mode)
|
||||
|
||||
|
||||
def construct_open_api_with_schema_class(
|
||||
open_api: OpenAPI,
|
||||
schema_classes: Optional[List[Type[BaseModel]]] = None,
|
||||
scan_for_pydantic_schema_reference: bool = True,
|
||||
by_alias: bool = True,
|
||||
) -> OpenAPI:
|
||||
"""
|
||||
Construct a new OpenAPI object, utilising pydantic classes to produce JSON schemas.
|
||||
|
||||
:param open_api: the base `OpenAPI` object
|
||||
:param schema_classes: Pydantic classes that their schema will be used
|
||||
"#/components/schemas" values
|
||||
:param scan_for_pydantic_schema_reference: flag to indicate if scanning for
|
||||
`PydanticSchemaReference` class
|
||||
is needed for "#/components/schemas"
|
||||
value updates
|
||||
:param by_alias: construct schema by alias (default is True)
|
||||
:return: new OpenAPI object with "#/components/schemas" values updated.
|
||||
If there is no update in "#/components/schemas" values, the original
|
||||
`open_api` will be returned.
|
||||
"""
|
||||
copy_func = getattr(open_api, "model_copy" if PYDANTIC_V2 else "copy")
|
||||
new_open_api: OpenAPI = copy_func(deep=True)
|
||||
|
||||
if scan_for_pydantic_schema_reference:
|
||||
extracted_schema_classes = _handle_pydantic_schema(new_open_api)
|
||||
if schema_classes:
|
||||
schema_classes = list({*schema_classes, *extracted_schema_classes})
|
||||
else:
|
||||
schema_classes = extracted_schema_classes
|
||||
|
||||
if not schema_classes:
|
||||
return open_api
|
||||
|
||||
schema_classes.sort(key=lambda x: x.__name__)
|
||||
logger.debug("schema_classes: %s", schema_classes)
|
||||
|
||||
# update new_open_api with new #/components/schemas
|
||||
if PYDANTIC_V2:
|
||||
_key_map, schema_definitions = models_json_schema(
|
||||
[(c, get_mode(c)) for c in schema_classes],
|
||||
by_alias=by_alias,
|
||||
ref_template=ref_template,
|
||||
)
|
||||
else:
|
||||
schema_definitions = v1_schema(
|
||||
schema_classes, by_alias=by_alias, ref_prefix=ref_prefix
|
||||
)
|
||||
|
||||
if not new_open_api.components:
|
||||
new_open_api.components = Components()
|
||||
if new_open_api.components.schemas:
|
||||
for existing_key in new_open_api.components.schemas:
|
||||
if existing_key in schema_definitions[DEFS_KEY]:
|
||||
logger.warning(
|
||||
f'"{existing_key}" already exists in {ref_prefix}. '
|
||||
f'The value of "{ref_prefix}{existing_key}" will be overwritten.'
|
||||
)
|
||||
new_open_api.components.schemas.update(_validate_schemas(schema_definitions))
|
||||
else:
|
||||
new_open_api.components.schemas = _validate_schemas(schema_definitions)
|
||||
return new_open_api
|
||||
|
||||
|
||||
def _validate_schemas(schema_definitions: Dict[str, Any]) -> Dict[str, Schema]:
|
||||
"""Convert JSON Schema definitions to parsed OpenAPI objects"""
|
||||
# Note: if an error occurs in schema_validate(), it may indicate that
|
||||
# the generated JSON schemas are not compatible with the version
|
||||
# of OpenAPI this module depends on.
|
||||
return {
|
||||
key: schema_validate(schema_dict)
|
||||
for key, schema_dict in schema_definitions[DEFS_KEY].items()
|
||||
}
|
||||
|
||||
|
||||
def _handle_pydantic_schema(open_api: OpenAPI) -> List[Type[BaseModel]]:
|
||||
"""
|
||||
This function traverses the `OpenAPI` object and
|
||||
|
||||
1. Replaces the `PydanticSchema` object with `Reference` object, with correct ref
|
||||
value;
|
||||
2. Extracts the involved schema class from `PydanticSchema` object.
|
||||
|
||||
**This function will mutate the input `OpenAPI` object.**
|
||||
|
||||
:param open_api: the `OpenAPI` object to be traversed and mutated
|
||||
:return: a list of schema classes extracted from `PydanticSchema` objects
|
||||
"""
|
||||
|
||||
pydantic_types: Set[Type[BaseModel]] = set()
|
||||
|
||||
def _traverse(obj: Any) -> None:
|
||||
if isinstance(obj, BaseModel):
|
||||
fields = getattr(
|
||||
obj, "model_fields_set" if PYDANTIC_V2 else "__fields_set__"
|
||||
)
|
||||
for field in fields:
|
||||
child_obj = obj.__getattribute__(field)
|
||||
if isinstance(child_obj, PydanticSchema):
|
||||
logger.debug("PydanticSchema found in %s: %s", obj, child_obj)
|
||||
obj.__setattr__(field, _construct_ref_obj(child_obj))
|
||||
pydantic_types.add(child_obj.schema_class)
|
||||
else:
|
||||
_traverse(child_obj)
|
||||
elif isinstance(obj, list):
|
||||
for index, elem in enumerate(obj):
|
||||
if isinstance(elem, PydanticSchema):
|
||||
logger.debug(f"PydanticSchema found in list: {elem}")
|
||||
obj[index] = _construct_ref_obj(elem)
|
||||
pydantic_types.add(elem.schema_class)
|
||||
else:
|
||||
_traverse(elem)
|
||||
elif isinstance(obj, dict):
|
||||
for key, value in obj.items():
|
||||
if isinstance(value, PydanticSchema):
|
||||
logger.debug(f"PydanticSchema found in dict: {value}")
|
||||
obj[key] = _construct_ref_obj(value)
|
||||
pydantic_types.add(value.schema_class)
|
||||
else:
|
||||
_traverse(value)
|
||||
|
||||
_traverse(open_api)
|
||||
return list(pydantic_types)
|
||||
|
||||
|
||||
def _construct_ref_obj(pydantic_schema: PydanticSchema[PydanticType]) -> Reference:
|
||||
"""
|
||||
Construct a reference object from the Pydantic schema name
|
||||
|
||||
characters in the schema name that are invalid/problematic
|
||||
for JSONschema $ref names will get replaced with underscores.
|
||||
Especially needed for Pydantic generic Models with brackets "[]"
|
||||
|
||||
see: https://github.com/pydantic/pydantic/blob/aee6057378ccfec02126bf9c984a9b6d6b411777/pydantic/json_schema.py#L2031
|
||||
"""
|
||||
ref_name = re.sub(
|
||||
r"[^a-zA-Z0-9.\-_]", "_", pydantic_schema.schema_class.__name__
|
||||
).replace(".", "__")
|
||||
ref_obj = Reference(**{"$ref": ref_prefix + ref_name})
|
||||
logger.debug(f"ref_obj={ref_obj}")
|
||||
return ref_obj
|
34
openapi_pydantic/v3/__init__.py
Normal file
34
openapi_pydantic/v3/__init__.py
Normal file
|
@ -0,0 +1,34 @@
|
|||
from .parser import parse_obj as parse_obj
|
||||
from .v3_1 import XML as XML
|
||||
from .v3_1 import Callback as Callback
|
||||
from .v3_1 import Components as Components
|
||||
from .v3_1 import Contact as Contact
|
||||
from .v3_1 import DataType as DataType
|
||||
from .v3_1 import Discriminator as Discriminator
|
||||
from .v3_1 import Encoding as Encoding
|
||||
from .v3_1 import Example as Example
|
||||
from .v3_1 import ExternalDocumentation as ExternalDocumentation
|
||||
from .v3_1 import Header as Header
|
||||
from .v3_1 import Info as Info
|
||||
from .v3_1 import License as License
|
||||
from .v3_1 import Link as Link
|
||||
from .v3_1 import MediaType as MediaType
|
||||
from .v3_1 import OAuthFlow as OAuthFlow
|
||||
from .v3_1 import OAuthFlows as OAuthFlows
|
||||
from .v3_1 import OpenAPI as OpenAPI
|
||||
from .v3_1 import Operation as Operation
|
||||
from .v3_1 import Parameter as Parameter
|
||||
from .v3_1 import ParameterLocation as ParameterLocation
|
||||
from .v3_1 import PathItem as PathItem
|
||||
from .v3_1 import Paths as Paths
|
||||
from .v3_1 import Reference as Reference
|
||||
from .v3_1 import RequestBody as RequestBody
|
||||
from .v3_1 import Response as Response
|
||||
from .v3_1 import Responses as Responses
|
||||
from .v3_1 import Schema as Schema
|
||||
from .v3_1 import SecurityRequirement as SecurityRequirement
|
||||
from .v3_1 import SecurityScheme as SecurityScheme
|
||||
from .v3_1 import Server as Server
|
||||
from .v3_1 import ServerVariable as ServerVariable
|
||||
from .v3_1 import Tag as Tag
|
||||
from .v3_1 import schema_validate as schema_validate
|
33
openapi_pydantic/v3/parser.py
Normal file
33
openapi_pydantic/v3/parser.py
Normal file
|
@ -0,0 +1,33 @@
|
|||
from typing import TYPE_CHECKING, Any, Union
|
||||
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
from openapi_pydantic.compat import PYDANTIC_V2
|
||||
|
||||
from .v3_0 import OpenAPI as OpenAPIv3_0
|
||||
from .v3_1 import OpenAPI as OpenAPIv3_1
|
||||
|
||||
OpenAPIv3 = Union[OpenAPIv3_1, OpenAPIv3_0]
|
||||
|
||||
if TYPE_CHECKING:
|
||||
|
||||
def parse_obj(data: Any) -> OpenAPIv3:
|
||||
"""Parse a raw object into an OpenAPI model with version inference."""
|
||||
...
|
||||
|
||||
elif PYDANTIC_V2:
|
||||
from pydantic import RootModel
|
||||
|
||||
class _OpenAPI(RootModel):
|
||||
root: OpenAPIv3 = Field(discriminator="openapi")
|
||||
|
||||
def parse_obj(data: Any) -> OpenAPIv3:
|
||||
return _OpenAPI.model_validate(data).root
|
||||
|
||||
else:
|
||||
|
||||
class _OpenAPI(BaseModel):
|
||||
__root__: OpenAPIv3 = Field(discriminator="openapi")
|
||||
|
||||
def parse_obj(data: Any) -> OpenAPIv3:
|
||||
return _OpenAPI.parse_obj(data).__root__
|
39
openapi_pydantic/v3/v3_0/README.md
Normal file
39
openapi_pydantic/v3/v3_0/README.md
Normal file
|
@ -0,0 +1,39 @@
|
|||
# OpenAPI v3.0 schema classes
|
||||
|
||||
## Alias
|
||||
|
||||
Due to the reserved words in python and pydantic,
|
||||
the following fields are used with [alias](https://pydantic-docs.helpmanual.io/usage/schema/#field-customisation) feature provided by pydantic:
|
||||
|
||||
| Class | Field name in the class | Alias (as in OpenAPI spec) |
|
||||
| ----- | ----------------------- | -------------------------- |
|
||||
| Header[*](#header_param_in) | param_in | in |
|
||||
| MediaType | media_type_schema | schema |
|
||||
| Parameter | param_in | in |
|
||||
| Parameter | param_schema | schema |
|
||||
| PathItem | ref | $ref |
|
||||
| Reference | ref | $ref |
|
||||
| SecurityScheme | security_scheme_in | in |
|
||||
| Schema | schema_format | format |
|
||||
| Schema | schema_not | not |
|
||||
|
||||
> <a name="header_param_in"></a>The "in" field in Header object is actually a constant (`{"in": "header"}`).
|
||||
|
||||
> For convenience of object creation, the classes mentioned in above
|
||||
> have configured `allow_population_by_field_name=True` (Pydantic V1) or `populate_by_name=True` (Pydantic V2).
|
||||
>
|
||||
> Reference: [Pydantic's Model Config](https://pydantic-docs.helpmanual.io/usage/model_config/)
|
||||
|
||||
## Non-pydantic schema types
|
||||
|
||||
Due to the constriants of python typing structure (not able to handle dynamic field names),
|
||||
the following schema classes are actually just a typing of `Dict`:
|
||||
|
||||
| Schema Type | Implementation |
|
||||
| ----------- | -------------- |
|
||||
| Callback | `Callback = Dict[str, PathItem]` |
|
||||
| Paths | `Paths = Dict[str, PathItem]` |
|
||||
| Responses | `Responses = Dict[str, Union[Response, Reference]]` |
|
||||
| SecurityRequirement | `SecurityRequirement = Dict[str, List[str]]` |
|
||||
|
||||
On creating such schema instances, please use python's `dict` type instead to instantiate.
|
59
openapi_pydantic/v3/v3_0/__init__.py
Normal file
59
openapi_pydantic/v3/v3_0/__init__.py
Normal file
|
@ -0,0 +1,59 @@
|
|||
"""
|
||||
OpenAPI v3.0 schema types, created according to the specification:
|
||||
https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.4.md
|
||||
|
||||
The type orders are according to the contents of the specification:
|
||||
https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.4.md#table-of-contents
|
||||
"""
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from openapi_pydantic.compat import PYDANTIC_V2
|
||||
|
||||
from .callback import Callback as Callback
|
||||
from .components import Components as Components
|
||||
from .contact import Contact as Contact
|
||||
from .datatype import DataType as DataType
|
||||
from .discriminator import Discriminator as Discriminator
|
||||
from .encoding import Encoding as Encoding
|
||||
from .example import Example as Example
|
||||
from .external_documentation import ExternalDocumentation as ExternalDocumentation
|
||||
from .header import Header as Header
|
||||
from .info import Info as Info
|
||||
from .license import License as License
|
||||
from .link import Link as Link
|
||||
from .media_type import MediaType as MediaType
|
||||
from .oauth_flow import OAuthFlow as OAuthFlow
|
||||
from .oauth_flows import OAuthFlows as OAuthFlows
|
||||
from .open_api import OpenAPI as OpenAPI
|
||||
from .operation import Operation as Operation
|
||||
from .parameter import Parameter as Parameter
|
||||
from .parameter import ParameterLocation as ParameterLocation
|
||||
from .path_item import PathItem as PathItem
|
||||
from .paths import Paths as Paths
|
||||
from .reference import Reference as Reference
|
||||
from .request_body import RequestBody as RequestBody
|
||||
from .response import Response as Response
|
||||
from .responses import Responses as Responses
|
||||
from .schema import Schema as Schema
|
||||
from .schema import schema_validate as schema_validate
|
||||
from .security_requirement import SecurityRequirement as SecurityRequirement
|
||||
from .security_scheme import SecurityScheme as SecurityScheme
|
||||
from .server import Server as Server
|
||||
from .server_variable import ServerVariable as ServerVariable
|
||||
from .tag import Tag as Tag
|
||||
from .xml import XML as XML
|
||||
|
||||
if TYPE_CHECKING:
|
||||
pass
|
||||
elif PYDANTIC_V2:
|
||||
# resolve forward references
|
||||
Encoding.model_rebuild()
|
||||
OpenAPI.model_rebuild()
|
||||
Components.model_rebuild()
|
||||
Operation.model_rebuild()
|
||||
else:
|
||||
# resolve forward references
|
||||
Encoding.update_forward_refs(Header=Header)
|
||||
Schema.update_forward_refs()
|
||||
Operation.update_forward_refs(PathItem=PathItem)
|
24
openapi_pydantic/v3/v3_0/callback.py
Normal file
24
openapi_pydantic/v3/v3_0/callback.py
Normal file
|
@ -0,0 +1,24 @@
|
|||
from typing import TYPE_CHECKING, Dict
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from .path_item import PathItem
|
||||
|
||||
|
||||
Callback = Dict[str, "PathItem"]
|
||||
"""
|
||||
A map of possible out-of band callbacks related to the parent operation.
|
||||
Each value in the map is a [Path Item Object](#pathItemObject)
|
||||
that describes a set of requests that may be initiated by the API provider and the
|
||||
expected responses. The key value used to identify the path item object is an
|
||||
expression, evaluated at runtime, that identifies a URL to use for the callback
|
||||
operation.
|
||||
"""
|
||||
|
||||
"""Patterned Fields"""
|
||||
|
||||
# {expression}: 'PathItem' = ...
|
||||
"""
|
||||
A Path Item Object used to define a callback request and expected responses.
|
||||
|
||||
A [complete example](../examples/v3.0/callback-example.yaml) is available.
|
||||
"""
|
138
openapi_pydantic/v3/v3_0/components.py
Normal file
138
openapi_pydantic/v3/v3_0/components.py
Normal file
|
@ -0,0 +1,138 @@
|
|||
from typing import Dict, Optional, Union
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
from openapi_pydantic.compat import PYDANTIC_V2, ConfigDict, Extra
|
||||
|
||||
from .callback import Callback
|
||||
from .example import Example
|
||||
from .header import Header
|
||||
from .link import Link
|
||||
from .parameter import Parameter
|
||||
from .reference import Reference
|
||||
from .request_body import RequestBody
|
||||
from .response import Response
|
||||
from .schema import Schema
|
||||
from .security_scheme import SecurityScheme
|
||||
|
||||
_examples = [
|
||||
{
|
||||
"schemas": {
|
||||
"GeneralError": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"code": {"type": "integer", "format": "int32"},
|
||||
"message": {"type": "string"},
|
||||
},
|
||||
},
|
||||
"Category": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {"type": "integer", "format": "int64"},
|
||||
"name": {"type": "string"},
|
||||
},
|
||||
},
|
||||
"Tag": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {"type": "integer", "format": "int64"},
|
||||
"name": {"type": "string"},
|
||||
},
|
||||
},
|
||||
},
|
||||
"parameters": {
|
||||
"skipParam": {
|
||||
"name": "skip",
|
||||
"in": "query",
|
||||
"description": "number of items to skip",
|
||||
"required": True,
|
||||
"schema": {"type": "integer", "format": "int32"},
|
||||
},
|
||||
"limitParam": {
|
||||
"name": "limit",
|
||||
"in": "query",
|
||||
"description": "max records to return",
|
||||
"required": True,
|
||||
"schema": {"type": "integer", "format": "int32"},
|
||||
},
|
||||
},
|
||||
"responses": {
|
||||
"NotFound": {"description": "Entity not found."},
|
||||
"IllegalInput": {"description": "Illegal input for operation."},
|
||||
"GeneralError": {
|
||||
"description": "General Error",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {"$ref": "#/components/schemas/GeneralError"}
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
"securitySchemes": {
|
||||
"api_key": {
|
||||
"type": "apiKey",
|
||||
"name": "api_key",
|
||||
"in": "header",
|
||||
},
|
||||
"petstore_auth": {
|
||||
"type": "oauth2",
|
||||
"flows": {
|
||||
"implicit": {
|
||||
"authorizationUrl": "http://example.org/api/oauth/dialog",
|
||||
"scopes": {
|
||||
"write:pets": "modify pets in your account",
|
||||
"read:pets": "read your pets",
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
class Components(BaseModel):
|
||||
"""
|
||||
Holds a set of reusable objects for different aspects of the OAS.
|
||||
All objects defined within the components object will have no effect on the API
|
||||
unless they are explicitly referenced from properties outside the components object.
|
||||
"""
|
||||
|
||||
schemas: Optional[Dict[str, Union[Reference, Schema]]] = None
|
||||
"""An object to hold reusable [Schema Objects](#schemaObject)."""
|
||||
|
||||
responses: Optional[Dict[str, Union[Response, Reference]]] = None
|
||||
"""An object to hold reusable [Response Objects](#responseObject)."""
|
||||
|
||||
parameters: Optional[Dict[str, Union[Parameter, Reference]]] = None
|
||||
"""An object to hold reusable [Parameter Objects](#parameterObject)."""
|
||||
|
||||
examples: Optional[Dict[str, Union[Example, Reference]]] = None
|
||||
"""An object to hold reusable [Example Objects](#exampleObject)."""
|
||||
|
||||
requestBodies: Optional[Dict[str, Union[RequestBody, Reference]]] = None
|
||||
"""An object to hold reusable [Request Body Objects](#requestBodyObject)."""
|
||||
|
||||
headers: Optional[Dict[str, Union[Header, Reference]]] = None
|
||||
"""An object to hold reusable [Header Objects](#headerObject)."""
|
||||
|
||||
securitySchemes: Optional[Dict[str, Union[SecurityScheme, Reference]]] = None
|
||||
"""An object to hold reusable [Security Scheme Objects](#securitySchemeObject)."""
|
||||
|
||||
links: Optional[Dict[str, Union[Link, Reference]]] = None
|
||||
"""An object to hold reusable [Link Objects](#linkObject)."""
|
||||
|
||||
callbacks: Optional[Dict[str, Union[Callback, Reference]]] = None
|
||||
"""An object to hold reusable [Callback Objects](#callbackObject)."""
|
||||
|
||||
if PYDANTIC_V2:
|
||||
model_config = ConfigDict(
|
||||
extra="allow",
|
||||
json_schema_extra={"examples": _examples},
|
||||
)
|
||||
|
||||
else:
|
||||
|
||||
class Config:
|
||||
extra = Extra.allow
|
||||
schema_extra = {"examples": _examples}
|
48
openapi_pydantic/v3/v3_0/contact.py
Normal file
48
openapi_pydantic/v3/v3_0/contact.py
Normal file
|
@ -0,0 +1,48 @@
|
|||
from typing import Optional
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
from openapi_pydantic.compat import PYDANTIC_V2, ConfigDict, Extra
|
||||
|
||||
_examples = [
|
||||
{
|
||||
"name": "API Support",
|
||||
"url": "http://www.example.com/support",
|
||||
"email": "support@example.com",
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
class Contact(BaseModel):
|
||||
"""
|
||||
Contact information for the exposed API.
|
||||
"""
|
||||
|
||||
name: Optional[str] = None
|
||||
"""
|
||||
The identifying name of the contact person/organization.
|
||||
"""
|
||||
|
||||
url: Optional[str] = None
|
||||
"""
|
||||
The URL pointing to the contact information.
|
||||
MUST be in the format of a URL.
|
||||
"""
|
||||
|
||||
email: Optional[str] = None
|
||||
"""
|
||||
The email address of the contact person/organization.
|
||||
MUST be in the format of an email address.
|
||||
"""
|
||||
|
||||
if PYDANTIC_V2:
|
||||
model_config = ConfigDict(
|
||||
extra="allow",
|
||||
json_schema_extra={"examples": _examples},
|
||||
)
|
||||
|
||||
else:
|
||||
|
||||
class Config:
|
||||
extra = Extra.allow
|
||||
schema_extra = {"examples": _examples}
|
15
openapi_pydantic/v3/v3_0/datatype.py
Normal file
15
openapi_pydantic/v3/v3_0/datatype.py
Normal file
|
@ -0,0 +1,15 @@
|
|||
import enum
|
||||
|
||||
|
||||
class DataType(str, enum.Enum):
|
||||
"""Data type of an object.
|
||||
|
||||
Note: OpenAPI 3.0.x does not support null as a data type.
|
||||
"""
|
||||
|
||||
STRING = "string"
|
||||
NUMBER = "number"
|
||||
INTEGER = "integer"
|
||||
BOOLEAN = "boolean"
|
||||
ARRAY = "array"
|
||||
OBJECT = "object"
|
52
openapi_pydantic/v3/v3_0/discriminator.py
Normal file
52
openapi_pydantic/v3/v3_0/discriminator.py
Normal file
|
@ -0,0 +1,52 @@
|
|||
from typing import Dict, Optional
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
from openapi_pydantic.compat import PYDANTIC_V2, ConfigDict, Extra
|
||||
|
||||
_examples = [
|
||||
{
|
||||
"propertyName": "petType",
|
||||
"mapping": {
|
||||
"dog": "#/components/schemas/Dog",
|
||||
"monster": "https://gigantic-server.com/schemas/Monster/schema.json",
|
||||
},
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
class Discriminator(BaseModel):
|
||||
"""
|
||||
When request bodies or response payloads may be one of a number of different
|
||||
schemas, a `discriminator` object can be used to aid in serialization,
|
||||
deserialization, and validation.
|
||||
|
||||
The discriminator is a specific object in a schema which is used to inform the
|
||||
consumer of the specification of an alternative schema based on the value
|
||||
associated with it.
|
||||
|
||||
When using the discriminator, _inline_ schemas will not be considered.
|
||||
"""
|
||||
|
||||
propertyName: str
|
||||
"""
|
||||
**REQUIRED**. The name of the property in the payload that will hold the
|
||||
discriminator value.
|
||||
"""
|
||||
|
||||
mapping: Optional[Dict[str, str]] = None
|
||||
"""
|
||||
An object to hold mappings between payload values and schema names or references.
|
||||
"""
|
||||
|
||||
if PYDANTIC_V2:
|
||||
model_config = ConfigDict(
|
||||
extra="allow",
|
||||
json_schema_extra={"examples": _examples},
|
||||
)
|
||||
|
||||
else:
|
||||
|
||||
class Config:
|
||||
extra = Extra.allow
|
||||
schema_extra = {"examples": _examples}
|
94
openapi_pydantic/v3/v3_0/encoding.py
Normal file
94
openapi_pydantic/v3/v3_0/encoding.py
Normal file
|
@ -0,0 +1,94 @@
|
|||
from typing import TYPE_CHECKING, Dict, Optional, Union
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
from openapi_pydantic.compat import PYDANTIC_V2, ConfigDict, Extra
|
||||
|
||||
from .reference import Reference
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from .header import Header
|
||||
|
||||
_examples = [
|
||||
{
|
||||
"contentType": "image/png, image/jpeg",
|
||||
"headers": {
|
||||
"X-Rate-Limit-Limit": {
|
||||
"description": "The number of allowed requests in the "
|
||||
"current period",
|
||||
"schema": {"type": "integer"},
|
||||
}
|
||||
},
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
class Encoding(BaseModel):
|
||||
"""A single encoding definition applied to a single schema property."""
|
||||
|
||||
contentType: Optional[str] = None
|
||||
"""
|
||||
The Content-Type for encoding a specific property.
|
||||
Default value depends on the property type:
|
||||
|
||||
- for `string` with `format` being `binary` – `application/octet-stream`;
|
||||
- for other primitive types – `text/plain`;
|
||||
- for `object` - `application/json`;
|
||||
- for `array` – the default is defined based on the inner type.
|
||||
|
||||
The value can be a specific media type (e.g. `application/json`), a wildcard media
|
||||
type (e.g. `image/*`), or a comma-separated list of the two types.
|
||||
"""
|
||||
|
||||
headers: Optional[Dict[str, Union["Header", Reference]]] = None
|
||||
"""
|
||||
A map allowing additional information to be provided as headers, for example
|
||||
`Content-Disposition`.
|
||||
|
||||
`Content-Type` is described separately and SHALL be ignored in this section.
|
||||
This property SHALL be ignored if the request body media type is not a `multipart`.
|
||||
"""
|
||||
|
||||
style: Optional[str] = None
|
||||
"""
|
||||
Describes how a specific property value will be serialized depending on its type.
|
||||
|
||||
See [Parameter Object](#parameterObject) for details on the
|
||||
[`style`](#parameterStyle) property. The behavior follows the same values as
|
||||
`query` parameters, including default values. This property SHALL be ignored if
|
||||
the request body media type is not `application/x-www-form-urlencoded`.
|
||||
"""
|
||||
|
||||
explode: Optional[bool] = None
|
||||
"""
|
||||
When this is true, property values of type `array` or `object` generate separate
|
||||
parameters for each value of the array, or key-value-pair of the map.
|
||||
|
||||
For other types of properties this property has no effect.
|
||||
When [`style`](#encodingStyle) is `form`, the default value is `true`.
|
||||
For all other styles, the default value is `false`.
|
||||
This property SHALL be ignored if the request body media type is not
|
||||
`application/x-www-form-urlencoded`.
|
||||
"""
|
||||
|
||||
allowReserved: bool = False
|
||||
"""
|
||||
Determines whether the parameter value SHOULD allow reserved characters,
|
||||
as defined by [RFC3986](https://tools.ietf.org/html/rfc3986#section-2.2)
|
||||
`:/?#[]@!$&'()*+,;=` to be included without percent-encoding.
|
||||
The default value is `false`.
|
||||
This property SHALL be ignored if the request body media type is not
|
||||
`application/x-www-form-urlencoded`.
|
||||
"""
|
||||
|
||||
if PYDANTIC_V2:
|
||||
model_config = ConfigDict(
|
||||
extra="allow",
|
||||
json_schema_extra={"examples": _examples},
|
||||
)
|
||||
|
||||
else:
|
||||
|
||||
class Config:
|
||||
extra = Extra.allow
|
||||
schema_extra = {"examples": _examples}
|
60
openapi_pydantic/v3/v3_0/example.py
Normal file
60
openapi_pydantic/v3/v3_0/example.py
Normal file
|
@ -0,0 +1,60 @@
|
|||
from typing import Any, Optional
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
from openapi_pydantic.compat import PYDANTIC_V2, ConfigDict, Extra
|
||||
|
||||
_examples = [
|
||||
{"summary": "A foo example", "value": {"foo": "bar"}},
|
||||
{
|
||||
"summary": "This is an example in XML",
|
||||
"externalValue": "http://example.org/examples/address-example.xml",
|
||||
},
|
||||
{
|
||||
"summary": "This is a text example",
|
||||
"externalValue": "http://foo.bar/examples/address-example.txt",
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
class Example(BaseModel):
|
||||
summary: Optional[str] = None
|
||||
"""
|
||||
Short description for the example.
|
||||
"""
|
||||
|
||||
description: Optional[str] = None
|
||||
"""
|
||||
Long description for the example.
|
||||
[CommonMark syntax](https://spec.commonmark.org/) MAY be used for rich text
|
||||
representation.
|
||||
"""
|
||||
|
||||
value: Optional[Any] = None
|
||||
"""
|
||||
Embedded literal example.
|
||||
The `value` field and `externalValue` field are mutually exclusive.
|
||||
To represent examples of media types that cannot naturally represented in JSON or
|
||||
YAML, use a string value to contain the example, escaping where necessary.
|
||||
"""
|
||||
|
||||
externalValue: Optional[str] = None
|
||||
"""
|
||||
A URL that points to the literal example.
|
||||
This provides the capability to reference examples that cannot easily be included
|
||||
in JSON or YAML documents.
|
||||
|
||||
The `value` field and `externalValue` field are mutually exclusive.
|
||||
"""
|
||||
|
||||
if PYDANTIC_V2:
|
||||
model_config = ConfigDict(
|
||||
extra="allow",
|
||||
json_schema_extra={"examples": _examples},
|
||||
)
|
||||
|
||||
else:
|
||||
|
||||
class Config:
|
||||
extra = Extra.allow
|
||||
schema_extra = {"examples": _examples}
|
36
openapi_pydantic/v3/v3_0/external_documentation.py
Normal file
36
openapi_pydantic/v3/v3_0/external_documentation.py
Normal file
|
@ -0,0 +1,36 @@
|
|||
from typing import Optional
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
from openapi_pydantic.compat import PYDANTIC_V2, ConfigDict, Extra
|
||||
|
||||
_examples = [{"description": "Find more info here", "url": "https://example.com"}]
|
||||
|
||||
|
||||
class ExternalDocumentation(BaseModel):
|
||||
"""Allows referencing an external resource for extended documentation."""
|
||||
|
||||
description: Optional[str] = None
|
||||
"""
|
||||
A short description of the target documentation.
|
||||
[CommonMark syntax](https://spec.commonmark.org/) MAY be used for rich text
|
||||
representation.
|
||||
"""
|
||||
|
||||
url: str
|
||||
"""
|
||||
**REQUIRED**. The URL for the target documentation.
|
||||
Value MUST be in the format of a URL.
|
||||
"""
|
||||
|
||||
if PYDANTIC_V2:
|
||||
model_config = ConfigDict(
|
||||
extra="allow",
|
||||
json_schema_extra={"examples": _examples},
|
||||
)
|
||||
|
||||
else:
|
||||
|
||||
class Config:
|
||||
extra = Extra.allow
|
||||
schema_extra = {"examples": _examples}
|
37
openapi_pydantic/v3/v3_0/header.py
Normal file
37
openapi_pydantic/v3/v3_0/header.py
Normal file
|
@ -0,0 +1,37 @@
|
|||
from openapi_pydantic.compat import PYDANTIC_V2, ConfigDict, Extra
|
||||
|
||||
from .parameter import ParameterBase
|
||||
|
||||
_examples = [
|
||||
{
|
||||
"description": "The number of allowed requests in the current period",
|
||||
"schema": {"type": "integer"},
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
class Header(ParameterBase):
|
||||
"""
|
||||
The Header Object follows the structure of the
|
||||
[Parameter Object](#parameterObject) with the following changes:
|
||||
|
||||
1. `name` MUST NOT be specified, it is given in the corresponding
|
||||
`headers` map.
|
||||
2. `in` MUST NOT be specified, it is implicitly in `header`.
|
||||
3. All traits that are affected by the location MUST be applicable
|
||||
to a location of `header` (for example, [`style`](#parameterStyle)).
|
||||
"""
|
||||
|
||||
if PYDANTIC_V2:
|
||||
model_config = ConfigDict(
|
||||
extra="allow",
|
||||
populate_by_name=True,
|
||||
json_schema_extra={"examples": _examples},
|
||||
)
|
||||
|
||||
else:
|
||||
|
||||
class Config:
|
||||
extra = Extra.allow
|
||||
allow_population_by_field_name = True
|
||||
schema_extra = {"examples": _examples}
|
81
openapi_pydantic/v3/v3_0/info.py
Normal file
81
openapi_pydantic/v3/v3_0/info.py
Normal file
|
@ -0,0 +1,81 @@
|
|||
from typing import Optional
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
from openapi_pydantic.compat import PYDANTIC_V2, ConfigDict, Extra
|
||||
|
||||
from .contact import Contact
|
||||
from .license import License
|
||||
|
||||
_examples = [
|
||||
{
|
||||
"title": "Sample Pet Store App",
|
||||
"description": "This is a sample server for a pet store.",
|
||||
"termsOfService": "http://example.com/terms/",
|
||||
"contact": {
|
||||
"name": "API Support",
|
||||
"url": "http://www.example.com/support",
|
||||
"email": "support@example.com",
|
||||
},
|
||||
"license": {
|
||||
"name": "Apache 2.0",
|
||||
"url": "https://www.apache.org/licenses/LICENSE-2.0.html",
|
||||
},
|
||||
"version": "1.0.1",
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
class Info(BaseModel):
|
||||
"""
|
||||
The object provides metadata about the API.
|
||||
The metadata MAY be used by the clients if needed,
|
||||
and MAY be presented in editing or documentation generation tools for convenience.
|
||||
"""
|
||||
|
||||
title: str
|
||||
"""
|
||||
**REQUIRED**. The title of the API.
|
||||
"""
|
||||
|
||||
description: Optional[str] = None
|
||||
"""
|
||||
A short description of the API.
|
||||
[CommonMark syntax](https://spec.commonmark.org/) MAY be used for rich text
|
||||
representation.
|
||||
"""
|
||||
|
||||
termsOfService: Optional[str] = None
|
||||
"""
|
||||
A URL to the Terms of Service for the API.
|
||||
MUST be in the format of a URL.
|
||||
"""
|
||||
|
||||
contact: Optional[Contact] = None
|
||||
"""
|
||||
The contact information for the exposed API.
|
||||
"""
|
||||
|
||||
license: Optional[License] = None
|
||||
"""
|
||||
The license information for the exposed API.
|
||||
"""
|
||||
|
||||
version: str
|
||||
"""
|
||||
**REQUIRED**. The version of the OpenAPI document
|
||||
(which is distinct from the [OpenAPI Specification version](#oasVersion) or the API
|
||||
implementation version).
|
||||
"""
|
||||
|
||||
if PYDANTIC_V2:
|
||||
model_config = ConfigDict(
|
||||
extra="allow",
|
||||
json_schema_extra={"examples": _examples},
|
||||
)
|
||||
|
||||
else:
|
||||
|
||||
class Config:
|
||||
extra = Extra.allow
|
||||
schema_extra = {"examples": _examples}
|
41
openapi_pydantic/v3/v3_0/license.py
Normal file
41
openapi_pydantic/v3/v3_0/license.py
Normal file
|
@ -0,0 +1,41 @@
|
|||
from typing import Optional
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
from openapi_pydantic.compat import PYDANTIC_V2, ConfigDict, Extra
|
||||
|
||||
_examples = [
|
||||
{
|
||||
"name": "Apache 2.0",
|
||||
"url": "https://www.apache.org/licenses/LICENSE-2.0.html",
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
class License(BaseModel):
|
||||
"""
|
||||
License information for the exposed API.
|
||||
"""
|
||||
|
||||
name: str
|
||||
"""
|
||||
**REQUIRED**. The license name used for the API.
|
||||
"""
|
||||
|
||||
url: Optional[str] = None
|
||||
"""
|
||||
A URL to the license used for the API.
|
||||
MUST be in the format of a URL.
|
||||
"""
|
||||
|
||||
if PYDANTIC_V2:
|
||||
model_config = ConfigDict(
|
||||
extra="allow",
|
||||
json_schema_extra={"examples": _examples},
|
||||
)
|
||||
|
||||
else:
|
||||
|
||||
class Config:
|
||||
extra = Extra.allow
|
||||
schema_extra = {"examples": _examples}
|
94
openapi_pydantic/v3/v3_0/link.py
Normal file
94
openapi_pydantic/v3/v3_0/link.py
Normal file
|
@ -0,0 +1,94 @@
|
|||
from typing import Any, Dict, Optional
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
from openapi_pydantic.compat import PYDANTIC_V2, ConfigDict, Extra
|
||||
|
||||
from .server import Server
|
||||
|
||||
_examples = [
|
||||
{
|
||||
"operationId": "getUserAddressByUUID",
|
||||
"parameters": {"userUuid": "$response.body#/uuid"},
|
||||
},
|
||||
{
|
||||
"operationRef": "#/paths/~12.0~1repositories~1{username}/get",
|
||||
"parameters": {"username": "$response.body#/username"},
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
class Link(BaseModel):
|
||||
"""
|
||||
The `Link object` represents a possible design-time link for a response.
|
||||
The presence of a link does not guarantee the caller's ability to successfully
|
||||
invoke it, rather it provides a known relationship and traversal mechanism between
|
||||
responses and other operations.
|
||||
|
||||
Unlike _dynamic_ links (i.e. links provided **in** the response payload),
|
||||
the OAS linking mechanism does not require link information in the runtime response.
|
||||
|
||||
For computing links, and providing instructions to execute them,
|
||||
a [runtime expression](#runtimeExpression) is used for accessing values in an
|
||||
operation and using them as parameters while invoking the linked operation.
|
||||
"""
|
||||
|
||||
operationRef: Optional[str] = None
|
||||
"""
|
||||
A relative or absolute URI reference to an OAS operation.
|
||||
This field is mutually exclusive of the `operationId` field,
|
||||
and MUST point to an [Operation Object](#operationObject).
|
||||
Relative `operationRef` values MAY be used to locate an existing
|
||||
[Operation Object](#operationObject) in the OpenAPI definition.
|
||||
"""
|
||||
|
||||
operationId: Optional[str] = None
|
||||
"""
|
||||
The name of an _existing_, resolvable OAS operation, as defined with a unique
|
||||
`operationId`.
|
||||
|
||||
This field is mutually exclusive of the `operationRef` field.
|
||||
"""
|
||||
|
||||
parameters: Optional[Dict[str, Any]] = None
|
||||
"""
|
||||
A map representing parameters to pass to an operation
|
||||
as specified with `operationId` or identified via `operationRef`.
|
||||
The key is the parameter name to be used,
|
||||
whereas the value can be a constant or an expression to be evaluated and passed to
|
||||
the linked operation.
|
||||
|
||||
The parameter name can be qualified using the [parameter location](#parameterIn)
|
||||
`[{in}.]{name}` for operations that use the same parameter name in different
|
||||
locations (e.g. path.id).
|
||||
"""
|
||||
|
||||
requestBody: Optional[Any] = None
|
||||
"""
|
||||
A literal value or [{expression}](#runtimeExpression) to use as a request body when
|
||||
calling the target operation.
|
||||
"""
|
||||
|
||||
description: Optional[str] = None
|
||||
"""
|
||||
A description of the link.
|
||||
[CommonMark syntax](https://spec.commonmark.org/) MAY be used for rich text
|
||||
representation.
|
||||
"""
|
||||
|
||||
server: Optional[Server] = None
|
||||
"""
|
||||
A server object to be used by the target operation.
|
||||
"""
|
||||
|
||||
if PYDANTIC_V2:
|
||||
model_config = ConfigDict(
|
||||
extra="allow",
|
||||
json_schema_extra={"examples": _examples},
|
||||
)
|
||||
|
||||
else:
|
||||
|
||||
class Config:
|
||||
extra = Extra.allow
|
||||
schema_extra = {"examples": _examples}
|
96
openapi_pydantic/v3/v3_0/media_type.py
Normal file
96
openapi_pydantic/v3/v3_0/media_type.py
Normal file
|
@ -0,0 +1,96 @@
|
|||
from typing import Any, Dict, Optional, Union
|
||||
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
from openapi_pydantic.compat import PYDANTIC_V2, ConfigDict, Extra
|
||||
|
||||
from .encoding import Encoding
|
||||
from .example import Example
|
||||
from .reference import Reference
|
||||
from .schema import Schema
|
||||
|
||||
_examples = [
|
||||
{
|
||||
"schema": {"$ref": "#/components/schemas/Pet"},
|
||||
"examples": {
|
||||
"cat": {
|
||||
"summary": "An example of a cat",
|
||||
"value": {
|
||||
"name": "Fluffy",
|
||||
"petType": "Cat",
|
||||
"color": "White",
|
||||
"gender": "male",
|
||||
"breed": "Persian",
|
||||
},
|
||||
},
|
||||
"dog": {
|
||||
"summary": "An example of a dog with a cat's name",
|
||||
"value": {
|
||||
"name": "Puma",
|
||||
"petType": "Dog",
|
||||
"color": "Black",
|
||||
"gender": "Female",
|
||||
"breed": "Mixed",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
class MediaType(BaseModel):
|
||||
"""Each Media Type Object provides schema and examples for the media type
|
||||
identified by its key."""
|
||||
|
||||
media_type_schema: Optional[Union[Reference, Schema]] = Field(
|
||||
default=None, alias="schema"
|
||||
)
|
||||
"""
|
||||
The schema defining the content of the request, response, or parameter.
|
||||
"""
|
||||
|
||||
example: Optional[Any] = None
|
||||
"""
|
||||
Example of the media type.
|
||||
|
||||
The example object SHOULD be in the correct format as specified by the media type.
|
||||
|
||||
The `example` field is mutually exclusive of the `examples` field.
|
||||
|
||||
Furthermore, if referencing a `schema` which contains an example,
|
||||
the `example` value SHALL _override_ the example provided by the schema.
|
||||
"""
|
||||
|
||||
examples: Optional[Dict[str, Union[Example, Reference]]] = None
|
||||
"""
|
||||
Examples of the media type.
|
||||
|
||||
Each example object SHOULD match the media type and specified schema if present.
|
||||
|
||||
The `examples` field is mutually exclusive of the `example` field.
|
||||
|
||||
Furthermore, if referencing a `schema` which contains an example,
|
||||
the `examples` value SHALL _override_ the example provided by the schema.
|
||||
"""
|
||||
|
||||
encoding: Optional[Dict[str, Encoding]] = None
|
||||
"""
|
||||
A map between a property name and its encoding information.
|
||||
The key, being the property name, MUST exist in the schema as a property.
|
||||
The encoding object SHALL only apply to `requestBody` objects
|
||||
when the media type is `multipart` or `application/x-www-form-urlencoded`.
|
||||
"""
|
||||
|
||||
if PYDANTIC_V2:
|
||||
model_config = ConfigDict(
|
||||
extra="allow",
|
||||
populate_by_name=True,
|
||||
json_schema_extra={"examples": _examples},
|
||||
)
|
||||
|
||||
else:
|
||||
|
||||
class Config:
|
||||
extra = Extra.allow
|
||||
allow_population_by_field_name = True
|
||||
schema_extra = {"examples": _examples}
|
76
openapi_pydantic/v3/v3_0/oauth_flow.py
Normal file
76
openapi_pydantic/v3/v3_0/oauth_flow.py
Normal file
|
@ -0,0 +1,76 @@
|
|||
from typing import Dict, Optional
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
from openapi_pydantic.compat import PYDANTIC_V2, ConfigDict, Extra
|
||||
|
||||
_examples = [
|
||||
{
|
||||
"authorizationUrl": "https://example.com/api/oauth/dialog",
|
||||
"scopes": {
|
||||
"write:pets": "modify pets in your account",
|
||||
"read:pets": "read your pets",
|
||||
},
|
||||
},
|
||||
{
|
||||
"authorizationUrl": "https://example.com/api/oauth/dialog",
|
||||
"tokenUrl": "https://example.com/api/oauth/token",
|
||||
"scopes": {
|
||||
"write:pets": "modify pets in your account",
|
||||
"read:pets": "read your pets",
|
||||
},
|
||||
},
|
||||
{
|
||||
"authorizationUrl": "/api/oauth/dialog",
|
||||
"tokenUrl": "/api/oauth/token",
|
||||
"refreshUrl": "/api/oauth/token",
|
||||
"scopes": {
|
||||
"write:pets": "modify pets in your account",
|
||||
"read:pets": "read your pets",
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
class OAuthFlow(BaseModel):
|
||||
"""
|
||||
Configuration details for a supported OAuth Flow
|
||||
"""
|
||||
|
||||
authorizationUrl: Optional[str] = None
|
||||
"""
|
||||
**REQUIRED** for `oauth2 ("implicit", "authorizationCode")`.
|
||||
The authorization URL to be used for this flow.
|
||||
This MUST be in the form of a URL.
|
||||
"""
|
||||
|
||||
tokenUrl: Optional[str] = None
|
||||
"""
|
||||
**REQUIRED** for `oauth2 ("password", "clientCredentials", "authorizationCode")`.
|
||||
The token URL to be used for this flow.
|
||||
This MUST be in the form of a URL.
|
||||
"""
|
||||
|
||||
refreshUrl: Optional[str] = None
|
||||
"""
|
||||
The URL to be used for obtaining refresh tokens. This MUST be in the form of a URL.
|
||||
"""
|
||||
|
||||
scopes: Dict[str, str]
|
||||
"""
|
||||
**REQUIRED**. The available scopes for the OAuth2 security scheme.
|
||||
A map between the scope name and a short description for it.
|
||||
The map MAY be empty.
|
||||
"""
|
||||
|
||||
if PYDANTIC_V2:
|
||||
model_config = ConfigDict(
|
||||
extra="allow",
|
||||
json_schema_extra={"examples": _examples},
|
||||
)
|
||||
|
||||
else:
|
||||
|
||||
class Config:
|
||||
extra = Extra.allow
|
||||
schema_extra = {"examples": _examples}
|
47
openapi_pydantic/v3/v3_0/oauth_flows.py
Normal file
47
openapi_pydantic/v3/v3_0/oauth_flows.py
Normal file
|
@ -0,0 +1,47 @@
|
|||
from typing import Optional
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
from openapi_pydantic.compat import PYDANTIC_V2, ConfigDict, Extra
|
||||
|
||||
from .oauth_flow import OAuthFlow
|
||||
|
||||
|
||||
class OAuthFlows(BaseModel):
|
||||
"""
|
||||
Allows configuration of the supported OAuth Flows.
|
||||
"""
|
||||
|
||||
implicit: Optional[OAuthFlow] = None
|
||||
"""
|
||||
Configuration for the OAuth Implicit flow
|
||||
"""
|
||||
|
||||
password: Optional[OAuthFlow] = None
|
||||
"""
|
||||
Configuration for the OAuth Resource Owner Password flow
|
||||
"""
|
||||
|
||||
clientCredentials: Optional[OAuthFlow] = None
|
||||
"""
|
||||
Configuration for the OAuth Client Credentials flow.
|
||||
|
||||
Previously called `application` in OpenAPI 2.0.
|
||||
"""
|
||||
|
||||
authorizationCode: Optional[OAuthFlow] = None
|
||||
"""
|
||||
Configuration for the OAuth Authorization Code flow.
|
||||
|
||||
Previously called `accessCode` in OpenAPI 2.0.
|
||||
"""
|
||||
|
||||
if PYDANTIC_V2:
|
||||
model_config = ConfigDict(
|
||||
extra="allow",
|
||||
)
|
||||
|
||||
else:
|
||||
|
||||
class Config:
|
||||
extra = Extra.allow
|
84
openapi_pydantic/v3/v3_0/open_api.py
Normal file
84
openapi_pydantic/v3/v3_0/open_api.py
Normal file
|
@ -0,0 +1,84 @@
|
|||
from typing import List, Literal, Optional
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
from openapi_pydantic.compat import PYDANTIC_V2, ConfigDict, Extra
|
||||
|
||||
from .components import Components
|
||||
from .external_documentation import ExternalDocumentation
|
||||
from .info import Info
|
||||
from .paths import Paths
|
||||
from .security_requirement import SecurityRequirement
|
||||
from .server import Server
|
||||
from .tag import Tag
|
||||
|
||||
|
||||
class OpenAPI(BaseModel):
|
||||
"""This is the root document object of the OpenAPI document."""
|
||||
|
||||
openapi: Literal["3.0.4", "3.0.3", "3.0.2", "3.0.1", "3.0.0"] = "3.0.4"
|
||||
"""
|
||||
**REQUIRED**. This string MUST be the [semantic version number](https://semver.org/spec/v2.0.0.html)
|
||||
of the [OpenAPI Specification version](#versions) that the OpenAPI document uses.
|
||||
The `openapi` field SHOULD be used by tooling specifications and clients to
|
||||
interpret the OpenAPI document. This is *not* related to the API
|
||||
[`info.version`](#infoVersion) string.
|
||||
"""
|
||||
|
||||
info: Info
|
||||
"""
|
||||
**REQUIRED**. Provides metadata about the API. The metadata MAY be used by tooling
|
||||
as required.
|
||||
"""
|
||||
|
||||
servers: List[Server] = [Server(url="/")]
|
||||
"""
|
||||
An array of Server Objects, which provide connectivity information to a target
|
||||
server. If the `servers` property is not provided, or is an empty array,
|
||||
the default value would be a [Server Object](#serverObject) with a
|
||||
[url](#serverUrl) value of `/`.
|
||||
"""
|
||||
|
||||
paths: Paths
|
||||
"""
|
||||
**REQUIRED**. The available paths and operations for the API.
|
||||
"""
|
||||
|
||||
components: Optional[Components] = None
|
||||
"""
|
||||
An element to hold various schemas for the specification.
|
||||
"""
|
||||
|
||||
security: Optional[List[SecurityRequirement]] = None
|
||||
"""
|
||||
A declaration of which security mechanisms can be used across the API.
|
||||
The list of values includes alternative security requirement objects that can be
|
||||
used. Only one of the security requirement objects need to be satisfied to
|
||||
authorize a request. Individual operations can override this definition.
|
||||
To make security optional, an empty security requirement (`{}`) can be included in
|
||||
the array.
|
||||
"""
|
||||
|
||||
tags: Optional[List[Tag]] = None
|
||||
"""
|
||||
A list of tags used by the specification with additional metadata.
|
||||
The order of the tags can be used to reflect on their order by the parsing tools.
|
||||
Not all tags that are used by the [Operation Object](#operationObject) must be
|
||||
declared. The tags that are not declared MAY be organized randomly or based on the
|
||||
tools' logic. Each tag name in the list MUST be unique.
|
||||
"""
|
||||
|
||||
externalDocs: Optional[ExternalDocumentation] = None
|
||||
"""
|
||||
Additional external documentation.
|
||||
"""
|
||||
|
||||
if PYDANTIC_V2:
|
||||
model_config = ConfigDict(
|
||||
extra="allow",
|
||||
)
|
||||
|
||||
else:
|
||||
|
||||
class Config:
|
||||
extra = Extra.allow
|
173
openapi_pydantic/v3/v3_0/operation.py
Normal file
173
openapi_pydantic/v3/v3_0/operation.py
Normal file
|
@ -0,0 +1,173 @@
|
|||
from typing import Dict, List, Optional, Union
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
from openapi_pydantic.compat import PYDANTIC_V2, ConfigDict, Extra
|
||||
|
||||
from .callback import Callback
|
||||
from .external_documentation import ExternalDocumentation
|
||||
from .parameter import Parameter
|
||||
from .reference import Reference
|
||||
from .request_body import RequestBody
|
||||
from .responses import Responses
|
||||
from .security_requirement import SecurityRequirement
|
||||
from .server import Server
|
||||
|
||||
_examples = [
|
||||
{
|
||||
"tags": ["pet"],
|
||||
"summary": "Updates a pet in the store with form data",
|
||||
"operationId": "updatePetWithForm",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "petId",
|
||||
"in": "path",
|
||||
"description": "ID of pet that needs to be updated",
|
||||
"required": True,
|
||||
"schema": {"type": "string"},
|
||||
}
|
||||
],
|
||||
"requestBody": {
|
||||
"content": {
|
||||
"application/x-www-form-urlencoded": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {
|
||||
"description": "Updated name of the pet",
|
||||
"type": "string",
|
||||
},
|
||||
"status": {
|
||||
"description": "Updated status of the pet",
|
||||
"type": "string",
|
||||
},
|
||||
},
|
||||
"required": ["status"],
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Pet updated.",
|
||||
"content": {"application/json": {}, "application/xml": {}},
|
||||
},
|
||||
"405": {
|
||||
"description": "Method Not Allowed",
|
||||
"content": {"application/json": {}, "application/xml": {}},
|
||||
},
|
||||
},
|
||||
"security": [{"petstore_auth": ["write:pets", "read:pets"]}],
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
class Operation(BaseModel):
|
||||
"""Describes a single API operation on a path."""
|
||||
|
||||
tags: Optional[List[str]] = None
|
||||
"""
|
||||
A list of tags for API documentation control.
|
||||
Tags can be used for logical grouping of operations by resources or any other
|
||||
qualifier.
|
||||
"""
|
||||
|
||||
summary: Optional[str] = None
|
||||
"""
|
||||
A short summary of what the operation does.
|
||||
"""
|
||||
|
||||
description: Optional[str] = None
|
||||
"""
|
||||
A verbose explanation of the operation behavior.
|
||||
[CommonMark syntax](https://spec.commonmark.org/) MAY be used for rich text
|
||||
representation.
|
||||
"""
|
||||
|
||||
externalDocs: Optional[ExternalDocumentation] = None
|
||||
"""
|
||||
Additional external documentation for this operation.
|
||||
"""
|
||||
|
||||
operationId: Optional[str] = None
|
||||
"""
|
||||
Unique string used to identify the operation.
|
||||
The id MUST be unique among all operations described in the API.
|
||||
The operationId value is **case-sensitive**.
|
||||
Tools and libraries MAY use the operationId to uniquely identify an operation,
|
||||
therefore, it is RECOMMENDED to follow common programming naming conventions.
|
||||
"""
|
||||
|
||||
parameters: Optional[List[Union[Parameter, Reference]]] = None
|
||||
"""
|
||||
A list of parameters that are applicable for this operation.
|
||||
If a parameter is already defined at the [Path Item](#pathItemParameters),
|
||||
the new definition will override it but can never remove it.
|
||||
The list MUST NOT include duplicated parameters.
|
||||
A unique parameter is defined by a combination of a [name](#parameterName) and
|
||||
[location](#parameterIn). The list can use the [Reference Object](#referenceObject)
|
||||
to link to parameters that are defined at the
|
||||
[OpenAPI Object's components/parameters](#componentsParameters).
|
||||
"""
|
||||
|
||||
requestBody: Optional[Union[RequestBody, Reference]] = None
|
||||
"""
|
||||
The request body applicable for this operation.
|
||||
|
||||
The `requestBody` is only supported in HTTP methods where the HTTP 1.1 specification
|
||||
[RFC7231](https://tools.ietf.org/html/rfc7231#section-4.3.1) has explicitly defined
|
||||
semantics for request bodies. In other cases where the HTTP spec is vague,
|
||||
`requestBody` SHALL be ignored by consumers.
|
||||
"""
|
||||
|
||||
responses: Responses
|
||||
"""
|
||||
**REQUIRED**. The list of possible responses as they are returned from executing
|
||||
this operation.
|
||||
"""
|
||||
|
||||
callbacks: Optional[Dict[str, Callback]] = None
|
||||
"""
|
||||
A map of possible out-of band callbacks related to the parent operation.
|
||||
The key is a unique identifier for the Callback Object.
|
||||
Each value in the map is a [Callback Object](#callbackObject)
|
||||
that describes a request that may be initiated by the API provider and the expected
|
||||
responses.
|
||||
"""
|
||||
|
||||
deprecated: bool = False
|
||||
"""
|
||||
Declares this operation to be deprecated.
|
||||
Consumers SHOULD refrain from usage of the declared operation.
|
||||
Default value is `false`.
|
||||
"""
|
||||
|
||||
security: Optional[List[SecurityRequirement]] = None
|
||||
"""
|
||||
A declaration of which security mechanisms can be used for this operation.
|
||||
The list of values includes alternative security requirement objects that can be
|
||||
used. Only one of the security requirement objects need to be satisfied to
|
||||
authorize a request. To make security optional, an empty security requirement
|
||||
(`{}`) can be included in the array. This definition overrides any declared
|
||||
top-level [`security`](#oasSecurity). To remove a top-level security declaration,
|
||||
an empty array can be used.
|
||||
"""
|
||||
|
||||
servers: Optional[List[Server]] = None
|
||||
"""
|
||||
An alternative `server` array to service this operation.
|
||||
If an alternative `server` object is specified at the Path Item Object or Root
|
||||
level, it will be overridden by this value.
|
||||
"""
|
||||
|
||||
if PYDANTIC_V2:
|
||||
model_config = ConfigDict(
|
||||
extra="allow",
|
||||
json_schema_extra={"examples": _examples},
|
||||
)
|
||||
|
||||
else:
|
||||
|
||||
class Config:
|
||||
extra = Extra.allow
|
||||
schema_extra = {"examples": _examples}
|
234
openapi_pydantic/v3/v3_0/parameter.py
Normal file
234
openapi_pydantic/v3/v3_0/parameter.py
Normal file
|
@ -0,0 +1,234 @@
|
|||
import enum
|
||||
from typing import Any, Dict, Optional, Union
|
||||
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
from openapi_pydantic.compat import PYDANTIC_V2, ConfigDict, Extra
|
||||
|
||||
from .example import Example
|
||||
from .media_type import MediaType
|
||||
from .reference import Reference
|
||||
from .schema import Schema
|
||||
|
||||
_examples = [
|
||||
{
|
||||
"name": "token",
|
||||
"in": "header",
|
||||
"description": "token to be passed as a header",
|
||||
"required": True,
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {"type": "integer", "format": "int64"},
|
||||
},
|
||||
"style": "simple",
|
||||
},
|
||||
{
|
||||
"name": "username",
|
||||
"in": "path",
|
||||
"description": "username to fetch",
|
||||
"required": True,
|
||||
"schema": {"type": "string"},
|
||||
},
|
||||
{
|
||||
"name": "id",
|
||||
"in": "query",
|
||||
"description": "ID of the object to fetch",
|
||||
"required": False,
|
||||
"schema": {"type": "array", "items": {"type": "string"}},
|
||||
"style": "form",
|
||||
"explode": True,
|
||||
},
|
||||
{
|
||||
"in": "query",
|
||||
"name": "freeForm",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": {"type": "integer"},
|
||||
},
|
||||
"style": "form",
|
||||
},
|
||||
{
|
||||
"in": "query",
|
||||
"name": "coordinates",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"required": ["lat", "long"],
|
||||
"properties": {
|
||||
"lat": {"type": "number"},
|
||||
"long": {"type": "number"},
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
class ParameterLocation(str, enum.Enum):
|
||||
"""The location of a given parameter."""
|
||||
|
||||
QUERY = "query"
|
||||
HEADER = "header"
|
||||
PATH = "path"
|
||||
COOKIE = "cookie"
|
||||
|
||||
|
||||
class ParameterBase(BaseModel):
|
||||
"""
|
||||
Base class for Parameter and Header.
|
||||
|
||||
(Header is like Parameter, but has no `name` or `in` fields.)
|
||||
"""
|
||||
|
||||
description: Optional[str] = None
|
||||
"""
|
||||
A brief description of the parameter.
|
||||
This could contain examples of use.
|
||||
[CommonMark syntax](https://spec.commonmark.org/) MAY be used for rich text
|
||||
representation.
|
||||
"""
|
||||
|
||||
required: bool = False
|
||||
"""
|
||||
Determines whether this parameter is mandatory.
|
||||
If the [parameter location](#parameterIn) is `"path"`, this property is
|
||||
**REQUIRED** and its value MUST be `true`.
|
||||
Otherwise, the property MAY be included and its default value is `false`.
|
||||
"""
|
||||
|
||||
deprecated: bool = False
|
||||
"""
|
||||
Specifies that a parameter is deprecated and SHOULD be transitioned out of usage.
|
||||
Default value is `false`.
|
||||
"""
|
||||
|
||||
style: Optional[str] = None
|
||||
"""
|
||||
Describes how the parameter value will be serialized depending on the type of the
|
||||
parameter value. Default values (based on value of `in`):
|
||||
|
||||
- for `query` - `form`;
|
||||
- for `path` - `simple`;
|
||||
- for `header` - `simple`;
|
||||
- for `cookie` - `form`.
|
||||
"""
|
||||
|
||||
explode: Optional[bool] = None
|
||||
"""
|
||||
When this is true, parameter values of type `array` or `object` generate separate
|
||||
parameters for each value of the array or key-value pair of the map.
|
||||
For other types of parameters this property has no effect.
|
||||
When [`style`](#parameterStyle) is `form`, the default value is `true`.
|
||||
For all other styles, the default value is `false`.
|
||||
"""
|
||||
|
||||
param_schema: Optional[Union[Reference, Schema]] = Field(
|
||||
default=None, alias="schema"
|
||||
)
|
||||
"""
|
||||
The schema defining the type used for the parameter.
|
||||
"""
|
||||
|
||||
example: Optional[Any] = None
|
||||
"""
|
||||
Example of the parameter's potential value.
|
||||
The example SHOULD match the specified schema and encoding properties if present.
|
||||
The `example` field is mutually exclusive of the `examples` field.
|
||||
Furthermore, if referencing a `schema` that contains an example,
|
||||
the `example` value SHALL _override_ the example provided by the schema.
|
||||
To represent examples of media types that cannot naturally be represented in JSON
|
||||
or YAML, a string value can contain the example with escaping where necessary.
|
||||
"""
|
||||
|
||||
examples: Optional[Dict[str, Union[Example, Reference]]] = None
|
||||
"""
|
||||
Examples of the parameter's potential value.
|
||||
Each example SHOULD contain a value in the correct format as specified in the
|
||||
parameter encoding. The `examples` field is mutually exclusive of the `example`
|
||||
field. Furthermore, if referencing a `schema` that contains an example,
|
||||
the `examples` value SHALL _override_ the example provided by the schema.
|
||||
"""
|
||||
|
||||
"""
|
||||
For more complex scenarios, the [`content`](#parameterContent) property
|
||||
can define the media type and schema of the parameter.
|
||||
A parameter MUST contain either a `schema` property, or a `content` property, but
|
||||
not both. When `example` or `examples` are provided in conjunction with the
|
||||
`schema` object, the example MUST follow the prescribed serialization strategy for
|
||||
the parameter.
|
||||
"""
|
||||
|
||||
content: Optional[Dict[str, MediaType]] = None
|
||||
"""
|
||||
A map containing the representations for the parameter.
|
||||
The key is the media type and the value describes it.
|
||||
The map MUST only contain one entry.
|
||||
"""
|
||||
|
||||
if PYDANTIC_V2:
|
||||
model_config = ConfigDict(
|
||||
extra="allow",
|
||||
populate_by_name=True,
|
||||
json_schema_extra={"examples": _examples},
|
||||
)
|
||||
|
||||
else:
|
||||
|
||||
class Config:
|
||||
extra = Extra.allow
|
||||
allow_population_by_field_name = True
|
||||
schema_extra = {"examples": _examples}
|
||||
|
||||
|
||||
class Parameter(ParameterBase):
|
||||
"""
|
||||
Describes a single operation parameter.
|
||||
|
||||
A unique parameter is defined by a combination of a [name](#parameterName) and
|
||||
[location](#parameterIn).
|
||||
"""
|
||||
|
||||
"""Fixed Fields"""
|
||||
|
||||
name: str
|
||||
"""
|
||||
**REQUIRED**. The name of the parameter.
|
||||
Parameter names are *case sensitive*.
|
||||
|
||||
- If [`in`](#parameterIn) is `"path"`, the `name` field MUST correspond to a
|
||||
template expression occurring within the [path](#pathsPath) field in the
|
||||
[Paths Object](#pathsObject). See [Path Templating](#pathTemplating) for further
|
||||
information.
|
||||
- If [`in`](#parameterIn) is `"header"` and the `name` field is `"Accept"`,
|
||||
`"Content-Type"` or `"Authorization"`, the parameter definition SHALL be ignored.
|
||||
- For all other cases, the `name` corresponds to the parameter name used by the
|
||||
[`in`](#parameterIn) property.
|
||||
"""
|
||||
|
||||
param_in: ParameterLocation = Field(alias="in")
|
||||
"""
|
||||
**REQUIRED**. The location of the parameter. Possible values are `"query"`,
|
||||
`"header"`, `"path"` or `"cookie"`.
|
||||
"""
|
||||
|
||||
allowEmptyValue: bool = False
|
||||
"""
|
||||
Sets the ability to pass empty-valued parameters.
|
||||
This is valid only for `query` parameters and allows sending a parameter with an
|
||||
empty value. Default value is `false`.
|
||||
If [`style`](#parameterStyle) is used, and if behavior is `n/a` (cannot be
|
||||
serialized), the value of `allowEmptyValue` SHALL be ignored.
|
||||
Use of this property is NOT RECOMMENDED, as it is likely to be removed in a later
|
||||
revision.
|
||||
"""
|
||||
|
||||
allowReserved: bool = False
|
||||
"""
|
||||
Determines whether the parameter value SHOULD allow reserved characters,
|
||||
as defined by [RFC3986](https://tools.ietf.org/html/rfc3986#section-2.2)
|
||||
`:/?#[]@!$&'()*+,;=` to be included without percent-encoding.
|
||||
This property only applies to parameters with an `in` value of `query`.
|
||||
The default value is `false`.
|
||||
"""
|
152
openapi_pydantic/v3/v3_0/path_item.py
Normal file
152
openapi_pydantic/v3/v3_0/path_item.py
Normal file
|
@ -0,0 +1,152 @@
|
|||
from typing import List, Optional, Union
|
||||
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
from openapi_pydantic.compat import PYDANTIC_V2, ConfigDict, Extra
|
||||
|
||||
from .operation import Operation
|
||||
from .parameter import Parameter
|
||||
from .reference import Reference
|
||||
from .server import Server
|
||||
|
||||
_examples = [
|
||||
{
|
||||
"get": {
|
||||
"description": "Returns pets based on ID",
|
||||
"summary": "Find pets by ID",
|
||||
"operationId": "getPetsById",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "pet response",
|
||||
"content": {
|
||||
"*/*": {
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {"$ref": "#/components/schemas/Pet"},
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
"default": {
|
||||
"description": "error payload",
|
||||
"content": {
|
||||
"text/html": {
|
||||
"schema": {"$ref": "#/components/schemas/ErrorModel"}
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"parameters": [
|
||||
{
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"description": "ID of pet to use",
|
||||
"required": True,
|
||||
"schema": {"type": "array", "items": {"type": "string"}},
|
||||
"style": "simple",
|
||||
}
|
||||
],
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
class PathItem(BaseModel):
|
||||
"""
|
||||
Describes the operations available on a single path.
|
||||
A Path Item MAY be empty, due to [ACL constraints](#securityFiltering).
|
||||
The path itself is still exposed to the documentation viewer
|
||||
but they will not know which operations and parameters are available.
|
||||
"""
|
||||
|
||||
ref: Optional[str] = Field(default=None, alias="$ref")
|
||||
"""
|
||||
Allows for an external definition of this path item.
|
||||
The referenced structure MUST be in the format of a
|
||||
[Path Item Object](#pathItemObject).
|
||||
|
||||
In case a Path Item Object field appears both in the defined object and the
|
||||
referenced object, the behavior is undefined.
|
||||
"""
|
||||
|
||||
summary: Optional[str] = None
|
||||
"""
|
||||
An optional, string summary, intended to apply to all operations in this path.
|
||||
"""
|
||||
|
||||
description: Optional[str] = None
|
||||
"""
|
||||
An optional, string description, intended to apply to all operations in this path.
|
||||
[CommonMark syntax](https://spec.commonmark.org/) MAY be used for rich text
|
||||
representation.
|
||||
"""
|
||||
|
||||
get: Optional[Operation] = None
|
||||
"""
|
||||
A definition of a GET operation on this path.
|
||||
"""
|
||||
|
||||
put: Optional[Operation] = None
|
||||
"""
|
||||
A definition of a PUT operation on this path.
|
||||
"""
|
||||
|
||||
post: Optional[Operation] = None
|
||||
"""
|
||||
A definition of a POST operation on this path.
|
||||
"""
|
||||
|
||||
delete: Optional[Operation] = None
|
||||
"""
|
||||
A definition of a DELETE operation on this path.
|
||||
"""
|
||||
|
||||
options: Optional[Operation] = None
|
||||
"""
|
||||
A definition of a OPTIONS operation on this path.
|
||||
"""
|
||||
|
||||
head: Optional[Operation] = None
|
||||
"""
|
||||
A definition of a HEAD operation on this path.
|
||||
"""
|
||||
|
||||
patch: Optional[Operation] = None
|
||||
"""
|
||||
A definition of a PATCH operation on this path.
|
||||
"""
|
||||
|
||||
trace: Optional[Operation] = None
|
||||
"""
|
||||
A definition of a TRACE operation on this path.
|
||||
"""
|
||||
|
||||
servers: Optional[List[Server]] = None
|
||||
"""
|
||||
An alternative `server` array to service all operations in this path.
|
||||
"""
|
||||
|
||||
parameters: Optional[List[Union[Parameter, Reference]]] = None
|
||||
"""
|
||||
A list of parameters that are applicable for all the operations described under
|
||||
this path. These parameters can be overridden at the operation level, but cannot be
|
||||
removed there. The list MUST NOT include duplicated parameters.
|
||||
A unique parameter is defined by a combination of a [name](#parameterName) and
|
||||
[location](#parameterIn). The list can use the [Reference Object](#referenceObject)
|
||||
to link to parameters that are defined at the
|
||||
[OpenAPI Object's components/parameters](#componentsParameters).
|
||||
"""
|
||||
|
||||
if PYDANTIC_V2:
|
||||
model_config = ConfigDict(
|
||||
extra="allow",
|
||||
populate_by_name=True,
|
||||
json_schema_extra={"examples": _examples},
|
||||
)
|
||||
|
||||
else:
|
||||
|
||||
class Config:
|
||||
extra = Extra.allow
|
||||
allow_population_by_field_name = True
|
||||
schema_extra = {"examples": _examples}
|
27
openapi_pydantic/v3/v3_0/paths.py
Normal file
27
openapi_pydantic/v3/v3_0/paths.py
Normal file
|
@ -0,0 +1,27 @@
|
|||
from typing import Dict
|
||||
|
||||
from .path_item import PathItem
|
||||
|
||||
Paths = Dict[str, PathItem]
|
||||
"""
|
||||
Holds the relative paths to the individual endpoints and their operations.
|
||||
The path is appended to the URL from the [`Server Object`](#serverObject) in order to
|
||||
construct the full URL.
|
||||
|
||||
The Paths MAY be empty, due to [ACL constraints](#securityFiltering).
|
||||
"""
|
||||
|
||||
"""Patterned Fields"""
|
||||
|
||||
# "/{path}" : PathItem
|
||||
"""
|
||||
A relative path to an individual endpoint.
|
||||
The field name MUST begin with a forward slash (`/`).
|
||||
The path is **appended** (no relative URL resolution) to the expanded URL
|
||||
from the [`Server Object`](#serverObject)'s `url` field in order to construct the full
|
||||
URL. [Path templating](#pathTemplating) is allowed.
|
||||
When matching URLs, concrete (non-templated) paths would be matched before their
|
||||
templated counterparts. Templated paths with the same hierarchy but different templated
|
||||
names MUST NOT exist as they are identical. In case of ambiguous matching, it's up to
|
||||
the tooling to decide which one to use.
|
||||
"""
|
38
openapi_pydantic/v3/v3_0/reference.py
Normal file
38
openapi_pydantic/v3/v3_0/reference.py
Normal file
|
@ -0,0 +1,38 @@
|
|||
from pydantic import BaseModel, Field
|
||||
|
||||
from openapi_pydantic.compat import PYDANTIC_V2, ConfigDict, Extra
|
||||
|
||||
_examples = [
|
||||
{"$ref": "#/components/schemas/Pet"},
|
||||
{"$ref": "Pet.json"},
|
||||
{"$ref": "definitions.json#/Pet"},
|
||||
]
|
||||
|
||||
|
||||
class Reference(BaseModel):
|
||||
"""
|
||||
A simple object to allow referencing other components in the specification.
|
||||
|
||||
The Reference Object is defined by [JSON Reference](https://tools.ietf.org/html/draft-pbryan-zyp-json-ref-03)
|
||||
and follows the same structure, behavior and rules.
|
||||
|
||||
For this specification, reference resolution is accomplished as defined by the JSON
|
||||
Reference specification and not by the JSON Schema specification.
|
||||
"""
|
||||
|
||||
ref: str = Field(alias="$ref")
|
||||
"""**REQUIRED**. The reference string."""
|
||||
|
||||
if PYDANTIC_V2:
|
||||
model_config = ConfigDict(
|
||||
extra="allow",
|
||||
populate_by_name=True,
|
||||
json_schema_extra={"examples": _examples},
|
||||
)
|
||||
|
||||
else:
|
||||
|
||||
class Config:
|
||||
extra = Extra.allow
|
||||
allow_population_by_field_name = True
|
||||
schema_extra = {"examples": _examples}
|
95
openapi_pydantic/v3/v3_0/request_body.py
Normal file
95
openapi_pydantic/v3/v3_0/request_body.py
Normal file
|
@ -0,0 +1,95 @@
|
|||
from typing import Dict, Optional
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
from openapi_pydantic.compat import PYDANTIC_V2, ConfigDict, Extra
|
||||
|
||||
from .media_type import MediaType
|
||||
|
||||
_examples = [
|
||||
{
|
||||
"description": "user to add to the system",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {"$ref": "#/components/schemas/User"},
|
||||
"examples": {
|
||||
"user": {
|
||||
"summary": "User Example",
|
||||
"externalValue": "http://foo.bar/examples/user-example.json",
|
||||
}
|
||||
},
|
||||
},
|
||||
"application/xml": {
|
||||
"schema": {"$ref": "#/components/schemas/User"},
|
||||
"examples": {
|
||||
"user": {
|
||||
"summary": "User example in XML",
|
||||
"externalValue": "http://foo.bar/examples/user-example.xml",
|
||||
}
|
||||
},
|
||||
},
|
||||
"text/plain": {
|
||||
"examples": {
|
||||
"user": {
|
||||
"summary": "User example in Plain text",
|
||||
"externalValue": "http://foo.bar/examples/user-example.txt",
|
||||
}
|
||||
}
|
||||
},
|
||||
"*/*": {
|
||||
"examples": {
|
||||
"user": {
|
||||
"summary": "User example in other format",
|
||||
"externalValue": "http://foo.bar/examples/user-example.whatever",
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
"description": "user to add to the system",
|
||||
"content": {
|
||||
"text/plain": {"schema": {"type": "array", "items": {"type": "string"}}}
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
class RequestBody(BaseModel):
|
||||
"""Describes a single request body."""
|
||||
|
||||
description: Optional[str] = None
|
||||
"""
|
||||
A brief description of the request body.
|
||||
This could contain examples of use.
|
||||
|
||||
[CommonMark syntax](https://spec.commonmark.org/) MAY be used for rich text
|
||||
representation.
|
||||
"""
|
||||
|
||||
content: Dict[str, MediaType]
|
||||
"""
|
||||
**REQUIRED**. The content of the request body.
|
||||
The key is a media type or [media type range](https://tools.ietf.org/html/rfc7231#appendix-D)
|
||||
and the value describes it.
|
||||
|
||||
For requests that match multiple keys, only the most specific key is applicable.
|
||||
e.g. text/plain overrides text/*
|
||||
"""
|
||||
|
||||
required: bool = False
|
||||
"""
|
||||
Determines if the request body is required in the request. Defaults to `false`.
|
||||
"""
|
||||
|
||||
if PYDANTIC_V2:
|
||||
model_config = ConfigDict(
|
||||
extra="allow",
|
||||
json_schema_extra={"examples": _examples},
|
||||
)
|
||||
|
||||
else:
|
||||
|
||||
class Config:
|
||||
extra = Extra.allow
|
||||
schema_extra = {"examples": _examples}
|
101
openapi_pydantic/v3/v3_0/response.py
Normal file
101
openapi_pydantic/v3/v3_0/response.py
Normal file
|
@ -0,0 +1,101 @@
|
|||
from typing import Dict, Optional, Union
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
from openapi_pydantic.compat import PYDANTIC_V2, ConfigDict, Extra
|
||||
|
||||
from .header import Header
|
||||
from .link import Link
|
||||
from .media_type import MediaType
|
||||
from .reference import Reference
|
||||
|
||||
_examples = [
|
||||
{
|
||||
"description": "A complex object array response",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {"$ref": "#/components/schemas/VeryComplexType"},
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
"description": "A simple string response",
|
||||
"content": {"text/plain": {"schema": {"type": "string"}}},
|
||||
},
|
||||
{
|
||||
"description": "A simple string response",
|
||||
"content": {"text/plain": {"schema": {"type": "string", "example": "whoa!"}}},
|
||||
"headers": {
|
||||
"X-Rate-Limit-Limit": {
|
||||
"description": ("The number of allowed requests in the current period"),
|
||||
"schema": {"type": "integer"},
|
||||
},
|
||||
"X-Rate-Limit-Remaining": {
|
||||
"description": (
|
||||
"The number of remaining requests in the current period"
|
||||
),
|
||||
"schema": {"type": "integer"},
|
||||
},
|
||||
"X-Rate-Limit-Reset": {
|
||||
"description": ("The number of seconds left in the current period"),
|
||||
"schema": {"type": "integer"},
|
||||
},
|
||||
},
|
||||
},
|
||||
{"description": "object created"},
|
||||
]
|
||||
|
||||
|
||||
class Response(BaseModel):
|
||||
"""
|
||||
Describes a single response from an API Operation, including design-time,
|
||||
static `links` to operations based on the response.
|
||||
"""
|
||||
|
||||
description: str
|
||||
"""
|
||||
**REQUIRED**. A short description of the response.
|
||||
[CommonMark syntax](https://spec.commonmark.org/) MAY be used for rich text
|
||||
representation.
|
||||
"""
|
||||
|
||||
headers: Optional[Dict[str, Union[Header, Reference]]] = None
|
||||
"""
|
||||
Maps a header name to its definition.
|
||||
[RFC7230](https://tools.ietf.org/html/rfc7230#page-22) states header names are case
|
||||
insensitive. If a response header is defined with the name `"Content-Type"`, it
|
||||
SHALL be ignored.
|
||||
"""
|
||||
|
||||
content: Optional[Dict[str, MediaType]] = None
|
||||
"""
|
||||
A map containing descriptions of potential response payloads.
|
||||
The key is a media type or [media type range](https://tools.ietf.org/html/rfc7231#appendix-D)
|
||||
and the value describes it.
|
||||
|
||||
For responses that match multiple keys, only the most specific key is applicable.
|
||||
e.g. text/plain overrides text/*
|
||||
"""
|
||||
|
||||
links: Optional[Dict[str, Union[Link, Reference]]] = None
|
||||
"""
|
||||
A map of operations links that can be followed from the response.
|
||||
The key of the map is a short name for the link,
|
||||
following the naming constraints of the names for
|
||||
[Component Objects](#componentsObject).
|
||||
"""
|
||||
|
||||
if PYDANTIC_V2:
|
||||
model_config = ConfigDict(
|
||||
extra="allow",
|
||||
json_schema_extra={"examples": _examples},
|
||||
)
|
||||
|
||||
else:
|
||||
|
||||
class Config:
|
||||
extra = Extra.allow
|
||||
schema_extra = {"examples": _examples}
|
49
openapi_pydantic/v3/v3_0/responses.py
Normal file
49
openapi_pydantic/v3/v3_0/responses.py
Normal file
|
@ -0,0 +1,49 @@
|
|||
from typing import Dict, Union
|
||||
|
||||
from .reference import Reference
|
||||
from .response import Response
|
||||
|
||||
Responses = Dict[str, Union[Response, Reference]]
|
||||
"""
|
||||
A container for the expected responses of an operation.
|
||||
The container maps a HTTP response code to the expected response.
|
||||
|
||||
The documentation is not necessarily expected to cover all possible HTTP response codes
|
||||
because they may not be known in advance.
|
||||
However, documentation is expected to cover a successful operation response and any
|
||||
known errors.
|
||||
|
||||
The `default` MAY be used as a default response object for all HTTP codes
|
||||
that are not covered individually by the specification.
|
||||
|
||||
The `Responses Object` MUST contain at least one response code, and it
|
||||
SHOULD be the response for a successful operation call.
|
||||
"""
|
||||
|
||||
"""Fixed Fields"""
|
||||
|
||||
# default: Optional[Union[Response, Reference]]
|
||||
"""
|
||||
The documentation of responses other than the ones declared for specific HTTP response
|
||||
codes. Use this field to cover undeclared responses.
|
||||
A [Reference Object](#referenceObject) can link to a response
|
||||
that the [OpenAPI Object's components/responses](#componentsResponses) section defines.
|
||||
"""
|
||||
|
||||
"""Patterned Fields"""
|
||||
# {httpStatusCode]: Optional[Union[Response, Reference]]
|
||||
"""
|
||||
Any [HTTP status code](#httpCodes) can be used as the property name,
|
||||
but only one property per code, to describe the expected response for that HTTP status
|
||||
code.
|
||||
|
||||
A [Reference Object](#referenceObject) can link to a response
|
||||
that is defined in the [OpenAPI Object's components/responses](#componentsResponses)
|
||||
section. This field MUST be enclosed in quotation marks (for example, "200") for
|
||||
compatibility between JSON and YAML. To define a range of response codes, this field
|
||||
MAY contain the uppercase wildcard character `X`. For example, `2XX` represents all
|
||||
response codes between `[200-299]`. Only the following range definitions are allowed:
|
||||
`1XX`, `2XX`, `3XX`, `4XX`, and `5XX`.
|
||||
If a response is defined using an explicit code,
|
||||
the explicit code definition takes precedence over the range definition for that code.
|
||||
"""
|
614
openapi_pydantic/v3/v3_0/schema.py
Normal file
614
openapi_pydantic/v3/v3_0/schema.py
Normal file
|
@ -0,0 +1,614 @@
|
|||
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Union
|
||||
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
from openapi_pydantic.compat import PYDANTIC_V2, ConfigDict, Extra, min_length_arg
|
||||
|
||||
from .datatype import DataType
|
||||
from .discriminator import Discriminator
|
||||
from .external_documentation import ExternalDocumentation
|
||||
from .reference import Reference
|
||||
from .xml import XML
|
||||
|
||||
_examples = [
|
||||
{"type": "string", "format": "email"},
|
||||
{
|
||||
"type": "object",
|
||||
"required": ["name"],
|
||||
"properties": {
|
||||
"name": {"type": "string"},
|
||||
"address": {"$ref": "#/components/schemas/Address"},
|
||||
"age": {"type": "integer", "format": "int32", "minimum": 0},
|
||||
},
|
||||
},
|
||||
{"type": "object", "additionalProperties": {"type": "string"}},
|
||||
{
|
||||
"type": "object",
|
||||
"additionalProperties": {"$ref": "#/components/schemas/ComplexModel"},
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {"type": "integer", "format": "int64"},
|
||||
"name": {"type": "string"},
|
||||
},
|
||||
"required": ["name"],
|
||||
"example": {"name": "Puma", "id": 1},
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"required": ["message", "code"],
|
||||
"properties": {
|
||||
"message": {"type": "string"},
|
||||
"code": {"type": "integer", "minimum": 100, "maximum": 600},
|
||||
},
|
||||
},
|
||||
{
|
||||
"allOf": [
|
||||
{"$ref": "#/components/schemas/ErrorModel"},
|
||||
{
|
||||
"type": "object",
|
||||
"required": ["rootCause"],
|
||||
"properties": {"rootCause": {"type": "string"}},
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"discriminator": {"propertyName": "petType"},
|
||||
"properties": {
|
||||
"name": {"type": "string"},
|
||||
"petType": {"type": "string"},
|
||||
},
|
||||
"required": ["name", "petType"],
|
||||
},
|
||||
{
|
||||
"description": "A representation of a cat. "
|
||||
"Note that `Cat` will be used as the discriminator value.",
|
||||
"allOf": [
|
||||
{"$ref": "#/components/schemas/Pet"},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"huntingSkill": {
|
||||
"type": "string",
|
||||
"description": "The measured skill for hunting",
|
||||
"default": "lazy",
|
||||
"enum": [
|
||||
"clueless",
|
||||
"lazy",
|
||||
"adventurous",
|
||||
"aggressive",
|
||||
],
|
||||
}
|
||||
},
|
||||
"required": ["huntingSkill"],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
"description": "A representation of a dog. "
|
||||
"Note that `Dog` will be used as the discriminator value.",
|
||||
"allOf": [
|
||||
{"$ref": "#/components/schemas/Pet"},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"packSize": {
|
||||
"type": "integer",
|
||||
"format": "int32",
|
||||
"description": ("the size of the pack the dog is from"),
|
||||
"default": 0,
|
||||
"minimum": 0,
|
||||
}
|
||||
},
|
||||
"required": ["packSize"],
|
||||
},
|
||||
],
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
class Schema(BaseModel):
|
||||
"""
|
||||
The Schema Object allows the definition of input and output data types.
|
||||
These types can be objects, but also primitives and arrays.
|
||||
This object is an extended subset of the [JSON Schema Specification Wright Draft 00](https://json-schema.org/).
|
||||
|
||||
For more information about the properties,
|
||||
see [JSON Schema Core](https://tools.ietf.org/html/draft-wright-json-schema-00)
|
||||
and [JSON Schema Validation](https://tools.ietf.org/html/draft-wright-json-schema-validation-00).
|
||||
Unless stated otherwise, the property definitions follow the JSON Schema.
|
||||
"""
|
||||
|
||||
"""
|
||||
The following properties are taken directly from the JSON Schema definition and
|
||||
follow the same specifications:
|
||||
"""
|
||||
|
||||
title: Optional[str] = None
|
||||
"""
|
||||
The value of "title" MUST be a string.
|
||||
|
||||
The title can be used to decorate a user interface with
|
||||
information about the data produced by this user interface.
|
||||
The title will preferrably be short.
|
||||
"""
|
||||
|
||||
multipleOf: Optional[float] = Field(default=None, gt=0.0)
|
||||
"""
|
||||
The value of "multipleOf" MUST be a number, strictly greater than 0.
|
||||
|
||||
A numeric instance is only valid if division by this keyword's value
|
||||
results in an integer.
|
||||
"""
|
||||
|
||||
maximum: Optional[float] = None
|
||||
"""
|
||||
The value of "maximum" MUST be a number, representing an upper limit
|
||||
for a numeric instance.
|
||||
|
||||
If the instance is a number, then this keyword validates if
|
||||
"exclusiveMaximum" is true and instance is less than the provided
|
||||
value, or else if the instance is less than or exactly equal to the
|
||||
provided value.
|
||||
"""
|
||||
|
||||
exclusiveMaximum: Optional[bool] = None
|
||||
"""
|
||||
The value of "exclusiveMaximum" MUST be a boolean, representing
|
||||
whether the limit in "maximum" is exclusive or not. An undefined
|
||||
value is the same as false.
|
||||
|
||||
If "exclusiveMaximum" is true, then a numeric instance SHOULD NOT be
|
||||
equal to the value specified in "maximum". If "exclusiveMaximum" is
|
||||
false (or not specified), then a numeric instance MAY be equal to the
|
||||
value of "maximum".
|
||||
"""
|
||||
|
||||
minimum: Optional[float] = None
|
||||
"""
|
||||
The value of "minimum" MUST be a number, representing a lower limit
|
||||
for a numeric instance.
|
||||
|
||||
If the instance is a number, then this keyword validates if
|
||||
"exclusiveMinimum" is true and instance is greater than the provided
|
||||
value, or else if the instance is greater than or exactly equal to
|
||||
the provided value.
|
||||
"""
|
||||
|
||||
exclusiveMinimum: Optional[bool] = None
|
||||
"""
|
||||
The value of "exclusiveMinimum" MUST be a boolean, representing
|
||||
whether the limit in "minimum" is exclusive or not. An undefined
|
||||
value is the same as false.
|
||||
|
||||
If "exclusiveMinimum" is true, then a numeric instance SHOULD NOT be
|
||||
equal to the value specified in "minimum". If "exclusiveMinimum" is
|
||||
false (or not specified), then a numeric instance MAY be equal to the
|
||||
value of "minimum".
|
||||
"""
|
||||
|
||||
maxLength: Optional[int] = Field(default=None, ge=0)
|
||||
"""
|
||||
The value of this keyword MUST be a non-negative integer.
|
||||
|
||||
The value of this keyword MUST be an integer. This integer MUST be
|
||||
greater than, or equal to, 0.
|
||||
|
||||
A string instance is valid against this keyword if its length is less
|
||||
than, or equal to, the value of this keyword.
|
||||
|
||||
The length of a string instance is defined as the number of its
|
||||
characters as defined by RFC 7159 [RFC7159].
|
||||
"""
|
||||
|
||||
minLength: Optional[int] = Field(default=None, ge=0)
|
||||
"""
|
||||
A string instance is valid against this keyword if its length is
|
||||
greater than, or equal to, the value of this keyword.
|
||||
|
||||
The length of a string instance is defined as the number of its
|
||||
characters as defined by RFC 7159 [RFC7159].
|
||||
|
||||
The value of this keyword MUST be an integer. This integer MUST be
|
||||
greater than, or equal to, 0.
|
||||
|
||||
"minLength", if absent, may be considered as being present with
|
||||
integer value 0.
|
||||
"""
|
||||
|
||||
pattern: Optional[str] = None
|
||||
"""
|
||||
The value of this keyword MUST be a string. This string SHOULD be a
|
||||
valid regular expression, according to the ECMA 262 regular
|
||||
expression dialect.
|
||||
|
||||
A string instance is considered valid if the regular expression
|
||||
matches the instance successfully. Recall: regular expressions are
|
||||
not implicitly anchored.
|
||||
"""
|
||||
|
||||
maxItems: Optional[int] = Field(default=None, ge=0)
|
||||
"""
|
||||
The value of this keyword MUST be an integer. This integer MUST be
|
||||
greater than, or equal to, 0.
|
||||
|
||||
An array instance is valid against "maxItems" if its size is less
|
||||
than, or equal to, the value of this keyword.
|
||||
"""
|
||||
|
||||
minItems: Optional[int] = Field(default=None, ge=0)
|
||||
"""
|
||||
The value of this keyword MUST be an integer. This integer MUST be
|
||||
greater than, or equal to, 0.
|
||||
|
||||
An array instance is valid against "minItems" if its size is greater
|
||||
than, or equal to, the value of this keyword.
|
||||
|
||||
If this keyword is not present, it may be considered present with a
|
||||
value of 0.
|
||||
"""
|
||||
|
||||
uniqueItems: Optional[bool] = None
|
||||
"""
|
||||
The value of this keyword MUST be a boolean.
|
||||
|
||||
If this keyword has boolean value false, the instance validates
|
||||
successfully. If it has boolean value true, the instance validates
|
||||
successfully if all of its elements are unique.
|
||||
|
||||
If not present, this keyword may be considered present with boolean
|
||||
value false.
|
||||
"""
|
||||
|
||||
maxProperties: Optional[int] = Field(default=None, ge=0)
|
||||
"""
|
||||
The value of this keyword MUST be an integer. This integer MUST be
|
||||
greater than, or equal to, 0.
|
||||
|
||||
An object instance is valid against "maxProperties" if its number of
|
||||
properties is less than, or equal to, the value of this keyword.
|
||||
"""
|
||||
|
||||
minProperties: Optional[int] = Field(default=None, ge=0)
|
||||
"""
|
||||
The value of this keyword MUST be an integer. This integer MUST be
|
||||
greater than, or equal to, 0.
|
||||
|
||||
An object instance is valid against "minProperties" if its number of
|
||||
properties is greater than, or equal to, the value of this keyword.
|
||||
|
||||
If this keyword is not present, it may be considered present with a
|
||||
value of 0.
|
||||
"""
|
||||
|
||||
required: Optional[List[str]] = Field(default=None, **min_length_arg(1))
|
||||
"""
|
||||
The value of this keyword MUST be an array. This array MUST have at
|
||||
least one element. Elements of this array MUST be strings, and MUST
|
||||
be unique.
|
||||
|
||||
An object instance is valid against this keyword if its property set
|
||||
contains all elements in this keyword's array value.
|
||||
"""
|
||||
|
||||
enum: Optional[List[Any]] = Field(default=None, **min_length_arg(1))
|
||||
"""
|
||||
The value of this keyword MUST be an array. This array SHOULD have
|
||||
at least one element. Elements in the array SHOULD be unique.
|
||||
|
||||
Elements in the array MAY be of any type, including null.
|
||||
|
||||
An instance validates successfully against this keyword if its value
|
||||
is equal to one of the elements in this keyword's array value.
|
||||
"""
|
||||
|
||||
"""
|
||||
The following properties are taken from the JSON Schema definition
|
||||
but their definitions were adjusted to the OpenAPI Specification.
|
||||
"""
|
||||
|
||||
type: Optional[DataType] = None
|
||||
"""
|
||||
**From OpenAPI spec:
|
||||
Value MUST be a string. Multiple types via an array are not supported.**
|
||||
|
||||
From JSON Schema:
|
||||
The value of this keyword MUST be either a string or an array. If it
|
||||
is an array, elements of the array MUST be strings and MUST be
|
||||
unique.
|
||||
|
||||
String values MUST be one of the seven primitive types defined by the
|
||||
core specification.
|
||||
|
||||
An instance matches successfully if its primitive type is one of the
|
||||
types defined by keyword. Recall: "number" includes "integer".
|
||||
"""
|
||||
|
||||
allOf: Optional[List[Union[Reference, "Schema"]]] = None
|
||||
"""
|
||||
**From OpenAPI spec:
|
||||
Inline or referenced schema MUST be of a [Schema Object](#schemaObject) and not a
|
||||
standard JSON Schema.**
|
||||
|
||||
From JSON Schema:
|
||||
This keyword's value MUST be an array. This array MUST have at least
|
||||
one element.
|
||||
|
||||
Elements of the array MUST be objects. Each object MUST be a valid
|
||||
JSON Schema.
|
||||
|
||||
An instance validates successfully against this keyword if it
|
||||
validates successfully against all schemas defined by this keyword's
|
||||
value.
|
||||
"""
|
||||
|
||||
oneOf: Optional[List[Union[Reference, "Schema"]]] = None
|
||||
"""
|
||||
**From OpenAPI spec:
|
||||
Inline or referenced schema MUST be of a [Schema Object](#schemaObject) and not a
|
||||
standard JSON Schema.**
|
||||
|
||||
From JSON Schema:
|
||||
This keyword's value MUST be an array. This array MUST have at least
|
||||
one element.
|
||||
|
||||
Elements of the array MUST be objects. Each object MUST be a valid
|
||||
JSON Schema.
|
||||
|
||||
An instance validates successfully against this keyword if it
|
||||
validates successfully against exactly one schema defined by this
|
||||
keyword's value.
|
||||
"""
|
||||
|
||||
anyOf: Optional[List[Union[Reference, "Schema"]]] = None
|
||||
"""
|
||||
**From OpenAPI spec:
|
||||
Inline or referenced schema MUST be of a [Schema Object](#schemaObject) and not a
|
||||
standard JSON Schema.**
|
||||
|
||||
From JSON Schema:
|
||||
This keyword's value MUST be an array. This array MUST have at least
|
||||
one element.
|
||||
|
||||
Elements of the array MUST be objects. Each object MUST be a valid
|
||||
JSON Schema.
|
||||
|
||||
An instance validates successfully against this keyword if it
|
||||
validates successfully against at least one schema defined by this
|
||||
keyword's value.
|
||||
"""
|
||||
|
||||
schema_not: Optional[Union[Reference, "Schema"]] = Field(default=None, alias="not")
|
||||
"""
|
||||
**From OpenAPI spec:
|
||||
Inline or referenced schema MUST be of a [Schema Object](#schemaObject) and not a
|
||||
standard JSON Schema.**
|
||||
|
||||
From JSON Schema:
|
||||
This keyword's value MUST be an object. This object MUST be a valid
|
||||
JSON Schema.
|
||||
|
||||
An instance is valid against this keyword if it fails to validate
|
||||
successfully against the schema defined by this keyword.
|
||||
"""
|
||||
|
||||
items: Optional[Union[Reference, "Schema"]] = None
|
||||
"""
|
||||
**From OpenAPI spec:
|
||||
Value MUST be an object and not an array.
|
||||
Inline or referenced schema MUST be of a [Schema Object](#schemaObject) and not a
|
||||
standard JSON Schema. `items` MUST be present if the `type` is `array`.**
|
||||
|
||||
From JSON Schema:
|
||||
The value of "items" MUST be either a schema or array of schemas.
|
||||
|
||||
Successful validation of an array instance with regards to these two
|
||||
keywords is determined as follows:
|
||||
|
||||
- if "items" is not present, or its value is an object, validation
|
||||
of the instance always succeeds, regardless of the value of
|
||||
"additionalItems";
|
||||
- if the value of "additionalItems" is boolean value true or an
|
||||
object, validation of the instance always succeeds;
|
||||
- if the value of "additionalItems" is boolean value false and the
|
||||
value of "items" is an array, the instance is valid if its size is
|
||||
less than, or equal to, the size of "items".
|
||||
"""
|
||||
|
||||
properties: Optional[Dict[str, Union[Reference, "Schema"]]] = None
|
||||
"""
|
||||
**From OpenAPI spec:
|
||||
Property definitions MUST be a [Schema Object](#schemaObject)
|
||||
and not a standard JSON Schema (inline or referenced).**
|
||||
|
||||
From JSON Schema:
|
||||
The value of "properties" MUST be an object. Each value of this
|
||||
object MUST be an object, and each object MUST be a valid JSON
|
||||
Schema.
|
||||
|
||||
If absent, it can be considered the same as an empty object.
|
||||
"""
|
||||
|
||||
additionalProperties: Optional[Union[bool, Reference, "Schema"]] = None
|
||||
"""
|
||||
**From OpenAPI spec:
|
||||
Value can be boolean or object.
|
||||
Inline or referenced schema MUST be of a [Schema Object](#schemaObject) and not a
|
||||
standard JSON Schema.
|
||||
Consistent with JSON Schema, `additionalProperties` defaults to `true`.**
|
||||
|
||||
From JSON Schema:
|
||||
The value of "additionalProperties" MUST be a boolean or a schema.
|
||||
|
||||
If "additionalProperties" is absent, it may be considered present
|
||||
with an empty schema as a value.
|
||||
|
||||
If "additionalProperties" is true, validation always succeeds.
|
||||
|
||||
If "additionalProperties" is false, validation succeeds only if the
|
||||
instance is an object and all properties on the instance were covered
|
||||
by "properties" and/or "patternProperties".
|
||||
|
||||
If "additionalProperties" is an object, validate the value as a
|
||||
schema to all of the properties that weren't validated by
|
||||
"properties" nor "patternProperties".
|
||||
"""
|
||||
|
||||
description: Optional[str] = None
|
||||
"""
|
||||
**From OpenAPI spec:
|
||||
[CommonMark syntax](https://spec.commonmark.org/) MAY be used for rich text
|
||||
representation.**
|
||||
|
||||
From JSON Schema:
|
||||
The value "description" MUST be a string.
|
||||
|
||||
The description can be used to decorate a user interface with
|
||||
information about the data produced by this user interface.
|
||||
The description will provide explanation about the purpose of
|
||||
the instance described by this schema.
|
||||
"""
|
||||
|
||||
schema_format: Optional[str] = Field(default=None, alias="format")
|
||||
"""
|
||||
**From OpenAPI spec:
|
||||
[Data Type Formats](#dataTypeFormat) for further details.
|
||||
While relying on JSON Schema's defined formats, the OAS offers a few additional
|
||||
predefined formats.**
|
||||
|
||||
From JSON Schema:
|
||||
Structural validation alone may be insufficient to validate that an
|
||||
instance meets all the requirements of an application. The "format"
|
||||
keyword is defined to allow interoperable semantic validation for a
|
||||
fixed subset of values which are accurately described by
|
||||
authoritative resources, be they RFCs or other external
|
||||
specifications.
|
||||
|
||||
The value of this keyword is called a format attribute. It MUST be a
|
||||
string. A format attribute can generally only validate a given set
|
||||
of instance types. If the type of the instance to validate is not in
|
||||
this set, validation for this format attribute and instance SHOULD
|
||||
succeed.
|
||||
"""
|
||||
|
||||
default: Optional[Any] = None
|
||||
"""
|
||||
**From OpenAPI spec:
|
||||
The default value represents what would be assumed by the consumer of the input
|
||||
as the value of the schema if one is not provided.
|
||||
Unlike JSON Schema, the value MUST conform to the defined type for the Schema
|
||||
Object defined at the same level. For example, if `type` is `string`, then
|
||||
`default` can be `"foo"` but cannot be `1`.**
|
||||
|
||||
From JSON Schema:
|
||||
There are no restrictions placed on the value of this keyword.
|
||||
|
||||
This keyword can be used to supply a default JSON value associated
|
||||
with a particular schema. It is RECOMMENDED that a default value be
|
||||
valid against the associated schema.
|
||||
|
||||
This keyword MAY be used in root schemas, and in any subschemas.
|
||||
"""
|
||||
|
||||
"""
|
||||
Other than the JSON Schema subset fields, the following fields MAY be used for
|
||||
further schema documentation:
|
||||
"""
|
||||
|
||||
nullable: Optional[bool] = None
|
||||
"""
|
||||
A `true` value adds `"null"` to the allowed type specified by the `type` keyword,
|
||||
only if `type` is explicitly defined within the same Schema Object.
|
||||
Other Schema Object constraints retain their defined behavior,
|
||||
and therefore may disallow the use of `null` as a value.
|
||||
A `false` value leaves the specified or default `type` unmodified.
|
||||
The default value is `false`.
|
||||
"""
|
||||
|
||||
discriminator: Optional[Discriminator] = None
|
||||
"""
|
||||
Adds support for polymorphism.
|
||||
The discriminator is an object name that is used to differentiate between other
|
||||
schemas which may satisfy the payload description.
|
||||
See [Composition and Inheritance](#schemaComposition) for more details.
|
||||
"""
|
||||
|
||||
readOnly: Optional[bool] = None
|
||||
"""
|
||||
Relevant only for Schema `"properties"` definitions.
|
||||
Declares the property as "read only".
|
||||
This means that it MAY be sent as part of a response but SHOULD NOT be sent as part
|
||||
of the request. If the property is marked as `readOnly` being `true` and is in the
|
||||
`required` list, the `required` will take effect on the response only.
|
||||
A property MUST NOT be marked as both `readOnly` and `writeOnly` being `true`.
|
||||
Default value is `false`.
|
||||
"""
|
||||
|
||||
writeOnly: Optional[bool] = None
|
||||
"""
|
||||
Relevant only for Schema `"properties"` definitions.
|
||||
Declares the property as "write only".
|
||||
Therefore, it MAY be sent as part of a request but SHOULD NOT be sent as part of
|
||||
the response. If the property is marked as `writeOnly` being `true` and is in the
|
||||
`required` list, the `required` will take effect on the request only.
|
||||
A property MUST NOT be marked as both `readOnly` and `writeOnly` being `true`.
|
||||
Default value is `false`.
|
||||
"""
|
||||
|
||||
xml: Optional[XML] = None
|
||||
"""
|
||||
This MAY be used only on properties schemas.
|
||||
It has no effect on root schemas.
|
||||
Adds additional metadata to describe the XML representation of this property.
|
||||
"""
|
||||
|
||||
externalDocs: Optional[ExternalDocumentation] = None
|
||||
"""
|
||||
Additional external documentation for this schema.
|
||||
"""
|
||||
|
||||
example: Optional[Any] = None
|
||||
"""
|
||||
A free-form property to include an example of an instance for this schema.
|
||||
To represent examples that cannot be naturally represented in JSON or YAML,
|
||||
a string value can be used to contain the example with escaping where necessary.
|
||||
"""
|
||||
|
||||
deprecated: Optional[bool] = None
|
||||
"""
|
||||
Specifies that a schema is deprecated and SHOULD be transitioned out of usage.
|
||||
Default value is `false`.
|
||||
"""
|
||||
|
||||
if PYDANTIC_V2:
|
||||
model_config = ConfigDict(
|
||||
extra="allow",
|
||||
populate_by_name=True,
|
||||
json_schema_extra={"examples": _examples},
|
||||
)
|
||||
|
||||
else:
|
||||
|
||||
class Config:
|
||||
extra = Extra.allow
|
||||
allow_population_by_field_name = True
|
||||
schema_extra = {"examples": _examples}
|
||||
|
||||
|
||||
if TYPE_CHECKING:
|
||||
|
||||
def schema_validate(
|
||||
obj: Any,
|
||||
*,
|
||||
strict: Optional[bool] = None,
|
||||
from_attributes: Optional[bool] = None,
|
||||
context: Optional[Dict[str, Any]] = None
|
||||
) -> Schema: ...
|
||||
|
||||
elif PYDANTIC_V2:
|
||||
schema_validate = Schema.model_validate
|
||||
|
||||
else:
|
||||
schema_validate = Schema.parse_obj
|
32
openapi_pydantic/v3/v3_0/security_requirement.py
Normal file
32
openapi_pydantic/v3/v3_0/security_requirement.py
Normal file
|
@ -0,0 +1,32 @@
|
|||
from typing import Dict, List
|
||||
|
||||
SecurityRequirement = Dict[str, List[str]]
|
||||
"""
|
||||
Lists the required security schemes to execute this operation.
|
||||
The name used for each property MUST correspond to a security scheme declared in the
|
||||
[Security Schemes](#componentsSecuritySchemes) under the
|
||||
[Components Object](#componentsObject).
|
||||
|
||||
Security Requirement Objects that contain multiple schemes require that
|
||||
all schemes MUST be satisfied for a request to be authorized.
|
||||
This enables support for scenarios where multiple query parameters or HTTP headers
|
||||
are required to convey security information.
|
||||
|
||||
When a list of Security Requirement Objects is defined on the
|
||||
[OpenAPI Object](#oasObject) or [Operation Object](#operationObject),
|
||||
only one of the Security Requirement Objects in the list needs to be satisfied to
|
||||
authorize the request.
|
||||
"""
|
||||
|
||||
"""Patterned Fields"""
|
||||
|
||||
# {name}: List[str]
|
||||
"""
|
||||
Each name MUST correspond to a security scheme which is declared
|
||||
in the [Security Schemes](#componentsSecuritySchemes) under the
|
||||
[Components Object](#componentsObject).
|
||||
If the security scheme is of type `"oauth2"` or `"openIdConnect"`,
|
||||
then the value is a list of scope names required for the execution,
|
||||
and the list MAY be empty if authorization does not require a specified scope.
|
||||
For other security scheme types, the array MUST be empty.
|
||||
"""
|
112
openapi_pydantic/v3/v3_0/security_scheme.py
Normal file
112
openapi_pydantic/v3/v3_0/security_scheme.py
Normal file
|
@ -0,0 +1,112 @@
|
|||
from typing import Optional
|
||||
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
from openapi_pydantic.compat import PYDANTIC_V2, ConfigDict, Extra
|
||||
|
||||
from .oauth_flows import OAuthFlows
|
||||
|
||||
_examples = [
|
||||
{"type": "http", "scheme": "basic"},
|
||||
{"type": "apiKey", "name": "api_key", "in": "header"},
|
||||
{"type": "http", "scheme": "bearer", "bearerFormat": "JWT"},
|
||||
{
|
||||
"type": "oauth2",
|
||||
"flows": {
|
||||
"implicit": {
|
||||
"authorizationUrl": "https://example.com/api/oauth/dialog",
|
||||
"scopes": {
|
||||
"write:pets": "modify pets in your account",
|
||||
"read:pets": "read your pets",
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
"type": "openIdConnect",
|
||||
"openIdConnectUrl": "https://example.com/openIdConnect",
|
||||
},
|
||||
{
|
||||
"type": "openIdConnect",
|
||||
"openIdConnectUrl": "openIdConnect",
|
||||
}, # #5: allow relative path
|
||||
]
|
||||
|
||||
|
||||
class SecurityScheme(BaseModel):
|
||||
"""
|
||||
Defines a security scheme that can be used by the operations.
|
||||
Supported schemes are HTTP authentication,
|
||||
an API key (either as a header, a cookie parameter or as a query parameter),
|
||||
OAuth2's common flows (implicit, password, client credentials and authorization
|
||||
code) as defined in [RFC6749](https://tools.ietf.org/html/rfc6749),
|
||||
and [OpenID Connect Discovery](https://tools.ietf.org/html/draft-ietf-oauth-discovery-06).
|
||||
"""
|
||||
|
||||
type: str
|
||||
"""
|
||||
**REQUIRED**. The type of the security scheme.
|
||||
Valid values are `"apiKey"`, `"http"`, `"oauth2"`, `"openIdConnect"`.
|
||||
"""
|
||||
|
||||
description: Optional[str] = None
|
||||
"""
|
||||
A short description for security scheme.
|
||||
[CommonMark syntax](https://spec.commonmark.org/) MAY be used for rich text
|
||||
representation.
|
||||
"""
|
||||
|
||||
name: Optional[str] = None
|
||||
"""
|
||||
**REQUIRED** for `apiKey`. The name of the header, query or cookie parameter to be
|
||||
used.
|
||||
"""
|
||||
|
||||
security_scheme_in: Optional[str] = Field(alias="in", default=None)
|
||||
"""
|
||||
**REQUIRED** for `apiKey`. The location of the API key. Valid values are `"query"`,
|
||||
`"header"` or `"cookie"`.
|
||||
"""
|
||||
|
||||
scheme: Optional[str] = None
|
||||
"""
|
||||
**REQUIRED** for `http`. The name of the HTTP Authorization scheme to be used in the
|
||||
[Authorization header as defined in RFC7235](https://tools.ietf.org/html/rfc7235#section-5.1).
|
||||
|
||||
The values used SHOULD be registered in the
|
||||
[IANA Authentication Scheme registry](https://www.iana.org/assignments/http-authschemes/http-authschemes.xhtml).
|
||||
"""
|
||||
|
||||
bearerFormat: Optional[str] = None
|
||||
"""
|
||||
A hint to the client to identify how the bearer token is formatted.
|
||||
|
||||
Bearer tokens are usually generated by an authorization server,
|
||||
so this information is primarily for documentation purposes.
|
||||
"""
|
||||
|
||||
flows: Optional[OAuthFlows] = None
|
||||
"""
|
||||
**REQUIRED** for `oauth2`. An object containing configuration information for the
|
||||
flow types supported.
|
||||
"""
|
||||
|
||||
openIdConnectUrl: Optional[str] = None
|
||||
"""
|
||||
**REQUIRED** for `openIdConnect`. OpenId Connect URL to discover OAuth2
|
||||
configuration values. This MUST be in the form of a URL.
|
||||
"""
|
||||
|
||||
if PYDANTIC_V2:
|
||||
model_config = ConfigDict(
|
||||
extra="allow",
|
||||
populate_by_name=True,
|
||||
json_schema_extra={"examples": _examples},
|
||||
)
|
||||
|
||||
else:
|
||||
|
||||
class Config:
|
||||
extra = Extra.allow
|
||||
allow_population_by_field_name = True
|
||||
schema_extra = {"examples": _examples}
|
67
openapi_pydantic/v3/v3_0/server.py
Normal file
67
openapi_pydantic/v3/v3_0/server.py
Normal file
|
@ -0,0 +1,67 @@
|
|||
from typing import Dict, Optional
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
from openapi_pydantic.compat import PYDANTIC_V2, ConfigDict, Extra
|
||||
|
||||
from .server_variable import ServerVariable
|
||||
|
||||
_examples = [
|
||||
{
|
||||
"url": "https://development.gigantic-server.com/v1",
|
||||
"description": "Development server",
|
||||
},
|
||||
{
|
||||
"url": "https://{username}.gigantic-server.com:{port}/{basePath}",
|
||||
"description": "The production API server",
|
||||
"variables": {
|
||||
"username": {
|
||||
"default": "demo",
|
||||
"description": "this value is assigned by the service"
|
||||
"provider, in this example `gigantic-server.com`",
|
||||
},
|
||||
"port": {"enum": ["8443", "443"], "default": "8443"},
|
||||
"basePath": {"default": "v2"},
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
class Server(BaseModel):
|
||||
"""An object representing a Server."""
|
||||
|
||||
url: str
|
||||
"""
|
||||
**REQUIRED**. A URL to the target host.
|
||||
|
||||
This URL supports Server Variables and MAY be relative,
|
||||
to indicate that the host location is relative to the location where the OpenAPI
|
||||
document is being served.
|
||||
Variable substitutions will be made when a variable is named in `{`brackets`}`.
|
||||
"""
|
||||
|
||||
description: Optional[str] = None
|
||||
"""
|
||||
An optional string describing the host designated by the URL.
|
||||
[CommonMark syntax](https://spec.commonmark.org/) MAY be used for rich text
|
||||
representation.
|
||||
"""
|
||||
|
||||
variables: Optional[Dict[str, ServerVariable]] = None
|
||||
"""
|
||||
A map between a variable name and its value.
|
||||
|
||||
The value is used for substitution in the server's URL template.
|
||||
"""
|
||||
|
||||
if PYDANTIC_V2:
|
||||
model_config = ConfigDict(
|
||||
extra="allow",
|
||||
json_schema_extra={"examples": _examples},
|
||||
)
|
||||
|
||||
else:
|
||||
|
||||
class Config:
|
||||
extra = Extra.allow
|
||||
schema_extra = {"examples": _examples}
|
42
openapi_pydantic/v3/v3_0/server_variable.py
Normal file
42
openapi_pydantic/v3/v3_0/server_variable.py
Normal file
|
@ -0,0 +1,42 @@
|
|||
from typing import List, Optional
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
from openapi_pydantic.compat import PYDANTIC_V2, ConfigDict, Extra
|
||||
|
||||
|
||||
class ServerVariable(BaseModel):
|
||||
"""An object representing a Server Variable for server URL template substitution."""
|
||||
|
||||
enum: Optional[List[str]] = None
|
||||
"""
|
||||
An enumeration of string values to be used if the substitution options are from a
|
||||
limited set. The array SHOULD NOT be empty.
|
||||
"""
|
||||
|
||||
default: str
|
||||
"""
|
||||
**REQUIRED**. The default value to use for substitution,
|
||||
which SHALL be sent if an alternate value is _not_ supplied.
|
||||
Note this behavior is different than the [Schema Object's](#schemaObject) treatment
|
||||
of default values, because in those cases parameter values are optional.
|
||||
If the [`enum`](#serverVariableEnum) is defined, the value SHOULD exist in the
|
||||
enum's values.
|
||||
"""
|
||||
|
||||
description: Optional[str] = None
|
||||
"""
|
||||
An optional description for the server variable.
|
||||
[CommonMark syntax](https://spec.commonmark.org/) MAY be used for rich text
|
||||
representation.
|
||||
"""
|
||||
|
||||
if PYDANTIC_V2:
|
||||
model_config = ConfigDict(
|
||||
extra="allow",
|
||||
)
|
||||
|
||||
else:
|
||||
|
||||
class Config:
|
||||
extra = Extra.allow
|
47
openapi_pydantic/v3/v3_0/tag.py
Normal file
47
openapi_pydantic/v3/v3_0/tag.py
Normal file
|
@ -0,0 +1,47 @@
|
|||
from typing import Optional
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
from openapi_pydantic.compat import PYDANTIC_V2, ConfigDict, Extra
|
||||
|
||||
from .external_documentation import ExternalDocumentation
|
||||
|
||||
_examples = [{"name": "pet", "description": "Pets operations"}]
|
||||
|
||||
|
||||
class Tag(BaseModel):
|
||||
"""
|
||||
Adds metadata to a single tag that is used by the
|
||||
[Operation Object](#operationObject).
|
||||
It is not mandatory to have a Tag Object per tag defined in the Operation Object
|
||||
instances.
|
||||
"""
|
||||
|
||||
name: str
|
||||
"""
|
||||
**REQUIRED**. The name of the tag.
|
||||
"""
|
||||
|
||||
description: Optional[str] = None
|
||||
"""
|
||||
A short description for the tag.
|
||||
[CommonMark syntax](https://spec.commonmark.org/) MAY be used for rich text
|
||||
representation.
|
||||
"""
|
||||
|
||||
externalDocs: Optional[ExternalDocumentation] = None
|
||||
"""
|
||||
Additional external documentation for this tag.
|
||||
"""
|
||||
|
||||
if PYDANTIC_V2:
|
||||
model_config = ConfigDict(
|
||||
extra="allow",
|
||||
json_schema_extra={"examples": _examples},
|
||||
)
|
||||
|
||||
else:
|
||||
|
||||
class Config:
|
||||
extra = Extra.allow
|
||||
schema_extra = {"examples": _examples}
|
260
openapi_pydantic/v3/v3_0/util.py
Normal file
260
openapi_pydantic/v3/v3_0/util.py
Normal file
|
@ -0,0 +1,260 @@
|
|||
import logging
|
||||
import re
|
||||
from typing import (
|
||||
TYPE_CHECKING,
|
||||
Any,
|
||||
Dict,
|
||||
Generic,
|
||||
List,
|
||||
Optional,
|
||||
Set,
|
||||
Type,
|
||||
TypeVar,
|
||||
Union,
|
||||
cast,
|
||||
)
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
from openapi_pydantic.compat import (
|
||||
DEFS_KEY,
|
||||
PYDANTIC_V2,
|
||||
JsonSchemaMode,
|
||||
models_json_schema,
|
||||
v1_schema,
|
||||
)
|
||||
|
||||
from . import Components, OpenAPI, Reference, Schema, schema_validate
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
PydanticType = TypeVar("PydanticType", bound=BaseModel)
|
||||
ref_prefix = "#/components/schemas/"
|
||||
ref_template = "#/components/schemas/{model}"
|
||||
|
||||
|
||||
class PydanticSchema(Schema, Generic[PydanticType]):
|
||||
"""Special `Schema` class to indicate a reference from pydantic class"""
|
||||
|
||||
schema_class: Type[PydanticType]
|
||||
"""the class that is used for generate the schema"""
|
||||
|
||||
|
||||
def get_mode(
|
||||
cls: Type[BaseModel], default: JsonSchemaMode = "validation"
|
||||
) -> JsonSchemaMode:
|
||||
"""Get the JSON schema mode for a model class.
|
||||
|
||||
The mode can be either "validation" or "serialization". In validation mode,
|
||||
computed fields are dropped and optional fields remain optional. In
|
||||
serialization mode, computed and optional fields are required.
|
||||
"""
|
||||
if not hasattr(cls, "model_config"):
|
||||
return default
|
||||
mode = cls.model_config.get("json_schema_mode", default)
|
||||
if mode not in ("validation", "serialization"):
|
||||
raise ValueError(f"invalid json_schema_mode: {mode}")
|
||||
return cast(JsonSchemaMode, mode)
|
||||
|
||||
|
||||
if TYPE_CHECKING:
|
||||
|
||||
class GenerateOpenAPI30Schema: ...
|
||||
|
||||
elif PYDANTIC_V2:
|
||||
from enum import Enum
|
||||
|
||||
from pydantic.json_schema import GenerateJsonSchema, JsonSchemaValue
|
||||
from pydantic_core import core_schema
|
||||
|
||||
class GenerateOpenAPI30Schema(GenerateJsonSchema):
|
||||
"""Modify the schema generation for OpenAPI 3.0."""
|
||||
|
||||
def nullable_schema(
|
||||
self,
|
||||
schema: core_schema.NullableSchema,
|
||||
) -> JsonSchemaValue:
|
||||
"""Generates a JSON schema that matches a schema that allows null values.
|
||||
|
||||
In OpenAPI 3.0, types can not be None, but a special "nullable" field is
|
||||
available.
|
||||
"""
|
||||
inner_json_schema = self.generate_inner(schema["schema"])
|
||||
inner_json_schema["nullable"] = True
|
||||
return inner_json_schema
|
||||
|
||||
def literal_schema(self, schema: core_schema.LiteralSchema) -> JsonSchemaValue:
|
||||
"""Generates a JSON schema that matches a literal value.
|
||||
|
||||
In OpenAPI 3.0, the "const" keyword is not supported, so this
|
||||
version of this method skips that optimization.
|
||||
"""
|
||||
expected = [
|
||||
v.value if isinstance(v, Enum) else v for v in schema["expected"]
|
||||
]
|
||||
|
||||
types = {type(e) for e in expected}
|
||||
if types == {str}:
|
||||
return {"enum": expected, "type": "string"}
|
||||
elif types == {int}:
|
||||
return {"enum": expected, "type": "integer"}
|
||||
elif types == {float}:
|
||||
return {"enum": expected, "type": "number"}
|
||||
elif types == {bool}:
|
||||
return {"enum": expected, "type": "boolean"}
|
||||
elif types == {list}:
|
||||
return {"enum": expected, "type": "array"}
|
||||
# there is not None case because if it's mixed it hits the final `else`
|
||||
# if it's a single Literal[None] then it becomes a `const` schema above
|
||||
else:
|
||||
return {"enum": expected}
|
||||
|
||||
else:
|
||||
|
||||
class GenerateOpenAPI30Schema: ...
|
||||
|
||||
|
||||
def construct_open_api_with_schema_class(
|
||||
open_api: OpenAPI,
|
||||
schema_classes: Optional[List[Type[BaseModel]]] = None,
|
||||
scan_for_pydantic_schema_reference: bool = True,
|
||||
by_alias: bool = True,
|
||||
) -> OpenAPI:
|
||||
"""
|
||||
Construct a new OpenAPI object, utilising pydantic classes to produce JSON schemas.
|
||||
|
||||
:param open_api: the base `OpenAPI` object
|
||||
:param schema_classes: Pydantic classes that their schema will be used
|
||||
"#/components/schemas" values
|
||||
:param scan_for_pydantic_schema_reference: flag to indicate if scanning for
|
||||
`PydanticSchemaReference` class
|
||||
is needed for "#/components/schemas"
|
||||
value updates
|
||||
:param by_alias: construct schema by alias (default is True)
|
||||
:return: new OpenAPI object with "#/components/schemas" values updated.
|
||||
If there is no update in "#/components/schemas" values, the original
|
||||
`open_api` will be returned.
|
||||
"""
|
||||
copy_func = getattr(open_api, "model_copy" if PYDANTIC_V2 else "copy")
|
||||
new_open_api: OpenAPI = copy_func(deep=True)
|
||||
|
||||
if scan_for_pydantic_schema_reference:
|
||||
extracted_schema_classes = _handle_pydantic_schema(new_open_api)
|
||||
if schema_classes:
|
||||
schema_classes = list({*schema_classes, *extracted_schema_classes})
|
||||
else:
|
||||
schema_classes = extracted_schema_classes
|
||||
|
||||
if not schema_classes:
|
||||
return open_api
|
||||
|
||||
schema_classes.sort(key=lambda x: x.__name__)
|
||||
logger.debug("schema_classes: %s", schema_classes)
|
||||
|
||||
# update new_open_api with new #/components/schemas
|
||||
if PYDANTIC_V2:
|
||||
_key_map, schema_definitions = models_json_schema(
|
||||
[(c, get_mode(c)) for c in schema_classes],
|
||||
by_alias=by_alias,
|
||||
ref_template=ref_template,
|
||||
schema_generator=GenerateOpenAPI30Schema,
|
||||
)
|
||||
else:
|
||||
schema_definitions = v1_schema(
|
||||
schema_classes, by_alias=by_alias, ref_prefix=ref_prefix
|
||||
)
|
||||
|
||||
if not new_open_api.components:
|
||||
new_open_api.components = Components()
|
||||
if new_open_api.components.schemas:
|
||||
for existing_key in new_open_api.components.schemas:
|
||||
if existing_key in schema_definitions[DEFS_KEY]:
|
||||
logger.warning(
|
||||
f'"{existing_key}" already exists in {ref_prefix}. '
|
||||
f'The value of "{ref_prefix}{existing_key}" will be overwritten.'
|
||||
)
|
||||
new_open_api.components.schemas.update(_validate_schemas(schema_definitions))
|
||||
else:
|
||||
new_open_api.components.schemas = _validate_schemas(schema_definitions)
|
||||
return new_open_api
|
||||
|
||||
|
||||
def _validate_schemas(
|
||||
schema_definitions: Dict[str, Any]
|
||||
) -> Dict[str, Union[Reference, Schema]]:
|
||||
"""Convert JSON Schema definitions to parsed OpenAPI objects"""
|
||||
# Note: if an error occurs in schema_validate(), it may indicate that
|
||||
# the generated JSON schemas are not compatible with the version
|
||||
# of OpenAPI this module depends on.
|
||||
return {
|
||||
key: schema_validate(schema_dict)
|
||||
for key, schema_dict in schema_definitions[DEFS_KEY].items()
|
||||
}
|
||||
|
||||
|
||||
def _handle_pydantic_schema(open_api: OpenAPI) -> List[Type[BaseModel]]:
|
||||
"""
|
||||
This function traverses the `OpenAPI` object and
|
||||
|
||||
1. Replaces the `PydanticSchema` object with `Reference` object, with correct ref
|
||||
value;
|
||||
2. Extracts the involved schema class from `PydanticSchema` object.
|
||||
|
||||
**This function will mutate the input `OpenAPI` object.**
|
||||
|
||||
:param open_api: the `OpenAPI` object to be traversed and mutated
|
||||
:return: a list of schema classes extracted from `PydanticSchema` objects
|
||||
"""
|
||||
|
||||
pydantic_types: Set[Type[BaseModel]] = set()
|
||||
|
||||
def _traverse(obj: Any) -> None:
|
||||
if isinstance(obj, BaseModel):
|
||||
fields = getattr(
|
||||
obj, "model_fields_set" if PYDANTIC_V2 else "__fields_set__"
|
||||
)
|
||||
for field in fields:
|
||||
child_obj = obj.__getattribute__(field)
|
||||
if isinstance(child_obj, PydanticSchema):
|
||||
logger.debug("PydanticSchema found in %s: %s", obj, child_obj)
|
||||
obj.__setattr__(field, _construct_ref_obj(child_obj))
|
||||
pydantic_types.add(child_obj.schema_class)
|
||||
else:
|
||||
_traverse(child_obj)
|
||||
elif isinstance(obj, list):
|
||||
for index, elem in enumerate(obj):
|
||||
if isinstance(elem, PydanticSchema):
|
||||
logger.debug(f"PydanticSchema found in list: {elem}")
|
||||
obj[index] = _construct_ref_obj(elem)
|
||||
pydantic_types.add(elem.schema_class)
|
||||
else:
|
||||
_traverse(elem)
|
||||
elif isinstance(obj, dict):
|
||||
for key, value in obj.items():
|
||||
if isinstance(value, PydanticSchema):
|
||||
logger.debug(f"PydanticSchema found in dict: {value}")
|
||||
obj[key] = _construct_ref_obj(value)
|
||||
pydantic_types.add(value.schema_class)
|
||||
else:
|
||||
_traverse(value)
|
||||
|
||||
_traverse(open_api)
|
||||
return list(pydantic_types)
|
||||
|
||||
|
||||
def _construct_ref_obj(pydantic_schema: PydanticSchema[PydanticType]) -> Reference:
|
||||
"""
|
||||
Construct a reference object from the Pydantic schema name
|
||||
|
||||
characters in the schema name that are invalid/problematic
|
||||
for JSONschema $ref names will get replaced with underscores.
|
||||
Especially needed for Pydantic generic Models with brackets "[]"
|
||||
|
||||
see: https://github.com/pydantic/pydantic/blob/aee6057378ccfec02126bf9c984a9b6d6b411777/pydantic/json_schema.py#L2031
|
||||
"""
|
||||
ref_name = re.sub(
|
||||
r"[^a-zA-Z0-9.\-_]", "_", pydantic_schema.schema_class.__name__
|
||||
).replace(".", "__")
|
||||
ref_obj = Reference(**{"$ref": ref_prefix + ref_name})
|
||||
logger.debug(f"ref_obj={ref_obj}")
|
||||
return ref_obj
|
68
openapi_pydantic/v3/v3_0/xml.py
Normal file
68
openapi_pydantic/v3/v3_0/xml.py
Normal file
|
@ -0,0 +1,68 @@
|
|||
from typing import Optional
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
from openapi_pydantic.compat import PYDANTIC_V2, ConfigDict, Extra
|
||||
|
||||
_examples = [
|
||||
{"namespace": "http://example.com/schema/sample", "prefix": "sample"},
|
||||
{"name": "aliens", "wrapped": True},
|
||||
]
|
||||
|
||||
|
||||
class XML(BaseModel):
|
||||
"""
|
||||
A metadata object that allows for more fine-tuned XML model definitions.
|
||||
|
||||
When using arrays, XML element names are *not* inferred (for singular/plural forms)
|
||||
and the `name` property SHOULD be used to add that information.
|
||||
See examples for expected behavior.
|
||||
"""
|
||||
|
||||
name: Optional[str] = None
|
||||
"""
|
||||
Replaces the name of the element/attribute used for the described schema property.
|
||||
When defined within `items`, it will affect the name of the individual XML elements
|
||||
within the list. When defined alongside `type` being `array` (outside the `items`),
|
||||
it will affect the wrapping element and only if `wrapped` is `true`.
|
||||
If `wrapped` is `false`, it will be ignored.
|
||||
"""
|
||||
|
||||
namespace: Optional[str] = None
|
||||
"""
|
||||
The URI of the namespace definition.
|
||||
Value MUST be in the form of an absolute URI.
|
||||
"""
|
||||
|
||||
prefix: Optional[str] = None
|
||||
"""
|
||||
The prefix to be used for the [name](#xmlName).
|
||||
"""
|
||||
|
||||
attribute: bool = False
|
||||
"""
|
||||
Declares whether the property definition translates to an attribute instead of an
|
||||
element. Default value is `false`.
|
||||
"""
|
||||
|
||||
wrapped: bool = False
|
||||
"""
|
||||
MAY be used only for an array definition.
|
||||
Signifies whether the array is wrapped (for example,
|
||||
`<books><book/><book/></books>`) or unwrapped (`<book/><book/>`).
|
||||
Default value is `false`.
|
||||
The definition takes effect only when defined alongside `type` being `array`
|
||||
(outside the `items`).
|
||||
"""
|
||||
|
||||
if PYDANTIC_V2:
|
||||
model_config = ConfigDict(
|
||||
extra="allow",
|
||||
json_schema_extra={"examples": _examples},
|
||||
)
|
||||
|
||||
else:
|
||||
|
||||
class Config:
|
||||
extra = Extra.allow
|
||||
schema_extra = {"examples": _examples}
|
41
openapi_pydantic/v3/v3_1/README.md
Normal file
41
openapi_pydantic/v3/v3_1/README.md
Normal file
|
@ -0,0 +1,41 @@
|
|||
# OpenAPI v3.1 schema classes
|
||||
|
||||
## Alias
|
||||
|
||||
Due to the reserved words in python and pydantic,
|
||||
the following fields are used with [alias](https://pydantic-docs.helpmanual.io/usage/schema/#field-customisation) feature provided by pydantic:
|
||||
|
||||
| Class | Field name in the class | Alias (as in OpenAPI spec) |
|
||||
| ----- | ----------------------- | -------------------------- |
|
||||
| Header[*](#header_param_in) | param_in | in |
|
||||
| MediaType | media_type_schema | schema |
|
||||
| Parameter | param_in | in |
|
||||
| Parameter | param_schema | schema |
|
||||
| PathItem | ref | $ref |
|
||||
| Reference | ref | $ref |
|
||||
| SecurityScheme | security_scheme_in | in |
|
||||
| Schema | schema_format | format |
|
||||
| Schema | schema_not | not |
|
||||
| Schema | schema_if | if |
|
||||
| Schema | schema_else | else |
|
||||
|
||||
> <a name="header_param_in"></a>The "in" field in Header object is actually a constant (`{"in": "header"}`).
|
||||
|
||||
> For convenience of object creation, the classes mentioned in above
|
||||
> have configured `allow_population_by_field_name=True` (Pydantic V1) or `populate_by_name=True` (Pydantic V2).
|
||||
>
|
||||
> Reference: [Pydantic's Model Config](https://pydantic-docs.helpmanual.io/usage/model_config/)
|
||||
|
||||
## Non-pydantic schema types
|
||||
|
||||
Due to the constriants of python typing structure (not able to handle dynamic field names),
|
||||
the following schema classes are actually just a typing of `Dict`:
|
||||
|
||||
| Schema Type | Implementation |
|
||||
| ----------- | -------------- |
|
||||
| Callback | `Callback = Dict[str, PathItem]` |
|
||||
| Paths | `Paths = Dict[str, PathItem]` |
|
||||
| Responses | `Responses = Dict[str, Union[Response, Reference]]` |
|
||||
| SecurityRequirement | `SecurityRequirement = Dict[str, List[str]]` |
|
||||
|
||||
On creating such schema instances, please use python's `dict` type instead to instantiate.
|
59
openapi_pydantic/v3/v3_1/__init__.py
Normal file
59
openapi_pydantic/v3/v3_1/__init__.py
Normal file
|
@ -0,0 +1,59 @@
|
|||
"""
|
||||
OpenAPI v3.1 schema types, created according to the specification:
|
||||
https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.1.md
|
||||
|
||||
The type orders are according to the contents of the specification:
|
||||
https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.1.md#table-of-contents
|
||||
"""
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from openapi_pydantic.compat import PYDANTIC_V2
|
||||
|
||||
from .callback import Callback as Callback
|
||||
from .components import Components as Components
|
||||
from .contact import Contact as Contact
|
||||
from .datatype import DataType as DataType
|
||||
from .discriminator import Discriminator as Discriminator
|
||||
from .encoding import Encoding as Encoding
|
||||
from .example import Example as Example
|
||||
from .external_documentation import ExternalDocumentation as ExternalDocumentation
|
||||
from .header import Header as Header
|
||||
from .info import Info as Info
|
||||
from .license import License as License
|
||||
from .link import Link as Link
|
||||
from .media_type import MediaType as MediaType
|
||||
from .oauth_flow import OAuthFlow as OAuthFlow
|
||||
from .oauth_flows import OAuthFlows as OAuthFlows
|
||||
from .open_api import OpenAPI as OpenAPI
|
||||
from .operation import Operation as Operation
|
||||
from .parameter import Parameter as Parameter
|
||||
from .parameter import ParameterLocation as ParameterLocation
|
||||
from .path_item import PathItem as PathItem
|
||||
from .paths import Paths as Paths
|
||||
from .reference import Reference as Reference
|
||||
from .request_body import RequestBody as RequestBody
|
||||
from .response import Response as Response
|
||||
from .responses import Responses as Responses
|
||||
from .schema import Schema as Schema
|
||||
from .schema import schema_validate as schema_validate
|
||||
from .security_requirement import SecurityRequirement as SecurityRequirement
|
||||
from .security_scheme import SecurityScheme as SecurityScheme
|
||||
from .server import Server as Server
|
||||
from .server_variable import ServerVariable as ServerVariable
|
||||
from .tag import Tag as Tag
|
||||
from .xml import XML as XML
|
||||
|
||||
if TYPE_CHECKING:
|
||||
pass
|
||||
elif PYDANTIC_V2:
|
||||
# resolve forward references
|
||||
Encoding.model_rebuild()
|
||||
OpenAPI.model_rebuild()
|
||||
Components.model_rebuild()
|
||||
Operation.model_rebuild()
|
||||
else:
|
||||
# resolve forward references
|
||||
Encoding.update_forward_refs(Header=Header)
|
||||
Schema.update_forward_refs()
|
||||
Operation.update_forward_refs(PathItem=PathItem)
|
26
openapi_pydantic/v3/v3_1/callback.py
Normal file
26
openapi_pydantic/v3/v3_1/callback.py
Normal file
|
@ -0,0 +1,26 @@
|
|||
from typing import TYPE_CHECKING, Dict, Union
|
||||
|
||||
from .reference import Reference
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from .path_item import PathItem
|
||||
|
||||
|
||||
Callback = Dict[str, Union["PathItem", Reference]]
|
||||
"""
|
||||
A map of possible out-of band callbacks related to the parent operation.
|
||||
Each value in the map is a [Path Item Object](#pathItemObject)
|
||||
that describes a set of requests that may be initiated by the API provider and the
|
||||
expected responses. The key value used to identify the path item object is an
|
||||
expression, evaluated at runtime, that identifies a URL to use for the callback
|
||||
operation.
|
||||
"""
|
||||
|
||||
"""Patterned Fields"""
|
||||
|
||||
# {expression}: 'PathItem' = ...
|
||||
"""
|
||||
A Path Item Object used to define a callback request and expected responses.
|
||||
|
||||
A [complete example](../examples/v3.0/callback-example.yaml) is available.
|
||||
"""
|
142
openapi_pydantic/v3/v3_1/components.py
Normal file
142
openapi_pydantic/v3/v3_1/components.py
Normal file
|
@ -0,0 +1,142 @@
|
|||
from typing import Dict, Optional, Union
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
from openapi_pydantic.compat import PYDANTIC_V2, ConfigDict, Extra
|
||||
|
||||
from .callback import Callback
|
||||
from .example import Example
|
||||
from .header import Header
|
||||
from .link import Link
|
||||
from .parameter import Parameter
|
||||
from .path_item import PathItem
|
||||
from .reference import Reference
|
||||
from .request_body import RequestBody
|
||||
from .response import Response
|
||||
from .schema import Schema
|
||||
from .security_scheme import SecurityScheme
|
||||
|
||||
_examples = [
|
||||
{
|
||||
"schemas": {
|
||||
"GeneralError": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"code": {"type": "integer", "format": "int32"},
|
||||
"message": {"type": "string"},
|
||||
},
|
||||
},
|
||||
"Category": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {"type": "integer", "format": "int64"},
|
||||
"name": {"type": "string"},
|
||||
},
|
||||
},
|
||||
"Tag": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {"type": "integer", "format": "int64"},
|
||||
"name": {"type": "string"},
|
||||
},
|
||||
},
|
||||
},
|
||||
"parameters": {
|
||||
"skipParam": {
|
||||
"name": "skip",
|
||||
"in": "query",
|
||||
"description": "number of items to skip",
|
||||
"required": True,
|
||||
"schema": {"type": "integer", "format": "int32"},
|
||||
},
|
||||
"limitParam": {
|
||||
"name": "limit",
|
||||
"in": "query",
|
||||
"description": "max records to return",
|
||||
"required": True,
|
||||
"schema": {"type": "integer", "format": "int32"},
|
||||
},
|
||||
},
|
||||
"responses": {
|
||||
"NotFound": {"description": "Entity not found."},
|
||||
"IllegalInput": {"description": "Illegal input for operation."},
|
||||
"GeneralError": {
|
||||
"description": "General Error",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {"$ref": "#/components/schemas/GeneralError"}
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
"securitySchemes": {
|
||||
"api_key": {
|
||||
"type": "apiKey",
|
||||
"name": "api_key",
|
||||
"in": "header",
|
||||
},
|
||||
"petstore_auth": {
|
||||
"type": "oauth2",
|
||||
"flows": {
|
||||
"implicit": {
|
||||
"authorizationUrl": "http://example.org/api/oauth/dialog",
|
||||
"scopes": {
|
||||
"write:pets": "modify pets in your account",
|
||||
"read:pets": "read your pets",
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
class Components(BaseModel):
|
||||
"""
|
||||
Holds a set of reusable objects for different aspects of the OAS.
|
||||
All objects defined within the components object will have no effect on the API
|
||||
unless they are explicitly referenced from properties outside the components object.
|
||||
"""
|
||||
|
||||
schemas: Optional[Dict[str, Schema]] = None
|
||||
"""An object to hold reusable [Schema Objects](#schemaObject)."""
|
||||
|
||||
responses: Optional[Dict[str, Union[Response, Reference]]] = None
|
||||
"""An object to hold reusable [Response Objects](#responseObject)."""
|
||||
|
||||
parameters: Optional[Dict[str, Union[Parameter, Reference]]] = None
|
||||
"""An object to hold reusable [Parameter Objects](#parameterObject)."""
|
||||
|
||||
examples: Optional[Dict[str, Union[Example, Reference]]] = None
|
||||
"""An object to hold reusable [Example Objects](#exampleObject)."""
|
||||
|
||||
requestBodies: Optional[Dict[str, Union[RequestBody, Reference]]] = None
|
||||
"""An object to hold reusable [Request Body Objects](#requestBodyObject)."""
|
||||
|
||||
headers: Optional[Dict[str, Union[Header, Reference]]] = None
|
||||
"""An object to hold reusable [Header Objects](#headerObject)."""
|
||||
|
||||
securitySchemes: Optional[Dict[str, Union[SecurityScheme, Reference]]] = None
|
||||
"""An object to hold reusable [Security Scheme Objects](#securitySchemeObject)."""
|
||||
|
||||
links: Optional[Dict[str, Union[Link, Reference]]] = None
|
||||
"""An object to hold reusable [Link Objects](#linkObject)."""
|
||||
|
||||
callbacks: Optional[Dict[str, Union[Callback, Reference]]] = None
|
||||
"""An object to hold reusable [Callback Objects](#callbackObject)."""
|
||||
|
||||
pathItems: Optional[Dict[str, Union[PathItem, Reference]]] = None
|
||||
"""An object to hold reusable [Path Item Object](#pathItemObject)."""
|
||||
|
||||
if PYDANTIC_V2:
|
||||
model_config = ConfigDict(
|
||||
extra="allow",
|
||||
json_schema_extra={"examples": _examples},
|
||||
)
|
||||
|
||||
else:
|
||||
|
||||
class Config:
|
||||
extra = Extra.allow
|
||||
schema_extra = {"examples": _examples}
|
48
openapi_pydantic/v3/v3_1/contact.py
Normal file
48
openapi_pydantic/v3/v3_1/contact.py
Normal file
|
@ -0,0 +1,48 @@
|
|||
from typing import Optional
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
from openapi_pydantic.compat import PYDANTIC_V2, ConfigDict, Extra
|
||||
|
||||
_examples = [
|
||||
{
|
||||
"name": "API Support",
|
||||
"url": "http://www.example.com/support",
|
||||
"email": "support@example.com",
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
class Contact(BaseModel):
|
||||
"""
|
||||
Contact information for the exposed API.
|
||||
"""
|
||||
|
||||
name: Optional[str] = None
|
||||
"""
|
||||
The identifying name of the contact person/organization.
|
||||
"""
|
||||
|
||||
url: Optional[str] = None
|
||||
"""
|
||||
The URL pointing to the contact information.
|
||||
MUST be in the form of a URL.
|
||||
"""
|
||||
|
||||
email: Optional[str] = None
|
||||
"""
|
||||
The email address of the contact person/organization.
|
||||
MUST be in the form of an email address.
|
||||
"""
|
||||
|
||||
if PYDANTIC_V2:
|
||||
model_config = ConfigDict(
|
||||
extra="allow",
|
||||
json_schema_extra={"examples": _examples},
|
||||
)
|
||||
|
||||
else:
|
||||
|
||||
class Config:
|
||||
extra = Extra.allow
|
||||
schema_extra = {"examples": _examples}
|
13
openapi_pydantic/v3/v3_1/datatype.py
Normal file
13
openapi_pydantic/v3/v3_1/datatype.py
Normal file
|
@ -0,0 +1,13 @@
|
|||
from enum import Enum
|
||||
|
||||
|
||||
class DataType(str, Enum):
|
||||
"""Data type of an object."""
|
||||
|
||||
NULL = "null"
|
||||
STRING = "string"
|
||||
NUMBER = "number"
|
||||
INTEGER = "integer"
|
||||
BOOLEAN = "boolean"
|
||||
ARRAY = "array"
|
||||
OBJECT = "object"
|
52
openapi_pydantic/v3/v3_1/discriminator.py
Normal file
52
openapi_pydantic/v3/v3_1/discriminator.py
Normal file
|
@ -0,0 +1,52 @@
|
|||
from typing import Dict, Optional
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
from openapi_pydantic.compat import PYDANTIC_V2, ConfigDict, Extra
|
||||
|
||||
_examples = [
|
||||
{
|
||||
"propertyName": "petType",
|
||||
"mapping": {
|
||||
"dog": "#/components/schemas/Dog",
|
||||
"monster": "https://gigantic-server.com/schemas/Monster/schema.json",
|
||||
},
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
class Discriminator(BaseModel):
|
||||
"""
|
||||
When request bodies or response payloads may be one of a number of different
|
||||
schemas, a `discriminator` object can be used to aid in serialization,
|
||||
deserialization, and validation.
|
||||
|
||||
The discriminator is a specific object in a schema which is used to inform the
|
||||
consumer of the specification of an alternative schema based on the value
|
||||
associated with it.
|
||||
|
||||
When using the discriminator, _inline_ schemas will not be considered.
|
||||
"""
|
||||
|
||||
propertyName: str
|
||||
"""
|
||||
**REQUIRED**. The name of the property in the payload that will hold the
|
||||
discriminator value.
|
||||
"""
|
||||
|
||||
mapping: Optional[Dict[str, str]] = None
|
||||
"""
|
||||
An object to hold mappings between payload values and schema names or references.
|
||||
"""
|
||||
|
||||
if PYDANTIC_V2:
|
||||
model_config = ConfigDict(
|
||||
extra="allow",
|
||||
json_schema_extra={"examples": _examples},
|
||||
)
|
||||
|
||||
else:
|
||||
|
||||
class Config:
|
||||
extra = Extra.allow
|
||||
schema_extra = {"examples": _examples}
|
101
openapi_pydantic/v3/v3_1/encoding.py
Normal file
101
openapi_pydantic/v3/v3_1/encoding.py
Normal file
|
@ -0,0 +1,101 @@
|
|||
from typing import TYPE_CHECKING, Dict, Optional, Union
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
from openapi_pydantic.compat import PYDANTIC_V2, ConfigDict, Extra
|
||||
|
||||
from .reference import Reference
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from .header import Header
|
||||
|
||||
_examples = [
|
||||
{
|
||||
"contentType": "image/png, image/jpeg",
|
||||
"headers": {
|
||||
"X-Rate-Limit-Limit": {
|
||||
"description": "The number of allowed requests in the "
|
||||
"current period",
|
||||
"schema": {"type": "integer"},
|
||||
}
|
||||
},
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
class Encoding(BaseModel):
|
||||
"""A single encoding definition applied to a single schema property."""
|
||||
|
||||
contentType: Optional[str] = None
|
||||
"""
|
||||
The Content-Type for encoding a specific property.
|
||||
Default value depends on the property type:
|
||||
|
||||
for `object` - `application/json`;
|
||||
for `array` – the default is defined based on the inner type;
|
||||
for all other cases the default is `application/octet-stream`.
|
||||
|
||||
The value can be a specific media type (e.g. `application/json`), a wildcard media
|
||||
type (e.g. `image/*`), or a comma-separated list of the two types.
|
||||
"""
|
||||
|
||||
headers: Optional[Dict[str, Union["Header", Reference]]] = None
|
||||
"""
|
||||
A map allowing additional information to be provided as headers, for example
|
||||
`Content-Disposition`.
|
||||
|
||||
`Content-Type` is described separately and SHALL be ignored in this section.
|
||||
This property SHALL be ignored if the request body media type is not a `multipart`.
|
||||
"""
|
||||
|
||||
style: Optional[str] = None
|
||||
"""
|
||||
Describes how a specific property value will be serialized depending on its type.
|
||||
|
||||
See [Parameter Object](#parameterObject) for details on the
|
||||
[`style`](#parameterStyle) property. The behavior follows the same values as
|
||||
`query` parameters, including default values.
|
||||
This property SHALL be ignored if the request body media type
|
||||
is not `application/x-www-form-urlencoded` or `multipart/form-data`.
|
||||
If a value is explicitly defined, then the value of
|
||||
[`contentType`](#encodingContentType) (implicit or explicit) SHALL be ignored.
|
||||
"""
|
||||
|
||||
explode: Optional[bool] = None
|
||||
"""
|
||||
When this is true, property values of type `array` or `object` generate separate
|
||||
parameters for each value of the array, or key-value-pair of the map.
|
||||
|
||||
For other types of properties this property has no effect.
|
||||
When [`style`](#encodingStyle) is `form`, the default value is `true`.
|
||||
For all other styles, the default value is `false`.
|
||||
This property SHALL be ignored if the request body media type
|
||||
is not `application/x-www-form-urlencoded` or `multipart/form-data`.
|
||||
If a value is explicitly defined, then the value of
|
||||
[`contentType`](#encodingContentType) (implicit or explicit) SHALL be ignored.
|
||||
"""
|
||||
|
||||
allowReserved: bool = False
|
||||
"""
|
||||
Determines whether the parameter value SHOULD allow reserved characters,
|
||||
as defined by [RFC3986](https://tools.ietf.org/html/rfc3986#section-2.2)
|
||||
`:/?#[]@!$&'()*+,;=` to be included without percent-encoding.
|
||||
The default value is `false`.
|
||||
This property SHALL be ignored if the request body media type
|
||||
is not `application/x-www-form-urlencoded` or `multipart/form-data`.
|
||||
If a value is explicitly defined,
|
||||
then the value of [`contentType`](#encodingContentType) (implicit or explicit)
|
||||
SHALL be ignored.
|
||||
"""
|
||||
|
||||
if PYDANTIC_V2:
|
||||
model_config = ConfigDict(
|
||||
extra="allow",
|
||||
json_schema_extra={"examples": _examples},
|
||||
)
|
||||
|
||||
else:
|
||||
|
||||
class Config:
|
||||
extra = Extra.allow
|
||||
schema_extra = {"examples": _examples}
|
64
openapi_pydantic/v3/v3_1/example.py
Normal file
64
openapi_pydantic/v3/v3_1/example.py
Normal file
|
@ -0,0 +1,64 @@
|
|||
from typing import Any, Optional
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
from openapi_pydantic.compat import PYDANTIC_V2, ConfigDict, Extra
|
||||
|
||||
_examples = [
|
||||
{
|
||||
"summary": "A foo example",
|
||||
"value": {"foo": "bar"},
|
||||
},
|
||||
{
|
||||
"summary": "This is an example in XML",
|
||||
"externalValue": "http://example.org/examples/address-example.xml",
|
||||
},
|
||||
{
|
||||
"summary": "This is a text example",
|
||||
"externalValue": "http://foo.bar/examples/address-example.txt",
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
class Example(BaseModel):
|
||||
summary: Optional[str] = None
|
||||
"""
|
||||
Short description for the example.
|
||||
"""
|
||||
|
||||
description: Optional[str] = None
|
||||
"""
|
||||
Long description for the example.
|
||||
[CommonMark syntax](https://spec.commonmark.org/) MAY be used for rich text
|
||||
representation.
|
||||
"""
|
||||
|
||||
value: Optional[Any] = None
|
||||
"""
|
||||
Embedded literal example.
|
||||
The `value` field and `externalValue` field are mutually exclusive.
|
||||
To represent examples of media types that cannot naturally represented in JSON or
|
||||
YAML, use a string value to contain the example, escaping where necessary.
|
||||
"""
|
||||
|
||||
externalValue: Optional[str] = None
|
||||
"""
|
||||
A URL that points to the literal example.
|
||||
This provides the capability to reference examples that cannot easily be included
|
||||
in JSON or YAML documents.
|
||||
|
||||
The `value` field and `externalValue` field are mutually exclusive.
|
||||
See the rules for resolving [Relative References](#relativeReferencesURI).
|
||||
"""
|
||||
|
||||
if PYDANTIC_V2:
|
||||
model_config = ConfigDict(
|
||||
extra="allow",
|
||||
json_schema_extra={"examples": _examples},
|
||||
)
|
||||
|
||||
else:
|
||||
|
||||
class Config:
|
||||
extra = Extra.allow
|
||||
schema_extra = {"examples": _examples}
|
36
openapi_pydantic/v3/v3_1/external_documentation.py
Normal file
36
openapi_pydantic/v3/v3_1/external_documentation.py
Normal file
|
@ -0,0 +1,36 @@
|
|||
from typing import Optional
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
from openapi_pydantic.compat import PYDANTIC_V2, ConfigDict, Extra
|
||||
|
||||
_examples = [{"description": "Find more info here", "url": "https://example.com"}]
|
||||
|
||||
|
||||
class ExternalDocumentation(BaseModel):
|
||||
"""Allows referencing an external resource for extended documentation."""
|
||||
|
||||
description: Optional[str] = None
|
||||
"""
|
||||
A short description of the target documentation.
|
||||
[CommonMark syntax](https://spec.commonmark.org/) MAY be used for rich text
|
||||
representation.
|
||||
"""
|
||||
|
||||
url: str
|
||||
"""
|
||||
**REQUIRED**. The URL for the target documentation.
|
||||
Value MUST be in the form of a URL.
|
||||
"""
|
||||
|
||||
if PYDANTIC_V2:
|
||||
model_config = ConfigDict(
|
||||
extra="allow",
|
||||
json_schema_extra={"examples": _examples},
|
||||
)
|
||||
|
||||
else:
|
||||
|
||||
class Config:
|
||||
extra = Extra.allow
|
||||
schema_extra = {"examples": _examples}
|
37
openapi_pydantic/v3/v3_1/header.py
Normal file
37
openapi_pydantic/v3/v3_1/header.py
Normal file
|
@ -0,0 +1,37 @@
|
|||
from openapi_pydantic.compat import PYDANTIC_V2, ConfigDict, Extra
|
||||
|
||||
from .parameter import ParameterBase
|
||||
|
||||
_examples = [
|
||||
{
|
||||
"description": "The number of allowed requests in the current period",
|
||||
"schema": {"type": "integer"},
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
class Header(ParameterBase):
|
||||
"""
|
||||
The Header Object follows the structure of the
|
||||
[Parameter Object](#parameterObject) with the following changes:
|
||||
|
||||
1. `name` MUST NOT be specified, it is given in the corresponding
|
||||
`headers` map.
|
||||
2. `in` MUST NOT be specified, it is implicitly in `header`.
|
||||
3. All traits that are affected by the location MUST be applicable
|
||||
to a location of `header` (for example, [`style`](#parameterStyle)).
|
||||
"""
|
||||
|
||||
if PYDANTIC_V2:
|
||||
model_config = ConfigDict(
|
||||
extra="allow",
|
||||
populate_by_name=True,
|
||||
json_schema_extra={"examples": _examples},
|
||||
)
|
||||
|
||||
else:
|
||||
|
||||
class Config:
|
||||
extra = Extra.allow
|
||||
allow_population_by_field_name = True
|
||||
schema_extra = {"examples": _examples}
|
87
openapi_pydantic/v3/v3_1/info.py
Normal file
87
openapi_pydantic/v3/v3_1/info.py
Normal file
|
@ -0,0 +1,87 @@
|
|||
from typing import Optional
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
from openapi_pydantic.compat import PYDANTIC_V2, ConfigDict, Extra
|
||||
|
||||
from .contact import Contact
|
||||
from .license import License
|
||||
|
||||
_examples = [
|
||||
{
|
||||
"title": "Sample Pet Store App",
|
||||
"summary": "A pet store manager.",
|
||||
"description": "This is a sample server for a pet store.",
|
||||
"termsOfService": "http://example.com/terms/",
|
||||
"contact": {
|
||||
"name": "API Support",
|
||||
"url": "http://www.example.com/support",
|
||||
"email": "support@example.com",
|
||||
},
|
||||
"license": {
|
||||
"name": "Apache 2.0",
|
||||
"url": "https://www.apache.org/licenses/LICENSE-2.0.html",
|
||||
},
|
||||
"version": "1.0.1",
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
class Info(BaseModel):
|
||||
"""
|
||||
The object provides metadata about the API.
|
||||
The metadata MAY be used by the clients if needed,
|
||||
and MAY be presented in editing or documentation generation tools for convenience.
|
||||
"""
|
||||
|
||||
title: str
|
||||
"""
|
||||
**REQUIRED**. The title of the API.
|
||||
"""
|
||||
|
||||
summary: Optional[str] = None
|
||||
"""
|
||||
A short summary of the API.
|
||||
"""
|
||||
|
||||
description: Optional[str] = None
|
||||
"""
|
||||
A description of the API.
|
||||
[CommonMark syntax](https://spec.commonmark.org/) MAY be used for rich text
|
||||
representation.
|
||||
"""
|
||||
|
||||
termsOfService: Optional[str] = None
|
||||
"""
|
||||
A URL to the Terms of Service for the API.
|
||||
MUST be in the form of a URL.
|
||||
"""
|
||||
|
||||
contact: Optional[Contact] = None
|
||||
"""
|
||||
The contact information for the exposed API.
|
||||
"""
|
||||
|
||||
license: Optional[License] = None
|
||||
"""
|
||||
The license information for the exposed API.
|
||||
"""
|
||||
|
||||
version: str
|
||||
"""
|
||||
**REQUIRED**. The version of the OpenAPI document
|
||||
(which is distinct from the [OpenAPI Specification version](#oasVersion) or the API
|
||||
implementation version).
|
||||
"""
|
||||
|
||||
if PYDANTIC_V2:
|
||||
model_config = ConfigDict(
|
||||
extra="allow",
|
||||
json_schema_extra={"examples": _examples},
|
||||
)
|
||||
|
||||
else:
|
||||
|
||||
class Config:
|
||||
extra = Extra.allow
|
||||
schema_extra = {"examples": _examples}
|
50
openapi_pydantic/v3/v3_1/license.py
Normal file
50
openapi_pydantic/v3/v3_1/license.py
Normal file
|
@ -0,0 +1,50 @@
|
|||
from typing import Optional
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
from openapi_pydantic.compat import PYDANTIC_V2, ConfigDict, Extra
|
||||
|
||||
_examples = [
|
||||
{"name": "Apache 2.0", "identifier": "Apache-2.0"},
|
||||
{
|
||||
"name": "Apache 2.0",
|
||||
"url": "https://www.apache.org/licenses/LICENSE-2.0.html",
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
class License(BaseModel):
|
||||
"""
|
||||
License information for the exposed API.
|
||||
"""
|
||||
|
||||
name: str
|
||||
"""
|
||||
**REQUIRED**. The license name used for the API.
|
||||
"""
|
||||
|
||||
identifier: Optional[str] = None
|
||||
"""
|
||||
An [SPDX](https://spdx.org/spdx-specification-21-web-version#h.jxpfx0ykyb60)
|
||||
license expression for the API. The `identifier` field is mutually exclusive of the
|
||||
`url` field.
|
||||
"""
|
||||
|
||||
url: Optional[str] = None
|
||||
"""
|
||||
A URL to the license used for the API.
|
||||
This MUST be in the form of a URL.
|
||||
The `url` field is mutually exclusive of the `identifier` field.
|
||||
"""
|
||||
|
||||
if PYDANTIC_V2:
|
||||
model_config = ConfigDict(
|
||||
extra="allow",
|
||||
json_schema_extra={"examples": _examples},
|
||||
)
|
||||
|
||||
else:
|
||||
|
||||
class Config:
|
||||
extra = Extra.allow
|
||||
schema_extra = {"examples": _examples}
|
95
openapi_pydantic/v3/v3_1/link.py
Normal file
95
openapi_pydantic/v3/v3_1/link.py
Normal file
|
@ -0,0 +1,95 @@
|
|||
from typing import Any, Dict, Optional
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
from openapi_pydantic.compat import PYDANTIC_V2, ConfigDict, Extra
|
||||
|
||||
from .server import Server
|
||||
|
||||
_examples = [
|
||||
{
|
||||
"operationId": "getUserAddressByUUID",
|
||||
"parameters": {"userUuid": "$response.body#/uuid"},
|
||||
},
|
||||
{
|
||||
"operationRef": "#/paths/~12.0~1repositories~1{username}/get",
|
||||
"parameters": {"username": "$response.body#/username"},
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
class Link(BaseModel):
|
||||
"""
|
||||
The `Link object` represents a possible design-time link for a response.
|
||||
The presence of a link does not guarantee the caller's ability to successfully
|
||||
invoke it, rather it provides a known relationship and traversal mechanism between
|
||||
responses and other operations.
|
||||
|
||||
Unlike _dynamic_ links (i.e. links provided **in** the response payload),
|
||||
the OAS linking mechanism does not require link information in the runtime response.
|
||||
|
||||
For computing links, and providing instructions to execute them,
|
||||
a [runtime expression](#runtimeExpression) is used for accessing values in an
|
||||
operation and using them as parameters while invoking the linked operation.
|
||||
"""
|
||||
|
||||
operationRef: Optional[str] = None
|
||||
"""
|
||||
A relative or absolute URI reference to an OAS operation.
|
||||
This field is mutually exclusive of the `operationId` field,
|
||||
and MUST point to an [Operation Object](#operationObject).
|
||||
Relative `operationRef` values MAY be used to locate an existing
|
||||
[Operation Object](#operationObject) in the OpenAPI definition. See the rules for
|
||||
resolving [Relative References](#relativeReferencesURI).
|
||||
"""
|
||||
|
||||
operationId: Optional[str] = None
|
||||
"""
|
||||
The name of an _existing_, resolvable OAS operation, as defined with a unique
|
||||
`operationId`.
|
||||
|
||||
This field is mutually exclusive of the `operationRef` field.
|
||||
"""
|
||||
|
||||
parameters: Optional[Dict[str, Any]] = None
|
||||
"""
|
||||
A map representing parameters to pass to an operation
|
||||
as specified with `operationId` or identified via `operationRef`.
|
||||
The key is the parameter name to be used,
|
||||
whereas the value can be a constant or an expression to be evaluated and passed to
|
||||
the linked operation.
|
||||
|
||||
The parameter name can be qualified using the [parameter location](#parameterIn)
|
||||
`[{in}.]{name}` for operations that use the same parameter name in different
|
||||
locations (e.g. path.id).
|
||||
"""
|
||||
|
||||
requestBody: Optional[Any] = None
|
||||
"""
|
||||
A literal value or [{expression}](#runtimeExpression) to use as a request body when
|
||||
calling the target operation.
|
||||
"""
|
||||
|
||||
description: Optional[str] = None
|
||||
"""
|
||||
A description of the link.
|
||||
[CommonMark syntax](https://spec.commonmark.org/) MAY be used for rich text
|
||||
representation.
|
||||
"""
|
||||
|
||||
server: Optional[Server] = None
|
||||
"""
|
||||
A server object to be used by the target operation.
|
||||
"""
|
||||
|
||||
if PYDANTIC_V2:
|
||||
model_config = ConfigDict(
|
||||
extra="allow",
|
||||
json_schema_extra={"examples": _examples},
|
||||
)
|
||||
|
||||
else:
|
||||
|
||||
class Config:
|
||||
extra = Extra.allow
|
||||
schema_extra = {"examples": _examples}
|
97
openapi_pydantic/v3/v3_1/media_type.py
Normal file
97
openapi_pydantic/v3/v3_1/media_type.py
Normal file
|
@ -0,0 +1,97 @@
|
|||
from typing import Any, Dict, Optional, Union
|
||||
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
from openapi_pydantic.compat import PYDANTIC_V2, ConfigDict, Extra
|
||||
|
||||
from .encoding import Encoding
|
||||
from .example import Example
|
||||
from .reference import Reference
|
||||
from .schema import Schema
|
||||
|
||||
_examples = [
|
||||
{
|
||||
"schema": {"$ref": "#/components/schemas/Pet"},
|
||||
"examples": {
|
||||
"cat": {
|
||||
"summary": "An example of a cat",
|
||||
"value": {
|
||||
"name": "Fluffy",
|
||||
"petType": "Cat",
|
||||
"color": "White",
|
||||
"gender": "male",
|
||||
"breed": "Persian",
|
||||
},
|
||||
},
|
||||
"dog": {
|
||||
"summary": "An example of a dog with a cat's name",
|
||||
"value": {
|
||||
"name": "Puma",
|
||||
"petType": "Dog",
|
||||
"color": "Black",
|
||||
"gender": "Female",
|
||||
"breed": "Mixed",
|
||||
},
|
||||
},
|
||||
"frog": {"$ref": "#/components/examples/frog-example"},
|
||||
},
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
class MediaType(BaseModel):
|
||||
"""Each Media Type Object provides schema and examples for the media type
|
||||
identified by its key."""
|
||||
|
||||
media_type_schema: Optional[Union[Reference, Schema]] = Field(
|
||||
default=None, alias="schema"
|
||||
)
|
||||
"""
|
||||
The schema defining the content of the request, response, or parameter.
|
||||
"""
|
||||
|
||||
example: Optional[Any] = None
|
||||
"""
|
||||
Example of the media type.
|
||||
|
||||
The example object SHOULD be in the correct format as specified by the media type.
|
||||
|
||||
The `example` field is mutually exclusive of the `examples` field.
|
||||
|
||||
Furthermore, if referencing a `schema` which contains an example,
|
||||
the `example` value SHALL _override_ the example provided by the schema.
|
||||
"""
|
||||
|
||||
examples: Optional[Dict[str, Union[Example, Reference]]] = None
|
||||
"""
|
||||
Examples of the media type.
|
||||
|
||||
Each example object SHOULD match the media type and specified schema if present.
|
||||
|
||||
The `examples` field is mutually exclusive of the `example` field.
|
||||
|
||||
Furthermore, if referencing a `schema` which contains an example,
|
||||
the `examples` value SHALL _override_ the example provided by the schema.
|
||||
"""
|
||||
|
||||
encoding: Optional[Dict[str, Encoding]] = None
|
||||
"""
|
||||
A map between a property name and its encoding information.
|
||||
The key, being the property name, MUST exist in the schema as a property.
|
||||
The encoding object SHALL only apply to `requestBody` objects
|
||||
when the media type is `multipart` or `application/x-www-form-urlencoded`.
|
||||
"""
|
||||
|
||||
if PYDANTIC_V2:
|
||||
model_config = ConfigDict(
|
||||
extra="allow",
|
||||
populate_by_name=True,
|
||||
json_schema_extra={"examples": _examples},
|
||||
)
|
||||
|
||||
else:
|
||||
|
||||
class Config:
|
||||
extra = Extra.allow
|
||||
allow_population_by_field_name = True
|
||||
schema_extra = {"examples": _examples}
|
80
openapi_pydantic/v3/v3_1/oauth_flow.py
Normal file
80
openapi_pydantic/v3/v3_1/oauth_flow.py
Normal file
|
@ -0,0 +1,80 @@
|
|||
from typing import Dict, Optional
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
from openapi_pydantic.compat import PYDANTIC_V2, ConfigDict, Extra
|
||||
|
||||
_examples = [
|
||||
{
|
||||
"authorizationUrl": "https://example.com/api/oauth/dialog",
|
||||
"scopes": {
|
||||
"write:pets": "modify pets in your account",
|
||||
"read:pets": "read your pets",
|
||||
},
|
||||
},
|
||||
{
|
||||
"authorizationUrl": "https://example.com/api/oauth/dialog",
|
||||
"tokenUrl": "https://example.com/api/oauth/token",
|
||||
"scopes": {
|
||||
"write:pets": "modify pets in your account",
|
||||
"read:pets": "read your pets",
|
||||
},
|
||||
},
|
||||
{
|
||||
"authorizationUrl": "/api/oauth/dialog",
|
||||
"tokenUrl": "/api/oauth/token",
|
||||
"refreshUrl": "/api/oauth/token",
|
||||
"scopes": {
|
||||
"write:pets": "modify pets in your account",
|
||||
"read:pets": "read your pets",
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
class OAuthFlow(BaseModel):
|
||||
"""
|
||||
Configuration details for a supported OAuth Flow
|
||||
"""
|
||||
|
||||
authorizationUrl: Optional[str] = None
|
||||
"""
|
||||
**REQUIRED** for `oauth2 ("implicit", "authorizationCode")`.
|
||||
The authorization URL to be used for this flow.
|
||||
This MUST be in the form of a URL.
|
||||
The OAuth2 standard requires the use of TLS.
|
||||
"""
|
||||
|
||||
tokenUrl: Optional[str] = None
|
||||
"""
|
||||
**REQUIRED** for `oauth2 ("password", "clientCredentials", "authorizationCode")`.
|
||||
The token URL to be used for this flow.
|
||||
This MUST be in the form of a URL.
|
||||
The OAuth2 standard requires the use of TLS.
|
||||
"""
|
||||
|
||||
refreshUrl: Optional[str] = None
|
||||
"""
|
||||
The URL to be used for obtaining refresh tokens.
|
||||
This MUST be in the form of a URL.
|
||||
The OAuth2 standard requires the use of TLS.
|
||||
"""
|
||||
|
||||
scopes: Optional[Dict[str, str]] = None
|
||||
"""
|
||||
**REQUIRED** for `oauth2`. The available scopes for the OAuth2 security scheme.
|
||||
A map between the scope name and a short description for it.
|
||||
The map MAY be empty.
|
||||
"""
|
||||
|
||||
if PYDANTIC_V2:
|
||||
model_config = ConfigDict(
|
||||
extra="allow",
|
||||
json_schema_extra={"examples": _examples},
|
||||
)
|
||||
|
||||
else:
|
||||
|
||||
class Config:
|
||||
extra = Extra.allow
|
||||
schema_extra = {"examples": _examples}
|
47
openapi_pydantic/v3/v3_1/oauth_flows.py
Normal file
47
openapi_pydantic/v3/v3_1/oauth_flows.py
Normal file
|
@ -0,0 +1,47 @@
|
|||
from typing import Optional
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
from openapi_pydantic.compat import PYDANTIC_V2, ConfigDict, Extra
|
||||
|
||||
from .oauth_flow import OAuthFlow
|
||||
|
||||
|
||||
class OAuthFlows(BaseModel):
|
||||
"""
|
||||
Allows configuration of the supported OAuth Flows.
|
||||
"""
|
||||
|
||||
implicit: Optional[OAuthFlow] = None
|
||||
"""
|
||||
Configuration for the OAuth Implicit flow
|
||||
"""
|
||||
|
||||
password: Optional[OAuthFlow] = None
|
||||
"""
|
||||
Configuration for the OAuth Resource Owner Password flow
|
||||
"""
|
||||
|
||||
clientCredentials: Optional[OAuthFlow] = None
|
||||
"""
|
||||
Configuration for the OAuth Client Credentials flow.
|
||||
|
||||
Previously called `application` in OpenAPI 2.0.
|
||||
"""
|
||||
|
||||
authorizationCode: Optional[OAuthFlow] = None
|
||||
"""
|
||||
Configuration for the OAuth Authorization Code flow.
|
||||
|
||||
Previously called `accessCode` in OpenAPI 2.0.
|
||||
"""
|
||||
|
||||
if PYDANTIC_V2:
|
||||
model_config = ConfigDict(
|
||||
extra="allow",
|
||||
)
|
||||
|
||||
else:
|
||||
|
||||
class Config:
|
||||
extra = Extra.allow
|
104
openapi_pydantic/v3/v3_1/open_api.py
Normal file
104
openapi_pydantic/v3/v3_1/open_api.py
Normal file
|
@ -0,0 +1,104 @@
|
|||
from typing import Dict, List, Literal, Optional, Union
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
from openapi_pydantic.compat import PYDANTIC_V2, ConfigDict, Extra
|
||||
|
||||
from .components import Components
|
||||
from .external_documentation import ExternalDocumentation
|
||||
from .info import Info
|
||||
from .path_item import PathItem
|
||||
from .paths import Paths
|
||||
from .reference import Reference
|
||||
from .security_requirement import SecurityRequirement
|
||||
from .server import Server
|
||||
from .tag import Tag
|
||||
|
||||
|
||||
class OpenAPI(BaseModel):
|
||||
"""This is the root document object of the OpenAPI document."""
|
||||
|
||||
openapi: Literal["3.1.1", "3.1.0"] = "3.1.1"
|
||||
"""
|
||||
**REQUIRED**. This string MUST be the [version number](#versions)
|
||||
of the OpenAPI Specification that the OpenAPI document uses.
|
||||
The `openapi` field SHOULD be used by tooling to interpret the OpenAPI document.
|
||||
This is *not* related to the API [`info.version`](#infoVersion) string.
|
||||
"""
|
||||
|
||||
info: Info
|
||||
"""
|
||||
**REQUIRED**. Provides metadata about the API. The metadata MAY be used by tooling
|
||||
as required.
|
||||
"""
|
||||
|
||||
jsonSchemaDialect: Optional[str] = None
|
||||
"""
|
||||
The default value for the `$schema` keyword within [Schema Objects](#schemaObject)
|
||||
contained within this OAS document. This MUST be in the form of a URI.
|
||||
"""
|
||||
|
||||
servers: List[Server] = [Server(url="/")]
|
||||
"""
|
||||
An array of Server Objects, which provide connectivity information to a target
|
||||
server. If the `servers` property is not provided, or is an empty array,
|
||||
the default value would be a [Server Object](#serverObject) with a
|
||||
[url](#serverUrl) value of `/`.
|
||||
"""
|
||||
|
||||
paths: Optional[Paths] = None
|
||||
"""
|
||||
The available paths and operations for the API.
|
||||
"""
|
||||
|
||||
webhooks: Optional[Dict[str, Union[PathItem, Reference]]] = None
|
||||
"""
|
||||
The incoming webhooks that MAY be received as part of this API and that the API
|
||||
consumer MAY choose to implement.
|
||||
Closely related to the `callbacks` feature, this section describes requests
|
||||
initiated other than by an API call,
|
||||
for example by an out of band registration.
|
||||
The key name is a unique string to refer to each webhook,
|
||||
while the (optionally referenced) Path Item Object describes a request
|
||||
that may be initiated by the API provider and the expected responses.
|
||||
An [example](../examples/v3.1/webhook-example.yaml) is available.
|
||||
"""
|
||||
|
||||
components: Optional[Components] = None
|
||||
"""
|
||||
An element to hold various schemas for the document.
|
||||
"""
|
||||
|
||||
security: Optional[List[SecurityRequirement]] = None
|
||||
"""
|
||||
A declaration of which security mechanisms can be used across the API.
|
||||
The list of values includes alternative security requirement objects that can be
|
||||
used. Only one of the security requirement objects need to be satisfied to
|
||||
authorize a request. Individual operations can override this definition.
|
||||
To make security optional, an empty security requirement (`{}`) can be included in
|
||||
the array.
|
||||
"""
|
||||
|
||||
tags: Optional[List[Tag]] = None
|
||||
"""
|
||||
A list of tags used by the document with additional metadata.
|
||||
The order of the tags can be used to reflect on their order by the parsing tools.
|
||||
Not all tags that are used by the [Operation Object](#operationObject) must be
|
||||
declared. The tags that are not declared MAY be organized randomly or based on the
|
||||
tools' logic. Each tag name in the list MUST be unique.
|
||||
"""
|
||||
|
||||
externalDocs: Optional[ExternalDocumentation] = None
|
||||
"""
|
||||
Additional external documentation.
|
||||
"""
|
||||
|
||||
if PYDANTIC_V2:
|
||||
model_config = ConfigDict(
|
||||
extra="allow",
|
||||
)
|
||||
|
||||
else:
|
||||
|
||||
class Config:
|
||||
extra = Extra.allow
|
176
openapi_pydantic/v3/v3_1/operation.py
Normal file
176
openapi_pydantic/v3/v3_1/operation.py
Normal file
|
@ -0,0 +1,176 @@
|
|||
from typing import Dict, List, Optional, Union
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
from openapi_pydantic.compat import PYDANTIC_V2, ConfigDict, Extra
|
||||
|
||||
from .callback import Callback
|
||||
from .external_documentation import ExternalDocumentation
|
||||
from .parameter import Parameter
|
||||
from .reference import Reference
|
||||
from .request_body import RequestBody
|
||||
from .responses import Responses
|
||||
from .security_requirement import SecurityRequirement
|
||||
from .server import Server
|
||||
|
||||
_examples = [
|
||||
{
|
||||
"tags": ["pet"],
|
||||
"summary": "Updates a pet in the store with form data",
|
||||
"operationId": "updatePetWithForm",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "petId",
|
||||
"in": "path",
|
||||
"description": "ID of pet that needs to be updated",
|
||||
"required": True,
|
||||
"schema": {"type": "string"},
|
||||
}
|
||||
],
|
||||
"requestBody": {
|
||||
"content": {
|
||||
"application/x-www-form-urlencoded": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {
|
||||
"description": "Updated name of the pet",
|
||||
"type": "string",
|
||||
},
|
||||
"status": {
|
||||
"description": "Updated status of the pet",
|
||||
"type": "string",
|
||||
},
|
||||
},
|
||||
"required": ["status"],
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Pet updated.",
|
||||
"content": {"application/json": {}, "application/xml": {}},
|
||||
},
|
||||
"405": {
|
||||
"description": "Method Not Allowed",
|
||||
"content": {"application/json": {}, "application/xml": {}},
|
||||
},
|
||||
},
|
||||
"security": [{"petstore_auth": ["write:pets", "read:pets"]}],
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
class Operation(BaseModel):
|
||||
"""Describes a single API operation on a path."""
|
||||
|
||||
tags: Optional[List[str]] = None
|
||||
"""
|
||||
A list of tags for API documentation control.
|
||||
Tags can be used for logical grouping of operations by resources or any other
|
||||
qualifier.
|
||||
"""
|
||||
|
||||
summary: Optional[str] = None
|
||||
"""
|
||||
A short summary of what the operation does.
|
||||
"""
|
||||
|
||||
description: Optional[str] = None
|
||||
"""
|
||||
A verbose explanation of the operation behavior.
|
||||
[CommonMark syntax](https://spec.commonmark.org/) MAY be used for rich text
|
||||
representation.
|
||||
"""
|
||||
|
||||
externalDocs: Optional[ExternalDocumentation] = None
|
||||
"""
|
||||
Additional external documentation for this operation.
|
||||
"""
|
||||
|
||||
operationId: Optional[str] = None
|
||||
"""
|
||||
Unique string used to identify the operation.
|
||||
The id MUST be unique among all operations described in the API.
|
||||
The operationId value is **case-sensitive**.
|
||||
Tools and libraries MAY use the operationId to uniquely identify an operation,
|
||||
therefore, it is RECOMMENDED to follow common programming naming conventions.
|
||||
"""
|
||||
|
||||
parameters: Optional[List[Union[Parameter, Reference]]] = None
|
||||
"""
|
||||
A list of parameters that are applicable for this operation.
|
||||
If a parameter is already defined at the [Path Item](#pathItemParameters),
|
||||
the new definition will override it but can never remove it.
|
||||
The list MUST NOT include duplicated parameters.
|
||||
A unique parameter is defined by a combination of a [name](#parameterName) and
|
||||
[location](#parameterIn). The list can use the [Reference Object](#referenceObject)
|
||||
to link to parameters that are defined at the
|
||||
[OpenAPI Object's components/parameters](#componentsParameters).
|
||||
"""
|
||||
|
||||
requestBody: Optional[Union[RequestBody, Reference]] = None
|
||||
"""
|
||||
The request body applicable for this operation.
|
||||
|
||||
The `requestBody` is fully supported in HTTP methods where the HTTP 1.1
|
||||
specification [RFC7231](https://tools.ietf.org/html/rfc7231#section-4.3.1) has
|
||||
explicitly defined semantics for request bodies.
|
||||
In other cases where the HTTP spec is vague (such as [GET](https://tools.ietf.org/html/rfc7231#section-4.3.1),
|
||||
[HEAD](https://tools.ietf.org/html/rfc7231#section-4.3.2)
|
||||
and [DELETE](https://tools.ietf.org/html/rfc7231#section-4.3.5)),
|
||||
`requestBody` is permitted but does not have well-defined semantics and SHOULD be
|
||||
avoided if possible.
|
||||
"""
|
||||
|
||||
responses: Optional[Responses] = None
|
||||
"""
|
||||
The list of possible responses as they are returned from executing this operation.
|
||||
"""
|
||||
|
||||
callbacks: Optional[Dict[str, Union[Callback, Reference]]] = None
|
||||
"""
|
||||
A map of possible out-of band callbacks related to the parent operation.
|
||||
The key is a unique identifier for the Callback Object.
|
||||
Each value in the map is a [Callback Object](#callbackObject)
|
||||
that describes a request that may be initiated by the API provider and the expected
|
||||
responses.
|
||||
"""
|
||||
|
||||
deprecated: bool = False
|
||||
"""
|
||||
Declares this operation to be deprecated.
|
||||
Consumers SHOULD refrain from usage of the declared operation.
|
||||
Default value is `false`.
|
||||
"""
|
||||
|
||||
security: Optional[List[SecurityRequirement]] = None
|
||||
"""
|
||||
A declaration of which security mechanisms can be used for this operation.
|
||||
The list of values includes alternative security requirement objects that can be
|
||||
used. Only one of the security requirement objects need to be satisfied to
|
||||
authorize a request. To make security optional, an empty security requirement
|
||||
(`{}`) can be included in the array. This definition overrides any declared
|
||||
top-level [`security`](#oasSecurity). To remove a top-level security declaration,
|
||||
an empty array can be used.
|
||||
"""
|
||||
|
||||
servers: Optional[List[Server]] = None
|
||||
"""
|
||||
An alternative `server` array to service this operation.
|
||||
If an alternative `server` object is specified at the Path Item Object or Root
|
||||
level, it will be overridden by this value.
|
||||
"""
|
||||
|
||||
if PYDANTIC_V2:
|
||||
model_config = ConfigDict(
|
||||
extra="allow",
|
||||
json_schema_extra={"examples": _examples},
|
||||
)
|
||||
|
||||
else:
|
||||
|
||||
class Config:
|
||||
extra = Extra.allow
|
||||
schema_extra = {"examples": _examples}
|
235
openapi_pydantic/v3/v3_1/parameter.py
Normal file
235
openapi_pydantic/v3/v3_1/parameter.py
Normal file
|
@ -0,0 +1,235 @@
|
|||
import enum
|
||||
from typing import Any, Dict, Optional, Union
|
||||
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
from openapi_pydantic.compat import PYDANTIC_V2, ConfigDict, Extra
|
||||
|
||||
from .example import Example
|
||||
from .media_type import MediaType
|
||||
from .reference import Reference
|
||||
from .schema import Schema
|
||||
|
||||
_examples = [
|
||||
{
|
||||
"name": "token",
|
||||
"in": "header",
|
||||
"description": "token to be passed as a header",
|
||||
"required": True,
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {"type": "integer", "format": "int64"},
|
||||
},
|
||||
"style": "simple",
|
||||
},
|
||||
{
|
||||
"name": "username",
|
||||
"in": "path",
|
||||
"description": "username to fetch",
|
||||
"required": True,
|
||||
"schema": {"type": "string"},
|
||||
},
|
||||
{
|
||||
"name": "id",
|
||||
"in": "query",
|
||||
"description": "ID of the object to fetch",
|
||||
"required": False,
|
||||
"schema": {"type": "array", "items": {"type": "string"}},
|
||||
"style": "form",
|
||||
"explode": True,
|
||||
},
|
||||
{
|
||||
"in": "query",
|
||||
"name": "freeForm",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": {"type": "integer"},
|
||||
},
|
||||
"style": "form",
|
||||
},
|
||||
{
|
||||
"in": "query",
|
||||
"name": "coordinates",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"required": ["lat", "long"],
|
||||
"properties": {
|
||||
"lat": {"type": "number"},
|
||||
"long": {"type": "number"},
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
class ParameterLocation(str, enum.Enum):
|
||||
"""The location of a given parameter."""
|
||||
|
||||
QUERY = "query"
|
||||
HEADER = "header"
|
||||
PATH = "path"
|
||||
COOKIE = "cookie"
|
||||
|
||||
|
||||
class ParameterBase(BaseModel):
|
||||
"""
|
||||
Base class for Parameter and Header.
|
||||
|
||||
(Header is like Parameter, but has no `name` or `in` fields.)
|
||||
"""
|
||||
|
||||
description: Optional[str] = None
|
||||
"""
|
||||
A brief description of the parameter.
|
||||
This could contain examples of use.
|
||||
[CommonMark syntax](https://spec.commonmark.org/) MAY be used for rich text
|
||||
representation.
|
||||
"""
|
||||
|
||||
required: bool = False
|
||||
"""
|
||||
Determines whether this parameter is mandatory.
|
||||
If the [parameter location](#parameterIn) is `"path"`, this property is
|
||||
**REQUIRED** and its value MUST be `true`.
|
||||
Otherwise, the property MAY be included and its default value is `false`.
|
||||
"""
|
||||
|
||||
deprecated: bool = False
|
||||
"""
|
||||
Specifies that a parameter is deprecated and SHOULD be transitioned out of usage.
|
||||
Default value is `false`.
|
||||
"""
|
||||
|
||||
style: Optional[str] = None
|
||||
"""
|
||||
Describes how the parameter value will be serialized depending on the type of the
|
||||
parameter value. Default values (based on value of `in`):
|
||||
|
||||
- for `query` - `form`;
|
||||
- for `path` - `simple`;
|
||||
- for `header` - `simple`;
|
||||
- for `cookie` - `form`.
|
||||
"""
|
||||
|
||||
explode: Optional[bool] = None
|
||||
"""
|
||||
When this is true, parameter values of type `array` or `object` generate separate
|
||||
parameters for each value of the array or key-value pair of the map.
|
||||
For other types of parameters this property has no effect.
|
||||
When [`style`](#parameterStyle) is `form`, the default value is `true`.
|
||||
For all other styles, the default value is `false`.
|
||||
"""
|
||||
|
||||
param_schema: Optional[Union[Schema, Reference]] = Field(
|
||||
default=None, alias="schema"
|
||||
)
|
||||
"""
|
||||
The schema defining the type used for the parameter.
|
||||
"""
|
||||
|
||||
example: Optional[Any] = None
|
||||
"""
|
||||
Example of the parameter's potential value.
|
||||
The example SHOULD match the specified schema and encoding properties if present.
|
||||
The `example` field is mutually exclusive of the `examples` field.
|
||||
Furthermore, if referencing a `schema` that contains an example,
|
||||
the `example` value SHALL _override_ the example provided by the schema.
|
||||
To represent examples of media types that cannot naturally be represented in JSON
|
||||
or YAML, a string value can contain the example with escaping where necessary.
|
||||
"""
|
||||
|
||||
examples: Optional[Dict[str, Union[Example, Reference]]] = None
|
||||
"""
|
||||
Examples of the parameter's potential value.
|
||||
Each example SHOULD contain a value in the correct format as specified in the
|
||||
parameter encoding. The `examples` field is mutually exclusive of the `example`
|
||||
field.
|
||||
Furthermore, if referencing a `schema` that contains an example,
|
||||
the `examples` value SHALL _override_ the example provided by the schema.
|
||||
"""
|
||||
|
||||
"""
|
||||
For more complex scenarios, the [`content`](#parameterContent) property
|
||||
can define the media type and schema of the parameter.
|
||||
A parameter MUST contain either a `schema` property, or a `content` property, but
|
||||
not both.
|
||||
When `example` or `examples` are provided in conjunction with the `schema` object,
|
||||
the example MUST follow the prescribed serialization strategy for the parameter.
|
||||
"""
|
||||
|
||||
content: Optional[Dict[str, MediaType]] = None
|
||||
"""
|
||||
A map containing the representations for the parameter.
|
||||
The key is the media type and the value describes it.
|
||||
The map MUST only contain one entry.
|
||||
"""
|
||||
|
||||
if PYDANTIC_V2:
|
||||
model_config = ConfigDict(
|
||||
extra="allow",
|
||||
populate_by_name=True,
|
||||
json_schema_extra={"examples": _examples},
|
||||
)
|
||||
|
||||
else:
|
||||
|
||||
class Config:
|
||||
extra = Extra.allow
|
||||
allow_population_by_field_name = True
|
||||
schema_extra = {"examples": _examples}
|
||||
|
||||
|
||||
class Parameter(ParameterBase):
|
||||
"""
|
||||
Describes a single operation parameter.
|
||||
|
||||
A unique parameter is defined by a combination of a [name](#parameterName) and
|
||||
[location](#parameterIn).
|
||||
"""
|
||||
|
||||
"""Fixed Fields"""
|
||||
|
||||
name: str
|
||||
"""
|
||||
**REQUIRED**. The name of the parameter.
|
||||
Parameter names are *case sensitive*.
|
||||
|
||||
- If [`in`](#parameterIn) is `"path"`, the `name` field MUST correspond to a
|
||||
template expression occurring within the [path](#pathsPath) field in the
|
||||
[Paths Object](#pathsObject).
|
||||
See [Path Templating](#pathTemplating) for further information.
|
||||
- If [`in`](#parameterIn) is `"header"` and the `name` field is `"Accept"`,
|
||||
`"Content-Type"` or `"Authorization"`, the parameter definition SHALL be ignored.
|
||||
- For all other cases, the `name` corresponds to the parameter name used by the
|
||||
[`in`](#parameterIn) property.
|
||||
"""
|
||||
|
||||
param_in: ParameterLocation = Field(alias="in")
|
||||
"""
|
||||
**REQUIRED**. The location of the parameter. Possible values are `"query"`,
|
||||
`"header"`, `"path"` or `"cookie"`.
|
||||
"""
|
||||
|
||||
allowEmptyValue: bool = False
|
||||
"""
|
||||
Sets the ability to pass empty-valued parameters.
|
||||
This is valid only for `query` parameters and allows sending a parameter with an
|
||||
empty value. Default value is `false`.
|
||||
If [`style`](#parameterStyle) is used, and if behavior is `n/a` (cannot be
|
||||
serialized), the value of `allowEmptyValue` SHALL be ignored.
|
||||
Use of this property is NOT RECOMMENDED, as it is likely to be removed in a later
|
||||
revision.
|
||||
"""
|
||||
|
||||
allowReserved: bool = False
|
||||
"""
|
||||
Determines whether the parameter value SHOULD allow reserved characters,
|
||||
as defined by [RFC3986](https://tools.ietf.org/html/rfc3986#section-2.2)
|
||||
`:/?#[]@!$&'()*+,;=` to be included without percent-encoding.
|
||||
This property only applies to parameters with an `in` value of `query`.
|
||||
The default value is `false`.
|
||||
"""
|
153
openapi_pydantic/v3/v3_1/path_item.py
Normal file
153
openapi_pydantic/v3/v3_1/path_item.py
Normal file
|
@ -0,0 +1,153 @@
|
|||
from typing import List, Optional, Union
|
||||
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
from openapi_pydantic.compat import PYDANTIC_V2, ConfigDict, Extra
|
||||
|
||||
from .operation import Operation
|
||||
from .parameter import Parameter
|
||||
from .reference import Reference
|
||||
from .server import Server
|
||||
|
||||
_examples = [
|
||||
{
|
||||
"get": {
|
||||
"description": "Returns pets based on ID",
|
||||
"summary": "Find pets by ID",
|
||||
"operationId": "getPetsById",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "pet response",
|
||||
"content": {
|
||||
"*/*": {
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {"$ref": "#/components/schemas/Pet"},
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
"default": {
|
||||
"description": "error payload",
|
||||
"content": {
|
||||
"text/html": {
|
||||
"schema": {"$ref": "#/components/schemas/ErrorModel"}
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"parameters": [
|
||||
{
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"description": "ID of pet to use",
|
||||
"required": True,
|
||||
"schema": {"type": "array", "items": {"type": "string"}},
|
||||
"style": "simple",
|
||||
}
|
||||
],
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
class PathItem(BaseModel):
|
||||
"""
|
||||
Describes the operations available on a single path.
|
||||
A Path Item MAY be empty, due to [ACL constraints](#securityFiltering).
|
||||
The path itself is still exposed to the documentation viewer
|
||||
but they will not know which operations and parameters are available.
|
||||
"""
|
||||
|
||||
ref: Optional[str] = Field(default=None, alias="$ref")
|
||||
"""
|
||||
Allows for an external definition of this path item.
|
||||
The referenced structure MUST be in the format of a
|
||||
[Path Item Object](#pathItemObject).
|
||||
|
||||
In case a Path Item Object field appears both in the defined object and the
|
||||
referenced object, the behavior is undefined.
|
||||
See the rules for resolving [Relative References](#relativeReferencesURI).
|
||||
"""
|
||||
|
||||
summary: Optional[str] = None
|
||||
"""
|
||||
An optional, string summary, intended to apply to all operations in this path.
|
||||
"""
|
||||
|
||||
description: Optional[str] = None
|
||||
"""
|
||||
An optional, string description, intended to apply to all operations in this path.
|
||||
[CommonMark syntax](https://spec.commonmark.org/) MAY be used for rich text
|
||||
representation.
|
||||
"""
|
||||
|
||||
get: Optional[Operation] = None
|
||||
"""
|
||||
A definition of a GET operation on this path.
|
||||
"""
|
||||
|
||||
put: Optional[Operation] = None
|
||||
"""
|
||||
A definition of a PUT operation on this path.
|
||||
"""
|
||||
|
||||
post: Optional[Operation] = None
|
||||
"""
|
||||
A definition of a POST operation on this path.
|
||||
"""
|
||||
|
||||
delete: Optional[Operation] = None
|
||||
"""
|
||||
A definition of a DELETE operation on this path.
|
||||
"""
|
||||
|
||||
options: Optional[Operation] = None
|
||||
"""
|
||||
A definition of a OPTIONS operation on this path.
|
||||
"""
|
||||
|
||||
head: Optional[Operation] = None
|
||||
"""
|
||||
A definition of a HEAD operation on this path.
|
||||
"""
|
||||
|
||||
patch: Optional[Operation] = None
|
||||
"""
|
||||
A definition of a PATCH operation on this path.
|
||||
"""
|
||||
|
||||
trace: Optional[Operation] = None
|
||||
"""
|
||||
A definition of a TRACE operation on this path.
|
||||
"""
|
||||
|
||||
servers: Optional[List[Server]] = None
|
||||
"""
|
||||
An alternative `server` array to service all operations in this path.
|
||||
"""
|
||||
|
||||
parameters: Optional[List[Union[Parameter, Reference]]] = None
|
||||
"""
|
||||
A list of parameters that are applicable for all the operations described under
|
||||
this path. These parameters can be overridden at the operation level, but cannot be
|
||||
removed there. The list MUST NOT include duplicated parameters.
|
||||
A unique parameter is defined by a combination of a [name](#parameterName) and
|
||||
[location](#parameterIn). The list can use the [Reference Object](#referenceObject)
|
||||
to link to parameters that are defined at the
|
||||
[OpenAPI Object's components/parameters](#componentsParameters).
|
||||
"""
|
||||
|
||||
if PYDANTIC_V2:
|
||||
model_config = ConfigDict(
|
||||
extra="allow",
|
||||
populate_by_name=True,
|
||||
json_schema_extra={"examples": _examples},
|
||||
)
|
||||
|
||||
else:
|
||||
|
||||
class Config:
|
||||
extra = Extra.allow
|
||||
allow_population_by_field_name = True
|
||||
schema_extra = {"examples": _examples}
|
28
openapi_pydantic/v3/v3_1/paths.py
Normal file
28
openapi_pydantic/v3/v3_1/paths.py
Normal file
|
@ -0,0 +1,28 @@
|
|||
from typing import Dict
|
||||
|
||||
from .path_item import PathItem
|
||||
|
||||
Paths = Dict[str, PathItem]
|
||||
"""
|
||||
Holds the relative paths to the individual endpoints and their operations.
|
||||
The path is appended to the URL from the [`Server Object`](#serverObject) in order to
|
||||
construct the full URL.
|
||||
|
||||
The Paths MAY be empty, due to
|
||||
[Access Control List (ACL) constraints](#securityFiltering).
|
||||
"""
|
||||
|
||||
"""Patterned Fields"""
|
||||
|
||||
# "/{path}" : PathItem
|
||||
"""
|
||||
A relative path to an individual endpoint.
|
||||
The field name MUST begin with a forward slash (`/`).
|
||||
The path is **appended** (no relative URL resolution) to the expanded URL
|
||||
from the [`Server Object`](#serverObject)'s `url` field in order to construct the full
|
||||
URL. [Path templating](#pathTemplating) is allowed.
|
||||
When matching URLs, concrete (non-templated) paths would be matched before their
|
||||
templated counterparts. Templated paths with the same hierarchy but different templated
|
||||
names MUST NOT exist as they are identical. In case of ambiguous matching, it's up to
|
||||
the tooling to decide which one to use.
|
||||
"""
|
55
openapi_pydantic/v3/v3_1/reference.py
Normal file
55
openapi_pydantic/v3/v3_1/reference.py
Normal file
|
@ -0,0 +1,55 @@
|
|||
from typing import Optional
|
||||
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
from openapi_pydantic.compat import PYDANTIC_V2, ConfigDict, Extra
|
||||
|
||||
_examples = [
|
||||
{"$ref": "#/components/schemas/Pet"},
|
||||
{"$ref": "Pet.json"},
|
||||
{"$ref": "definitions.json#/Pet"},
|
||||
]
|
||||
|
||||
|
||||
class Reference(BaseModel):
|
||||
"""
|
||||
A simple object to allow referencing other components in the OpenAPI document.
|
||||
|
||||
The `$ref` string value contains a URI [RFC3986](https://tools.ietf.org/html/rfc3986),
|
||||
which identifies the location of the value being referenced.
|
||||
|
||||
See the rules for resolving [Relative References](#relativeReferencesURI).
|
||||
"""
|
||||
|
||||
ref: str = Field(alias="$ref")
|
||||
"""**REQUIRED**. The reference identifier. This MUST be in the form of a URI."""
|
||||
|
||||
summary: Optional[str] = None
|
||||
"""
|
||||
A short summary which by default SHOULD override that of the referenced component.
|
||||
If the referenced object-type does not allow a `summary` field, then this field has
|
||||
no effect.
|
||||
"""
|
||||
|
||||
description: Optional[str] = None
|
||||
"""
|
||||
A description which by default SHOULD override that of the referenced component.
|
||||
[CommonMark syntax](https://spec.commonmark.org/) MAY be used for rich text
|
||||
representation.
|
||||
If the referenced object-type does not allow a `description` field, then this field
|
||||
has no effect.
|
||||
"""
|
||||
|
||||
if PYDANTIC_V2:
|
||||
model_config = ConfigDict(
|
||||
extra="allow",
|
||||
populate_by_name=True,
|
||||
json_schema_extra={"examples": _examples},
|
||||
)
|
||||
|
||||
else:
|
||||
|
||||
class Config:
|
||||
extra = Extra.allow
|
||||
allow_population_by_field_name = True
|
||||
schema_extra = {"examples": _examples}
|
95
openapi_pydantic/v3/v3_1/request_body.py
Normal file
95
openapi_pydantic/v3/v3_1/request_body.py
Normal file
|
@ -0,0 +1,95 @@
|
|||
from typing import Dict, Optional
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
from openapi_pydantic.compat import PYDANTIC_V2, ConfigDict, Extra
|
||||
|
||||
from .media_type import MediaType
|
||||
|
||||
_examples = [
|
||||
{
|
||||
"description": "user to add to the system",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {"$ref": "#/components/schemas/User"},
|
||||
"examples": {
|
||||
"user": {
|
||||
"summary": "User Example",
|
||||
"externalValue": "http://foo.bar/examples/user-example.json",
|
||||
}
|
||||
},
|
||||
},
|
||||
"application/xml": {
|
||||
"schema": {"$ref": "#/components/schemas/User"},
|
||||
"examples": {
|
||||
"user": {
|
||||
"summary": "User example in XML",
|
||||
"externalValue": "http://foo.bar/examples/user-example.xml",
|
||||
}
|
||||
},
|
||||
},
|
||||
"text/plain": {
|
||||
"examples": {
|
||||
"user": {
|
||||
"summary": "User example in Plain text",
|
||||
"externalValue": "http://foo.bar/examples/user-example.txt",
|
||||
}
|
||||
}
|
||||
},
|
||||
"*/*": {
|
||||
"examples": {
|
||||
"user": {
|
||||
"summary": "User example in other format",
|
||||
"externalValue": "http://foo.bar/examples/user-example.whatever",
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
"description": "user to add to the system",
|
||||
"content": {
|
||||
"text/plain": {"schema": {"type": "array", "items": {"type": "string"}}}
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
class RequestBody(BaseModel):
|
||||
"""Describes a single request body."""
|
||||
|
||||
description: Optional[str] = None
|
||||
"""
|
||||
A brief description of the request body.
|
||||
This could contain examples of use.
|
||||
|
||||
[CommonMark syntax](https://spec.commonmark.org/) MAY be used for rich text
|
||||
representation.
|
||||
"""
|
||||
|
||||
content: Dict[str, MediaType]
|
||||
"""
|
||||
**REQUIRED**. The content of the request body.
|
||||
The key is a media type or [media type range](https://tools.ietf.org/html/rfc7231#appendix-D)
|
||||
and the value describes it.
|
||||
|
||||
For requests that match multiple keys, only the most specific key is applicable.
|
||||
e.g. text/plain overrides text/*
|
||||
"""
|
||||
|
||||
required: bool = False
|
||||
"""
|
||||
Determines if the request body is required in the request. Defaults to `false`.
|
||||
"""
|
||||
|
||||
if PYDANTIC_V2:
|
||||
model_config = ConfigDict(
|
||||
extra="allow",
|
||||
json_schema_extra={"examples": _examples},
|
||||
)
|
||||
|
||||
else:
|
||||
|
||||
class Config:
|
||||
extra = Extra.allow
|
||||
schema_extra = {"examples": _examples}
|
100
openapi_pydantic/v3/v3_1/response.py
Normal file
100
openapi_pydantic/v3/v3_1/response.py
Normal file
|
@ -0,0 +1,100 @@
|
|||
from typing import Dict, Optional, Union
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
from openapi_pydantic.compat import PYDANTIC_V2, ConfigDict, Extra
|
||||
|
||||
from .header import Header
|
||||
from .link import Link
|
||||
from .media_type import MediaType
|
||||
from .reference import Reference
|
||||
|
||||
_examples = [
|
||||
{
|
||||
"description": "A complex object array response",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {"$ref": "#/components/schemas/VeryComplexType"},
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
"description": "A simple string response",
|
||||
"content": {"text/plain": {"schema": {"type": "string"}}},
|
||||
},
|
||||
{
|
||||
"description": "A simple string response",
|
||||
"content": {"text/plain": {"schema": {"type": "string", "example": "whoa!"}}},
|
||||
"headers": {
|
||||
"X-Rate-Limit-Limit": {
|
||||
"description": "The number of allowed requests in the "
|
||||
"current period",
|
||||
"schema": {"type": "integer"},
|
||||
},
|
||||
"X-Rate-Limit-Remaining": {
|
||||
"description": "The number of remaining requests in the "
|
||||
"current period",
|
||||
"schema": {"type": "integer"},
|
||||
},
|
||||
"X-Rate-Limit-Reset": {
|
||||
"description": "The number of seconds left in the current period",
|
||||
"schema": {"type": "integer"},
|
||||
},
|
||||
},
|
||||
},
|
||||
{"description": "object created"},
|
||||
]
|
||||
|
||||
|
||||
class Response(BaseModel):
|
||||
"""
|
||||
Describes a single response from an API Operation, including design-time,
|
||||
static `links` to operations based on the response.
|
||||
"""
|
||||
|
||||
description: str
|
||||
"""
|
||||
**REQUIRED**. A short description of the response.
|
||||
[CommonMark syntax](https://spec.commonmark.org/) MAY be used for rich text
|
||||
representation.
|
||||
"""
|
||||
|
||||
headers: Optional[Dict[str, Union[Header, Reference]]] = None
|
||||
"""
|
||||
Maps a header name to its definition.
|
||||
[RFC7230](https://tools.ietf.org/html/rfc7230#page-22) states header names are case
|
||||
insensitive.
|
||||
If a response header is defined with the name `"Content-Type"`, it SHALL be ignored.
|
||||
"""
|
||||
|
||||
content: Optional[Dict[str, MediaType]] = None
|
||||
"""
|
||||
A map containing descriptions of potential response payloads.
|
||||
The key is a media type or [media type range](https://tools.ietf.org/html/rfc7231#appendix-D)
|
||||
and the value describes it.
|
||||
|
||||
For responses that match multiple keys, only the most specific key is applicable.
|
||||
e.g. text/plain overrides text/*
|
||||
"""
|
||||
|
||||
links: Optional[Dict[str, Union[Link, Reference]]] = None
|
||||
"""
|
||||
A map of operations links that can be followed from the response.
|
||||
The key of the map is a short name for the link, following the naming constraints
|
||||
of the names for [Component Objects](#componentsObject).
|
||||
"""
|
||||
|
||||
if PYDANTIC_V2:
|
||||
model_config = ConfigDict(
|
||||
extra="allow",
|
||||
json_schema_extra={"examples": _examples},
|
||||
)
|
||||
|
||||
else:
|
||||
|
||||
class Config:
|
||||
extra = Extra.allow
|
||||
schema_extra = {"examples": _examples}
|
52
openapi_pydantic/v3/v3_1/responses.py
Normal file
52
openapi_pydantic/v3/v3_1/responses.py
Normal file
|
@ -0,0 +1,52 @@
|
|||
from typing import Dict, Union
|
||||
|
||||
from .reference import Reference
|
||||
from .response import Response
|
||||
|
||||
Responses = Dict[str, Union[Response, Reference]]
|
||||
"""
|
||||
A container for the expected responses of an operation.
|
||||
The container maps a HTTP response code to the expected response.
|
||||
|
||||
The documentation is not necessarily expected to cover all possible HTTP response codes
|
||||
because they may not be known in advance.
|
||||
However, documentation is expected to cover a successful operation response and any
|
||||
known errors.
|
||||
|
||||
The `default` MAY be used as a default response object for all HTTP codes
|
||||
that are not covered individually by the specification.
|
||||
|
||||
The `Responses Object` MUST contain at least one response code, and it
|
||||
SHOULD be the response for a successful operation call.
|
||||
"""
|
||||
|
||||
"""Fixed Fields"""
|
||||
|
||||
# default: Optional[Union[Response, Reference]]
|
||||
"""
|
||||
The documentation of responses other than the ones declared for specific HTTP response
|
||||
codes.
|
||||
Use this field to cover undeclared responses.
|
||||
A [Reference Object](#referenceObject) can link to a response
|
||||
that the [OpenAPI Object's components/responses](#componentsResponses) section defines.
|
||||
"""
|
||||
|
||||
"""Patterned Fields"""
|
||||
# {httpStatusCode}: Optional[Union[Response, Reference]]
|
||||
"""
|
||||
Any [HTTP status code](#httpCodes) can be used as the property name,
|
||||
but only one property per code, to describe the expected response for that HTTP status
|
||||
code.
|
||||
|
||||
A [Reference Object](#referenceObject) can link to a response
|
||||
that is defined in the [OpenAPI Object's components/responses](#componentsResponses)
|
||||
section.
|
||||
This field MUST be enclosed in quotation marks (for example, "200") for compatibility
|
||||
between JSON and YAML.
|
||||
To define a range of response codes, this field MAY contain the uppercase wildcard
|
||||
character `X`.
|
||||
For example, `2XX` represents all response codes between `[200-299]`.
|
||||
Only the following range definitions are allowed: `1XX`, `2XX`, `3XX`, `4XX`, and `5XX`.
|
||||
If a response is defined using an explicit code,
|
||||
the explicit code definition takes precedence over the range definition for that code.
|
||||
"""
|
971
openapi_pydantic/v3/v3_1/schema.py
Normal file
971
openapi_pydantic/v3/v3_1/schema.py
Normal file
|
@ -0,0 +1,971 @@
|
|||
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Union
|
||||
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
from openapi_pydantic.compat import PYDANTIC_V2, ConfigDict, Extra, min_length_arg
|
||||
|
||||
from .datatype import DataType
|
||||
from .discriminator import Discriminator
|
||||
from .external_documentation import ExternalDocumentation
|
||||
from .reference import Reference
|
||||
from .xml import XML
|
||||
|
||||
_examples = [
|
||||
{"type": "string", "format": "email"},
|
||||
{
|
||||
"type": "object",
|
||||
"required": ["name"],
|
||||
"properties": {
|
||||
"name": {"type": "string"},
|
||||
"address": {"$ref": "#/components/schemas/Address"},
|
||||
"age": {"type": "integer", "format": "int32", "minimum": 0},
|
||||
},
|
||||
},
|
||||
{"type": "object", "additionalProperties": {"type": "string"}},
|
||||
{
|
||||
"type": "object",
|
||||
"additionalProperties": {"$ref": "#/components/schemas/ComplexModel"},
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {"type": "integer", "format": "int64"},
|
||||
"name": {"type": "string"},
|
||||
},
|
||||
"required": ["name"],
|
||||
"example": {"name": "Puma", "id": 1},
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"required": ["message", "code"],
|
||||
"properties": {
|
||||
"message": {"type": "string"},
|
||||
"code": {"type": "integer", "minimum": 100, "maximum": 600},
|
||||
},
|
||||
},
|
||||
{
|
||||
"allOf": [
|
||||
{"$ref": "#/components/schemas/ErrorModel"},
|
||||
{
|
||||
"type": "object",
|
||||
"required": ["rootCause"],
|
||||
"properties": {"rootCause": {"type": "string"}},
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"discriminator": {"propertyName": "petType"},
|
||||
"properties": {
|
||||
"name": {"type": "string"},
|
||||
"petType": {"type": "string"},
|
||||
},
|
||||
"required": ["name", "petType"],
|
||||
},
|
||||
{
|
||||
"description": "A representation of a cat. "
|
||||
"Note that `Cat` will be used as the discriminator value.",
|
||||
"allOf": [
|
||||
{"$ref": "#/components/schemas/Pet"},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"huntingSkill": {
|
||||
"type": "string",
|
||||
"description": "The measured skill for hunting",
|
||||
"default": "lazy",
|
||||
"enum": [
|
||||
"clueless",
|
||||
"lazy",
|
||||
"adventurous",
|
||||
"aggressive",
|
||||
],
|
||||
}
|
||||
},
|
||||
"required": ["huntingSkill"],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
"description": "A representation of a dog. "
|
||||
"Note that `Dog` will be used as the discriminator value.",
|
||||
"allOf": [
|
||||
{"$ref": "#/components/schemas/Pet"},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"packSize": {
|
||||
"type": "integer",
|
||||
"format": "int32",
|
||||
"description": "the size of the pack the dog is from",
|
||||
"default": 0,
|
||||
"minimum": 0,
|
||||
}
|
||||
},
|
||||
"required": ["packSize"],
|
||||
},
|
||||
],
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
class Schema(BaseModel):
|
||||
"""
|
||||
The Schema Object allows the definition of input and output data types.
|
||||
These types can be objects, but also primitives and arrays.
|
||||
This object is a superset of
|
||||
the [JSON Schema Specification Draft 2020-12](https://tools.ietf.org/html/draft-bhutton-json-schema-00).
|
||||
|
||||
For more information about the properties,
|
||||
see [JSON Schema Core](https://tools.ietf.org/html/draft-wright-json-schema-00)
|
||||
and [JSON Schema Validation](https://tools.ietf.org/html/draft-wright-json-schema-validation-00).
|
||||
|
||||
Unless stated otherwise, the property definitions follow those of JSON Schema
|
||||
and do not add any additional semantics.
|
||||
Where JSON Schema indicates that behavior is defined by the application (e.g. for
|
||||
annotations), OAS also defers the definition of semantics to the application
|
||||
consuming the OpenAPI document.
|
||||
"""
|
||||
|
||||
"""
|
||||
The following properties are taken directly from the
|
||||
[JSON Schema Core](https://tools.ietf.org/html/draft-wright-json-schema-00)
|
||||
and follow the same specifications:
|
||||
"""
|
||||
|
||||
allOf: Optional[List[Union[Reference, "Schema"]]] = None
|
||||
"""
|
||||
This keyword's value MUST be a non-empty array. Each item of the
|
||||
array MUST be a valid JSON Schema.
|
||||
|
||||
An instance validates successfully against this keyword if it
|
||||
validates successfully against all schemas defined by this keyword's
|
||||
value.
|
||||
"""
|
||||
|
||||
anyOf: Optional[List[Union[Reference, "Schema"]]] = None
|
||||
"""
|
||||
This keyword's value MUST be a non-empty array. Each item of the
|
||||
array MUST be a valid JSON Schema.
|
||||
|
||||
An instance validates successfully against this keyword if it
|
||||
validates successfully against at least one schema defined by this
|
||||
keyword's value. Note that when annotations are being collected, all
|
||||
subschemas MUST be examined so that annotations are collected from
|
||||
each subschema that validates successfully.
|
||||
"""
|
||||
|
||||
oneOf: Optional[List[Union[Reference, "Schema"]]] = None
|
||||
"""
|
||||
This keyword's value MUST be a non-empty array. Each item of the
|
||||
array MUST be a valid JSON Schema.
|
||||
|
||||
An instance validates successfully against this keyword if it
|
||||
validates successfully against exactly one schema defined by this
|
||||
keyword's value.
|
||||
"""
|
||||
|
||||
schema_not: Optional[Union[Reference, "Schema"]] = Field(default=None, alias="not")
|
||||
"""
|
||||
This keyword's value MUST be a valid JSON Schema.
|
||||
|
||||
An instance is valid against this keyword if it fails to validate
|
||||
successfully against the schema defined by this keyword.
|
||||
"""
|
||||
|
||||
schema_if: Optional[Union[Reference, "Schema"]] = Field(default=None, alias="if")
|
||||
"""
|
||||
This keyword's value MUST be a valid JSON Schema.
|
||||
|
||||
This validation outcome of this keyword's subschema has no direct
|
||||
effect on the overall validation result. Rather, it controls which
|
||||
of the "then" or "else" keywords are evaluated.
|
||||
|
||||
Instances that successfully validate against this keyword's subschema
|
||||
MUST also be valid against the subschema value of the "then" keyword,
|
||||
if present.
|
||||
|
||||
Instances that fail to validate against this keyword's subschema MUST
|
||||
also be valid against the subschema value of the "else" keyword, if
|
||||
present.
|
||||
|
||||
If annotations (Section 7.7) are being collected, they are collected
|
||||
from this keyword's subschema in the usual way, including when the
|
||||
keyword is present without either "then" or "else".
|
||||
"""
|
||||
|
||||
then: Optional[Union[Reference, "Schema"]] = None
|
||||
"""
|
||||
This keyword's value MUST be a valid JSON Schema.
|
||||
|
||||
When "if" is present, and the instance successfully validates against
|
||||
its subschema, then validation succeeds against this keyword if the
|
||||
instance also successfully validates against this keyword's
|
||||
subschema.
|
||||
|
||||
This keyword has no effect when "if" is absent, or when the instance
|
||||
fails to validate against its subschema. Implementations MUST NOT
|
||||
evaluate the instance against this keyword, for either validation or
|
||||
annotation collection purposes, in such cases.
|
||||
"""
|
||||
|
||||
schema_else: Optional[Union[Reference, "Schema"]] = Field(
|
||||
default=None, alias="else"
|
||||
)
|
||||
"""
|
||||
This keyword's value MUST be a valid JSON Schema.
|
||||
|
||||
When "if" is present, and the instance fails to validate against its
|
||||
subschema, then validation succeeds against this keyword if the
|
||||
instance successfully validates against this keyword's subschema.
|
||||
|
||||
This keyword has no effect when "if" is absent, or when the instance
|
||||
successfully validates against its subschema. Implementations MUST
|
||||
NOT evaluate the instance against this keyword, for either validation
|
||||
or annotation collection purposes, in such cases.
|
||||
"""
|
||||
|
||||
dependentSchemas: Optional[Dict[str, Union[Reference, "Schema"]]] = None
|
||||
"""
|
||||
This keyword specifies subschemas that are evaluated if the instance
|
||||
is an object and contains a certain property.
|
||||
|
||||
This keyword's value MUST be an object. Each value in the object
|
||||
MUST be a valid JSON Schema.
|
||||
|
||||
If the object key is a property in the instance, the entire instance
|
||||
must validate against the subschema. Its use is dependent on the
|
||||
presence of the property.
|
||||
|
||||
Omitting this keyword has the same behavior as an empty object.
|
||||
"""
|
||||
|
||||
prefixItems: Optional[List[Union[Reference, "Schema"]]] = None
|
||||
"""
|
||||
The value of "prefixItems" MUST be a non-empty array of valid JSON
|
||||
Schemas.
|
||||
|
||||
Validation succeeds if each element of the instance validates against
|
||||
the schema at the same position, if any. This keyword does not
|
||||
constrain the length of the array. If the array is longer than this
|
||||
keyword's value, this keyword validates only the prefix of matching
|
||||
length.
|
||||
|
||||
This keyword produces an annotation value which is the largest index
|
||||
to which this keyword applied a subschema. The value MAY be a
|
||||
boolean true if a subschema was applied to every index of the
|
||||
instance, such as is produced by the "items" keyword. This
|
||||
annotation affects the behavior of "items" and "unevaluatedItems".
|
||||
|
||||
Omitting this keyword has the same assertion behavior as an empty
|
||||
array.
|
||||
"""
|
||||
|
||||
items: Optional[Union[Reference, "Schema"]] = None
|
||||
"""
|
||||
The value of "items" MUST be a valid JSON Schema.
|
||||
|
||||
This keyword applies its subschema to all instance elements at
|
||||
indexes greater than the length of the "prefixItems" array in the
|
||||
same schema object, as reported by the annotation result of that
|
||||
"prefixItems" keyword. If no such annotation result exists, "items"
|
||||
applies its subschema to all instance array elements. [[CREF11: Note
|
||||
that the behavior of "items" without "prefixItems" is identical to
|
||||
that of the schema form of "items" in prior drafts. When
|
||||
"prefixItems" is present, the behavior of "items" is identical to the
|
||||
former "additionalItems" keyword. ]]
|
||||
|
||||
If the "items" subschema is applied to any positions within the
|
||||
instance array, it produces an annotation result of boolean true,
|
||||
indicating that all remaining array elements have been evaluated
|
||||
against this keyword's subschema.
|
||||
|
||||
Omitting this keyword has the same assertion behavior as an empty
|
||||
schema.
|
||||
|
||||
Implementations MAY choose to implement or optimize this keyword in
|
||||
another way that produces the same effect, such as by directly
|
||||
checking for the presence and size of a "prefixItems" array.
|
||||
Implementations that do not support annotation collection MUST do so.
|
||||
"""
|
||||
|
||||
contains: Optional[Union[Reference, "Schema"]] = None
|
||||
"""
|
||||
The value of this keyword MUST be a valid JSON Schema.
|
||||
|
||||
An array instance is valid against "contains" if at least one of its
|
||||
elements is valid against the given schema. The subschema MUST be
|
||||
applied to every array element even after the first match has been
|
||||
found, in order to collect annotations for use by other keywords.
|
||||
This is to ensure that all possible annotations are collected.
|
||||
|
||||
Logically, the validation result of applying the value subschema to
|
||||
each item in the array MUST be ORed with "false", resulting in an
|
||||
overall validation result.
|
||||
|
||||
This keyword produces an annotation value which is an array of the
|
||||
indexes to which this keyword validates successfully when applying
|
||||
its subschema, in ascending order. The value MAY be a boolean "true"
|
||||
if the subschema validates successfully when applied to every index
|
||||
of the instance. The annotation MUST be present if the instance
|
||||
array to which this keyword's schema applies is empty.
|
||||
"""
|
||||
|
||||
properties: Optional[Dict[str, Union[Reference, "Schema"]]] = None
|
||||
"""
|
||||
The value of "properties" MUST be an object. Each value of this
|
||||
object MUST be a valid JSON Schema.
|
||||
|
||||
Validation succeeds if, for each name that appears in both the
|
||||
instance and as a name within this keyword's value, the child
|
||||
instance for that name successfully validates against the
|
||||
corresponding schema.
|
||||
|
||||
The annotation result of this keyword is the set of instance property
|
||||
names matched by this keyword.
|
||||
|
||||
Omitting this keyword has the same assertion behavior as an empty
|
||||
object.
|
||||
"""
|
||||
|
||||
patternProperties: Optional[Dict[str, Union[Reference, "Schema"]]] = None
|
||||
"""
|
||||
The value of "patternProperties" MUST be an object. Each property
|
||||
name of this object SHOULD be a valid regular expression, according
|
||||
to the ECMA-262 regular expression dialect. Each property value of
|
||||
this object MUST be a valid JSON Schema.
|
||||
|
||||
Validation succeeds if, for each instance name that matches any
|
||||
regular expressions that appear as a property name in this keyword's
|
||||
value, the child instance for that name successfully validates
|
||||
against each schema that corresponds to a matching regular
|
||||
expression.
|
||||
|
||||
The annotation result of this keyword is the set of instance property
|
||||
names matched by this keyword.
|
||||
|
||||
Omitting this keyword has the same assertion behavior as an empty
|
||||
object.
|
||||
"""
|
||||
|
||||
additionalProperties: Optional[Union[Reference, "Schema", bool]] = None
|
||||
"""
|
||||
The value of "additionalProperties" MUST be a valid JSON Schema.
|
||||
|
||||
The behavior of this keyword depends on the presence and annotation
|
||||
results of "properties" and "patternProperties" within the same
|
||||
schema object. Validation with "additionalProperties" applies only
|
||||
to the child values of instance names that do not appear in the
|
||||
annotation results of either "properties" or "patternProperties".
|
||||
|
||||
For all such properties, validation succeeds if the child instance
|
||||
validates against the "additionalProperties" schema.
|
||||
|
||||
The annotation result of this keyword is the set of instance property
|
||||
names validated by this keyword's subschema.
|
||||
|
||||
Omitting this keyword has the same assertion behavior as an empty
|
||||
schema.
|
||||
|
||||
Implementations MAY choose to implement or optimize this keyword in
|
||||
another way that produces the same effect, such as by directly
|
||||
checking the names in "properties" and the patterns in
|
||||
"patternProperties" against the instance property set.
|
||||
Implementations that do not support annotation collection MUST do so.
|
||||
"""
|
||||
|
||||
propertyNames: Optional[Union[Reference, "Schema"]] = None
|
||||
"""
|
||||
The value of "propertyNames" MUST be a valid JSON Schema.
|
||||
|
||||
If the instance is an object, this keyword validates if every
|
||||
property name in the instance validates against the provided schema.
|
||||
Note the property name that the schema is testing will always be a
|
||||
string.
|
||||
|
||||
Omitting this keyword has the same behavior as an empty schema.
|
||||
"""
|
||||
|
||||
unevaluatedItems: Optional[Union[Reference, "Schema"]] = None
|
||||
"""
|
||||
The value of "unevaluatedItems" MUST be a valid JSON Schema.
|
||||
|
||||
The behavior of this keyword depends on the annotation results of
|
||||
adjacent keywords that apply to the instance location being
|
||||
validated. Specifically, the annotations from "prefixItems",
|
||||
"items", and "contains", which can come from those keywords when they
|
||||
are adjacent to the "unevaluatedItems" keyword. Those three
|
||||
annotations, as well as "unevaluatedItems", can also result from any
|
||||
and all adjacent in-place applicator (Section 10.2) keywords. This
|
||||
includes but is not limited to the in-place applicators defined in
|
||||
this document.
|
||||
|
||||
If no relevant annotations are present, the "unevaluatedItems"
|
||||
subschema MUST be applied to all locations in the array. If a
|
||||
boolean true value is present from any of the relevant annotations,
|
||||
"unevaluatedItems" MUST be ignored. Otherwise, the subschema MUST be
|
||||
applied to any index greater than the largest annotation value for
|
||||
"prefixItems", which does not appear in any annotation value for
|
||||
"contains".
|
||||
|
||||
This means that "prefixItems", "items", "contains", and all in-place
|
||||
applicators MUST be evaluated before this keyword can be evaluated.
|
||||
Authors of extension keywords MUST NOT define an in-place applicator
|
||||
that would need to be evaluated after this keyword.
|
||||
|
||||
If the "unevaluatedItems" subschema is applied to any positions
|
||||
within the instance array, it produces an annotation result of
|
||||
boolean true, analogous to the behavior of "items".
|
||||
|
||||
Omitting this keyword has the same assertion behavior as an empty
|
||||
schema.
|
||||
"""
|
||||
|
||||
unevaluatedProperties: Optional[Union[Reference, "Schema"]] = None
|
||||
"""
|
||||
The value of "unevaluatedProperties" MUST be a valid JSON Schema.
|
||||
|
||||
The behavior of this keyword depends on the annotation results of
|
||||
adjacent keywords that apply to the instance location being
|
||||
validated. Specifically, the annotations from "properties",
|
||||
"patternProperties", and "additionalProperties", which can come from
|
||||
those keywords when they are adjacent to the "unevaluatedProperties"
|
||||
keyword. Those three annotations, as well as
|
||||
"unevaluatedProperties", can also result from any and all adjacent
|
||||
in-place applicator (Section 10.2) keywords. This includes but is
|
||||
not limited to the in-place applicators defined in this document.
|
||||
|
||||
Validation with "unevaluatedProperties" applies only to the child
|
||||
values of instance names that do not appear in the "properties",
|
||||
"patternProperties", "additionalProperties", or
|
||||
"unevaluatedProperties" annotation results that apply to the instance
|
||||
location being validated.
|
||||
|
||||
For all such properties, validation succeeds if the child instance
|
||||
validates against the "unevaluatedProperties" schema.
|
||||
|
||||
This means that "properties", "patternProperties",
|
||||
"additionalProperties", and all in-place applicators MUST be
|
||||
evaluated before this keyword can be evaluated. Authors of extension
|
||||
keywords MUST NOT define an in-place applicator that would need to be
|
||||
evaluated after this keyword.
|
||||
|
||||
The annotation result of this keyword is the set of instance property
|
||||
names validated by this keyword's subschema.
|
||||
|
||||
Omitting this keyword has the same assertion behavior as an empty
|
||||
schema.
|
||||
"""
|
||||
|
||||
"""
|
||||
The following properties are taken directly from the
|
||||
[JSON Schema Validation](https://tools.ietf.org/html/draft-wright-json-schema-validation-00)
|
||||
and follow the same specifications:
|
||||
"""
|
||||
|
||||
type: Optional[Union[DataType, List[DataType]]] = None
|
||||
"""
|
||||
The value of this keyword MUST be either a string or an array. If it
|
||||
is an array, elements of the array MUST be strings and MUST be
|
||||
unique.
|
||||
|
||||
String values MUST be one of the six primitive types ("null",
|
||||
"boolean", "object", "array", "number", or "string"), or "integer"
|
||||
which matches any number with a zero fractional part.
|
||||
|
||||
An instance validates if and only if the instance is in any of the
|
||||
sets listed for this keyword.
|
||||
"""
|
||||
|
||||
enum: Optional[List[Any]] = Field(default=None, **min_length_arg(1))
|
||||
"""
|
||||
The value of this keyword MUST be an array. This array SHOULD have
|
||||
at least one element. Elements in the array SHOULD be unique.
|
||||
|
||||
An instance validates successfully against this keyword if its value
|
||||
is equal to one of the elements in this keyword's array value.
|
||||
|
||||
Elements in the array might be of any type, including null.
|
||||
"""
|
||||
|
||||
const: Optional[Any] = None
|
||||
"""
|
||||
The value of this keyword MAY be of any type, including null.
|
||||
|
||||
Use of this keyword is functionally equivalent to an "enum"
|
||||
(Section 6.1.2) with a single value.
|
||||
|
||||
An instance validates successfully against this keyword if its value
|
||||
is equal to the value of the keyword.
|
||||
"""
|
||||
|
||||
multipleOf: Optional[float] = Field(default=None, gt=0.0)
|
||||
"""
|
||||
The value of "multipleOf" MUST be a number, strictly greater than 0.
|
||||
|
||||
A numeric instance is only valid if division by this keyword's value
|
||||
results in an integer.
|
||||
"""
|
||||
|
||||
maximum: Optional[float] = None
|
||||
"""
|
||||
The value of "maximum" MUST be a number, representing an inclusive
|
||||
upper limit for a numeric instance.
|
||||
|
||||
If the instance is a number, then this keyword validates only if the
|
||||
instance is less than or exactly equal to "maximum".
|
||||
"""
|
||||
|
||||
exclusiveMaximum: Optional[float] = None
|
||||
"""
|
||||
The value of "exclusiveMaximum" MUST be a number, representing an
|
||||
exclusive upper limit for a numeric instance.
|
||||
|
||||
If the instance is a number, then the instance is valid only if it
|
||||
has a value strictly less than (not equal to) "exclusiveMaximum".
|
||||
"""
|
||||
|
||||
minimum: Optional[float] = None
|
||||
"""
|
||||
The value of "minimum" MUST be a number, representing an inclusive
|
||||
lower limit for a numeric instance.
|
||||
|
||||
If the instance is a number, then this keyword validates only if the
|
||||
instance is greater than or exactly equal to "minimum".
|
||||
"""
|
||||
|
||||
exclusiveMinimum: Optional[float] = None
|
||||
"""
|
||||
The value of "exclusiveMinimum" MUST be a number, representing an
|
||||
exclusive lower limit for a numeric instance.
|
||||
|
||||
If the instance is a number, then the instance is valid only if it
|
||||
has a value strictly greater than (not equal to) "exclusiveMinimum".
|
||||
"""
|
||||
|
||||
maxLength: Optional[int] = Field(default=None, ge=0)
|
||||
"""
|
||||
The value of this keyword MUST be a non-negative integer.
|
||||
|
||||
A string instance is valid against this keyword if its length is less
|
||||
than, or equal to, the value of this keyword.
|
||||
|
||||
The length of a string instance is defined as the number of its
|
||||
characters as defined by RFC 8259 [RFC8259].
|
||||
"""
|
||||
|
||||
minLength: Optional[int] = Field(default=None, ge=0)
|
||||
"""
|
||||
The value of this keyword MUST be a non-negative integer.
|
||||
|
||||
A string instance is valid against this keyword if its length is
|
||||
greater than, or equal to, the value of this keyword.
|
||||
|
||||
The length of a string instance is defined as the number of its
|
||||
characters as defined by RFC 8259 [RFC8259].
|
||||
|
||||
Omitting this keyword has the same behavior as a value of 0.
|
||||
"""
|
||||
|
||||
pattern: Optional[str] = None
|
||||
"""
|
||||
The value of this keyword MUST be a string. This string SHOULD be a
|
||||
valid regular expression, according to the ECMA-262 regular
|
||||
expression dialect.
|
||||
|
||||
A string instance is considered valid if the regular expression
|
||||
matches the instance successfully. Recall: regular expressions are
|
||||
not implicitly anchored.
|
||||
"""
|
||||
|
||||
maxItems: Optional[int] = Field(default=None, ge=0)
|
||||
"""
|
||||
The value of this keyword MUST be a non-negative integer.
|
||||
|
||||
An array instance is valid against "maxItems" if its size is less
|
||||
than, or equal to, the value of this keyword.
|
||||
"""
|
||||
|
||||
minItems: Optional[int] = Field(default=None, ge=0)
|
||||
"""
|
||||
The value of this keyword MUST be a non-negative integer.
|
||||
|
||||
An array instance is valid against "minItems" if its size is greater
|
||||
than, or equal to, the value of this keyword.
|
||||
|
||||
Omitting this keyword has the same behavior as a value of 0.
|
||||
"""
|
||||
|
||||
uniqueItems: Optional[bool] = None
|
||||
"""
|
||||
The value of this keyword MUST be a boolean.
|
||||
|
||||
If this keyword has boolean value false, the instance validates
|
||||
successfully. If it has boolean value true, the instance validates
|
||||
successfully if all of its elements are unique.
|
||||
|
||||
Omitting this keyword has the same behavior as a value of false.
|
||||
"""
|
||||
|
||||
maxContains: Optional[int] = Field(default=None, ge=0)
|
||||
"""
|
||||
The value of this keyword MUST be a non-negative integer.
|
||||
|
||||
If "contains" is not present within the same schema object, then this
|
||||
keyword has no effect.
|
||||
|
||||
An instance array is valid against "maxContains" in two ways,
|
||||
depending on the form of the annotation result of an adjacent
|
||||
"contains" [json-schema] keyword. The first way is if the annotation
|
||||
result is an array and the length of that array is less than or equal
|
||||
to the "maxContains" value. The second way is if the annotation
|
||||
result is a boolean "true" and the instance array length is less than
|
||||
or equal to the "maxContains" value.
|
||||
"""
|
||||
|
||||
minContains: Optional[int] = Field(default=None, ge=0)
|
||||
"""
|
||||
The value of this keyword MUST be a non-negative integer.
|
||||
|
||||
If "contains" is not present within the same schema object, then this
|
||||
keyword has no effect.
|
||||
|
||||
An instance array is valid against "minContains" in two ways,
|
||||
depending on the form of the annotation result of an adjacent
|
||||
"contains" [json-schema] keyword. The first way is if the annotation
|
||||
result is an array and the length of that array is greater than or
|
||||
equal to the "minContains" value. The second way is if the
|
||||
annotation result is a boolean "true" and the instance array length
|
||||
is greater than or equal to the "minContains" value.
|
||||
|
||||
A value of 0 is allowed, but is only useful for setting a range of
|
||||
occurrences from 0 to the value of "maxContains". A value of 0 with
|
||||
no "maxContains" causes "contains" to always pass validation.
|
||||
|
||||
Omitting this keyword has the same behavior as a value of 1.
|
||||
"""
|
||||
|
||||
maxProperties: Optional[int] = Field(default=None, ge=0)
|
||||
"""
|
||||
The value of this keyword MUST be a non-negative integer.
|
||||
|
||||
An object instance is valid against "maxProperties" if its number of
|
||||
properties is less than, or equal to, the value of this keyword.
|
||||
"""
|
||||
|
||||
minProperties: Optional[int] = Field(default=None, ge=0)
|
||||
"""
|
||||
The value of this keyword MUST be a non-negative integer.
|
||||
|
||||
An object instance is valid against "minProperties" if its number of
|
||||
properties is greater than, or equal to, the value of this keyword.
|
||||
|
||||
Omitting this keyword has the same behavior as a value of 0.
|
||||
"""
|
||||
|
||||
required: Optional[List[str]] = None
|
||||
"""
|
||||
The value of this keyword MUST be an array. Elements of this array,
|
||||
if any, MUST be strings, and MUST be unique.
|
||||
|
||||
An object instance is valid against this keyword if every item in the
|
||||
array is the name of a property in the instance.
|
||||
|
||||
Omitting this keyword has the same behavior as an empty array.
|
||||
"""
|
||||
|
||||
dependentRequired: Optional[Dict[str, List[str]]] = None
|
||||
"""
|
||||
The value of this keyword MUST be an object. Properties in this
|
||||
object, if any, MUST be arrays. Elements in each array, if any, MUST
|
||||
be strings, and MUST be unique.
|
||||
|
||||
This keyword specifies properties that are required if a specific
|
||||
other property is present. Their requirement is dependent on the
|
||||
presence of the other property.
|
||||
|
||||
Validation succeeds if, for each name that appears in both the
|
||||
instance and as a name within this keyword's value, every item in the
|
||||
corresponding array is also the name of a property in the instance.
|
||||
|
||||
Omitting this keyword has the same behavior as an empty object.
|
||||
"""
|
||||
|
||||
schema_format: Optional[str] = Field(default=None, alias="format")
|
||||
"""
|
||||
From OpenAPI:
|
||||
See [Data Type Formats](#dataTypeFormat) for further details.
|
||||
While relying on JSON Schema's defined formats, the OAS offers a few additional
|
||||
predefined formats.
|
||||
|
||||
From JSON Schema:
|
||||
Structural validation alone may be insufficient to allow an
|
||||
application to correctly utilize certain values. The "format"
|
||||
annotation keyword is defined to allow schema authors to convey
|
||||
semantic information for a fixed subset of values which are
|
||||
accurately described by authoritative resources, be they RFCs or
|
||||
other external specifications.
|
||||
|
||||
The value of this keyword is called a format attribute. It MUST be a
|
||||
string. A format attribute can generally only validate a given set
|
||||
of instance types. If the type of the instance to validate is not in
|
||||
this set, validation for this format attribute and instance SHOULD
|
||||
succeed. All format attributes defined in this section apply to
|
||||
strings, but a format attribute can be specified to apply to any
|
||||
instance types defined in the data model defined in the core JSON
|
||||
Schema. [json-schema] [[CREF1: Note that the "type" keyword in this
|
||||
specification defines an "integer" type which is not part of the data
|
||||
model. Therefore a format attribute can be limited to numbers, but
|
||||
not specifically to integers. However, a numeric format can be used
|
||||
alongside the "type" keyword with a value of "integer", or could be
|
||||
explicitly defined to always pass if the number is not an integer,
|
||||
which produces essentially the same behavior as only applying to
|
||||
integers. ]]
|
||||
"""
|
||||
|
||||
contentEncoding: Optional[str] = None
|
||||
"""
|
||||
If the instance value is a string, this property defines that the
|
||||
string SHOULD be interpreted as binary data and decoded using the
|
||||
encoding named by this property.
|
||||
|
||||
Possible values indicating base 16, 32, and 64 encodings with several
|
||||
variations are listed in RFC 4648 [RFC4648]. Additionally, sections
|
||||
6.7 and 6.8 of RFC 2045 [RFC2045] provide encodings used in MIME. As
|
||||
"base64" is defined in both RFCs, the definition from RFC 4648 SHOULD
|
||||
be assumed unless the string is specifically intended for use in a
|
||||
MIME context. Note that all of these encodings result in strings
|
||||
consisting only of 7-bit ASCII characters. Therefore, this keyword
|
||||
has no meaning for strings containing characters outside of that
|
||||
range.
|
||||
|
||||
If this keyword is absent, but "contentMediaType" is present, this
|
||||
indicates that the encoding is the identity encoding, meaning that no
|
||||
transformation was needed in order to represent the content in a
|
||||
UTF-8 string.
|
||||
"""
|
||||
|
||||
contentMediaType: Optional[str] = None
|
||||
"""
|
||||
If the instance is a string, this property indicates the media type
|
||||
of the contents of the string. If "contentEncoding" is present, this
|
||||
property describes the decoded string.
|
||||
|
||||
The value of this property MUST be a string, which MUST be a media
|
||||
type, as defined by RFC 2046 [RFC2046].
|
||||
"""
|
||||
|
||||
contentSchema: Optional[Union[Reference, "Schema"]] = None
|
||||
"""
|
||||
If the instance is a string, and if "contentMediaType" is present,
|
||||
this property contains a schema which describes the structure of the
|
||||
string.
|
||||
|
||||
This keyword MAY be used with any media type that can be mapped into
|
||||
JSON Schema's data model.
|
||||
|
||||
The value of this property MUST be a valid JSON schema. It SHOULD be
|
||||
ignored if "contentMediaType" is not present.
|
||||
"""
|
||||
|
||||
title: Optional[str] = None
|
||||
"""
|
||||
The value of "title" MUST be a string.
|
||||
|
||||
The title can be used to decorate a user interface with
|
||||
information about the data produced by this user interface.
|
||||
A title will preferably be short.
|
||||
"""
|
||||
|
||||
description: Optional[str] = None
|
||||
"""
|
||||
From OpenAPI:
|
||||
[CommonMark syntax](https://spec.commonmark.org/) MAY be used for rich text
|
||||
representation.
|
||||
|
||||
From JSON Schema:
|
||||
The value "description" MUST be a string.
|
||||
|
||||
The description can be used to decorate a user interface with
|
||||
information about the data produced by this user interface.
|
||||
A description will provide explanation about the purpose of
|
||||
the instance described by this schema.
|
||||
"""
|
||||
|
||||
default: Optional[Any] = None
|
||||
"""
|
||||
There are no restrictions placed on the value of this keyword. When
|
||||
multiple occurrences of this keyword are applicable to a single sub-
|
||||
instance, implementations SHOULD remove duplicates.
|
||||
|
||||
This keyword can be used to supply a default JSON value associated
|
||||
with a particular schema. It is RECOMMENDED that a default value be
|
||||
valid against the associated schema.
|
||||
"""
|
||||
|
||||
deprecated: Optional[bool] = None
|
||||
"""
|
||||
The value of this keyword MUST be a boolean. When multiple
|
||||
occurrences of this keyword are applicable to a single sub-instance,
|
||||
applications SHOULD consider the instance location to be deprecated
|
||||
if any occurrence specifies a true value.
|
||||
|
||||
If "deprecated" has a value of boolean true, it indicates that
|
||||
applications SHOULD refrain from usage of the declared property. It
|
||||
MAY mean the property is going to be removed in the future.
|
||||
|
||||
A root schema containing "deprecated" with a value of true indicates
|
||||
that the entire resource being described MAY be removed in the
|
||||
future.
|
||||
|
||||
The "deprecated" keyword applies to each instance location to which
|
||||
the schema object containing the keyword successfully applies. This
|
||||
can result in scenarios where every array item or object property is
|
||||
deprecated even though the containing array or object is not.
|
||||
|
||||
Omitting this keyword has the same behavior as a value of false.
|
||||
"""
|
||||
|
||||
readOnly: Optional[bool] = None
|
||||
"""
|
||||
The value of "readOnly" MUST be a boolean. When multiple
|
||||
occurrences of this keyword are applicable to a single sub-instance,
|
||||
the resulting behavior SHOULD be as for a true value if any
|
||||
occurrence specifies a true value, and SHOULD be as for a false value
|
||||
otherwise.
|
||||
|
||||
If "readOnly" has a value of boolean true, it indicates that the
|
||||
value of the instance is managed exclusively by the owning authority,
|
||||
and attempts by an application to modify the value of this property
|
||||
are expected to be ignored or rejected by that owning authority.
|
||||
|
||||
An instance document that is marked as "readOnly" for the entire
|
||||
document MAY be ignored if sent to the owning authority, or MAY
|
||||
result in an error, at the authority's discretion.
|
||||
|
||||
For example, "readOnly" would be used to mark a database-generated
|
||||
serial number as read-only, while "writeOnly" would be used to mark a
|
||||
password input field.
|
||||
|
||||
This keyword can be used to assist in user interface instance
|
||||
generation. In particular, an application MAY choose to use a widget
|
||||
that hides input values as they are typed for write-only fields.
|
||||
|
||||
Omitting these keywords has the same behavior as values of false.
|
||||
"""
|
||||
|
||||
writeOnly: Optional[bool] = None
|
||||
"""
|
||||
The value of "writeOnly" MUST be a boolean. When multiple
|
||||
occurrences of this keyword are applicable to a single sub-instance,
|
||||
the resulting behavior SHOULD be as for a true value if any
|
||||
occurrence specifies a true value, and SHOULD be as for a false value
|
||||
otherwise.
|
||||
|
||||
If "writeOnly" has a value of boolean true, it indicates that the
|
||||
value is never present when the instance is retrieved from the owning
|
||||
authority. It can be present when sent to the owning authority to
|
||||
update or create the document (or the resource it represents), but it
|
||||
will not be included in any updated or newly created version of the
|
||||
instance.
|
||||
|
||||
An instance document that is marked as "writeOnly" for the entire
|
||||
document MAY be returned as a blank document of some sort, or MAY
|
||||
produce an error upon retrieval, or have the retrieval request
|
||||
ignored, at the authority's discretion.
|
||||
|
||||
For example, "readOnly" would be used to mark a database-generated
|
||||
serial number as read-only, while "writeOnly" would be used to mark a
|
||||
password input field.
|
||||
|
||||
This keyword can be used to assist in user interface instance
|
||||
generation. In particular, an application MAY choose to use a widget
|
||||
that hides input values as they are typed for write-only fields.
|
||||
|
||||
Omitting these keywords has the same behavior as values of false.
|
||||
"""
|
||||
|
||||
examples: Optional[List[Any]] = None
|
||||
"""
|
||||
The value of this keyword MUST be an array. There are no
|
||||
restrictions placed on the values within the array. When multiple
|
||||
occurrences of this keyword are applicable to a single sub-instance,
|
||||
implementations MUST provide a flat array of all values rather than
|
||||
an array of arrays.
|
||||
|
||||
This keyword can be used to provide sample JSON values associated
|
||||
with a particular schema, for the purpose of illustrating usage. It
|
||||
is RECOMMENDED that these values be valid against the associated
|
||||
schema.
|
||||
|
||||
Implementations MAY use the value(s) of "default", if present, as an
|
||||
additional example. If "examples" is absent, "default" MAY still be
|
||||
used in this manner.
|
||||
"""
|
||||
|
||||
"""
|
||||
The OpenAPI Specification's base vocabulary is comprised of the following keywords:
|
||||
"""
|
||||
|
||||
discriminator: Optional[Discriminator] = None
|
||||
"""
|
||||
Adds support for polymorphism.
|
||||
The discriminator is an object name that is used to differentiate between other
|
||||
schemas which may satisfy the payload description.
|
||||
See [Composition and Inheritance](#schemaComposition) for more details.
|
||||
"""
|
||||
|
||||
xml: Optional[XML] = None
|
||||
"""
|
||||
This MAY be used only on properties schemas.
|
||||
It has no effect on root schemas.
|
||||
Adds additional metadata to describe the XML representation of this property.
|
||||
"""
|
||||
|
||||
externalDocs: Optional[ExternalDocumentation] = None
|
||||
"""
|
||||
Additional external documentation for this schema.
|
||||
"""
|
||||
|
||||
example: Optional[Any] = None
|
||||
"""
|
||||
A free-form property to include an example of an instance for this schema.
|
||||
To represent examples that cannot be naturally represented in JSON or YAML,
|
||||
a string value can be used to contain the example with escaping where necessary.
|
||||
|
||||
Deprecated: The example property has been deprecated in favor of the JSON Schema
|
||||
examples keyword.
|
||||
Use of example is discouraged, and later versions of this specification may remove
|
||||
it.
|
||||
"""
|
||||
|
||||
if PYDANTIC_V2:
|
||||
model_config = ConfigDict(
|
||||
extra="allow",
|
||||
populate_by_name=True,
|
||||
json_schema_extra={"examples": _examples},
|
||||
)
|
||||
|
||||
else:
|
||||
|
||||
class Config:
|
||||
extra = Extra.allow
|
||||
allow_population_by_field_name = True
|
||||
schema_extra = {"examples": _examples}
|
||||
|
||||
|
||||
if TYPE_CHECKING:
|
||||
|
||||
def schema_validate(
|
||||
obj: Any,
|
||||
*,
|
||||
strict: Optional[bool] = None,
|
||||
from_attributes: Optional[bool] = None,
|
||||
context: Optional[Dict[str, Any]] = None
|
||||
) -> Schema: ...
|
||||
|
||||
elif PYDANTIC_V2:
|
||||
schema_validate = Schema.model_validate
|
||||
|
||||
else:
|
||||
schema_validate = Schema.parse_obj
|
33
openapi_pydantic/v3/v3_1/security_requirement.py
Normal file
33
openapi_pydantic/v3/v3_1/security_requirement.py
Normal file
|
@ -0,0 +1,33 @@
|
|||
from typing import Dict, List
|
||||
|
||||
SecurityRequirement = Dict[str, List[str]]
|
||||
"""
|
||||
Lists the required security schemes to execute this operation.
|
||||
The name used for each property MUST correspond to a security scheme declared in the
|
||||
[Security Schemes](#componentsSecuritySchemes) under the
|
||||
[Components Object](#componentsObject).
|
||||
|
||||
Security Requirement Objects that contain multiple schemes require that
|
||||
all schemes MUST be satisfied for a request to be authorized.
|
||||
This enables support for scenarios where multiple query parameters or HTTP headers
|
||||
are required to convey security information.
|
||||
|
||||
When a list of Security Requirement Objects is defined on the
|
||||
[OpenAPI Object](#oasObject) or [Operation Object](#operationObject),
|
||||
only one of the Security Requirement Objects in the list needs to be satisfied to
|
||||
authorize the request.
|
||||
"""
|
||||
|
||||
"""Patterned Fields"""
|
||||
|
||||
# {name}: List[str]
|
||||
"""
|
||||
Each name MUST correspond to a security scheme which is declared
|
||||
in the [Security Schemes](#componentsSecuritySchemes) under the
|
||||
[Components Object](#componentsObject).
|
||||
If the security scheme is of type `"oauth2"` or `"openIdConnect"`,
|
||||
then the value is a list of scope names required for the execution,
|
||||
and the list MAY be empty if authorization does not require a specified scope.
|
||||
For other security scheme types, the array MAY contain a list of role names which are
|
||||
required for the execution, but are not otherwise defined or exchanged in-band.
|
||||
"""
|
119
openapi_pydantic/v3/v3_1/security_scheme.py
Normal file
119
openapi_pydantic/v3/v3_1/security_scheme.py
Normal file
|
@ -0,0 +1,119 @@
|
|||
from typing import Optional
|
||||
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
from openapi_pydantic.compat import PYDANTIC_V2, ConfigDict, Extra
|
||||
|
||||
from .oauth_flows import OAuthFlows
|
||||
|
||||
_examples = [
|
||||
{"type": "http", "scheme": "basic"},
|
||||
{"type": "apiKey", "name": "api_key", "in": "header"},
|
||||
{"type": "http", "scheme": "bearer", "bearerFormat": "JWT"},
|
||||
{
|
||||
"type": "oauth2",
|
||||
"flows": {
|
||||
"implicit": {
|
||||
"authorizationUrl": "https://example.com/api/oauth/dialog",
|
||||
"scopes": {
|
||||
"write:pets": "modify pets in your account",
|
||||
"read:pets": "read your pets",
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
"type": "openIdConnect",
|
||||
"openIdConnectUrl": "https://example.com/openIdConnect",
|
||||
},
|
||||
{
|
||||
"type": "openIdConnect",
|
||||
"openIdConnectUrl": "openIdConnect",
|
||||
}, # issue #5: allow relative path
|
||||
]
|
||||
|
||||
|
||||
class SecurityScheme(BaseModel):
|
||||
"""
|
||||
Defines a security scheme that can be used by the operations.
|
||||
|
||||
Supported schemes are HTTP authentication,
|
||||
an API key (either as a header, a cookie parameter or as a query parameter),
|
||||
mutual TLS (use of a client certificate),
|
||||
OAuth2's common flows (implicit, password, client credentials and authorization
|
||||
code) as defined in [RFC6749](https://tools.ietf.org/html/rfc6749),
|
||||
and [OpenID Connect Discovery](https://tools.ietf.org/html/draft-ietf-oauth-discovery-06).
|
||||
|
||||
Please note that as of 2020, the implicit flow is about to be deprecated by
|
||||
[OAuth 2.0 Security Best Current Practice](https://tools.ietf.org/html/draft-ietf-oauth-security-topics).
|
||||
Recommended for most use case is Authorization Code Grant flow with PKCE.
|
||||
"""
|
||||
|
||||
type: str
|
||||
"""
|
||||
**REQUIRED**. The type of the security scheme.
|
||||
Valid values are `"apiKey"`, `"http"`, "mutualTLS", `"oauth2"`, `"openIdConnect"`.
|
||||
"""
|
||||
|
||||
description: Optional[str] = None
|
||||
"""
|
||||
A description for security scheme.
|
||||
[CommonMark syntax](https://spec.commonmark.org/) MAY be used for rich text
|
||||
representation.
|
||||
"""
|
||||
|
||||
name: Optional[str] = None
|
||||
"""
|
||||
**REQUIRED** for `apiKey`. The name of the header, query or cookie parameter to be
|
||||
used.
|
||||
"""
|
||||
|
||||
security_scheme_in: Optional[str] = Field(alias="in", default=None)
|
||||
"""
|
||||
**REQUIRED** for `apiKey`. The location of the API key. Valid values are `"query"`,
|
||||
`"header"` or `"cookie"`.
|
||||
"""
|
||||
|
||||
scheme: Optional[str] = None
|
||||
"""
|
||||
**REQUIRED** for `http`. The name of the HTTP Authorization scheme to be used in the
|
||||
[Authorization header as defined in RFC7235](https://tools.ietf.org/html/rfc7235#section-5.1).
|
||||
|
||||
The values used SHOULD be registered in the
|
||||
[IANA Authentication Scheme registry](https://www.iana.org/assignments/http-authschemes/http-authschemes.xhtml).
|
||||
"""
|
||||
|
||||
bearerFormat: Optional[str] = None
|
||||
"""
|
||||
A hint to the client to identify how the bearer token is formatted.
|
||||
|
||||
Bearer tokens are usually generated by an authorization server,
|
||||
so this information is primarily for documentation purposes.
|
||||
"""
|
||||
|
||||
flows: Optional[OAuthFlows] = None
|
||||
"""
|
||||
**REQUIRED** for `oauth2`. An object containing configuration information for the
|
||||
flow types supported.
|
||||
"""
|
||||
|
||||
openIdConnectUrl: Optional[str] = None
|
||||
"""
|
||||
**REQUIRED** for `openIdConnect`. OpenId Connect URL to discover OAuth2
|
||||
configuration values. This MUST be in the form of a URL. The OpenID Connect
|
||||
standard requires the use of TLS.
|
||||
"""
|
||||
|
||||
if PYDANTIC_V2:
|
||||
model_config = ConfigDict(
|
||||
extra="allow",
|
||||
populate_by_name=True,
|
||||
json_schema_extra={"examples": _examples},
|
||||
)
|
||||
|
||||
else:
|
||||
|
||||
class Config:
|
||||
extra = Extra.allow
|
||||
allow_population_by_field_name = True
|
||||
schema_extra = {"examples": _examples}
|
67
openapi_pydantic/v3/v3_1/server.py
Normal file
67
openapi_pydantic/v3/v3_1/server.py
Normal file
|
@ -0,0 +1,67 @@
|
|||
from typing import Dict, Optional
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
from openapi_pydantic.compat import PYDANTIC_V2, ConfigDict, Extra
|
||||
|
||||
from .server_variable import ServerVariable
|
||||
|
||||
_examples = [
|
||||
{
|
||||
"url": "https://development.gigantic-server.com/v1",
|
||||
"description": "Development server",
|
||||
},
|
||||
{
|
||||
"url": "https://{username}.gigantic-server.com:{port}/{basePath}",
|
||||
"description": "The production API server",
|
||||
"variables": {
|
||||
"username": {
|
||||
"default": "demo",
|
||||
"description": "this value is assigned by the service "
|
||||
"provider, in this example `gigantic-server.com`",
|
||||
},
|
||||
"port": {"enum": ["8443", "443"], "default": "8443"},
|
||||
"basePath": {"default": "v2"},
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
class Server(BaseModel):
|
||||
"""An object representing a Server."""
|
||||
|
||||
url: str
|
||||
"""
|
||||
**REQUIRED**. A URL to the target host.
|
||||
|
||||
This URL supports Server Variables and MAY be relative,
|
||||
to indicate that the host location is relative to the location where the OpenAPI
|
||||
document is being served.
|
||||
Variable substitutions will be made when a variable is named in `{`brackets`}`.
|
||||
"""
|
||||
|
||||
description: Optional[str] = None
|
||||
"""
|
||||
An optional string describing the host designated by the URL.
|
||||
[CommonMark syntax](https://spec.commonmark.org/) MAY be used for rich text
|
||||
representation.
|
||||
"""
|
||||
|
||||
variables: Optional[Dict[str, ServerVariable]] = None
|
||||
"""
|
||||
A map between a variable name and its value.
|
||||
|
||||
The value is used for substitution in the server's URL template.
|
||||
"""
|
||||
|
||||
if PYDANTIC_V2:
|
||||
model_config = ConfigDict(
|
||||
extra="allow",
|
||||
json_schema_extra={"examples": _examples},
|
||||
)
|
||||
|
||||
else:
|
||||
|
||||
class Config:
|
||||
extra = Extra.allow
|
||||
schema_extra = {"examples": _examples}
|
42
openapi_pydantic/v3/v3_1/server_variable.py
Normal file
42
openapi_pydantic/v3/v3_1/server_variable.py
Normal file
|
@ -0,0 +1,42 @@
|
|||
from typing import List, Optional
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
from openapi_pydantic.compat import PYDANTIC_V2, ConfigDict, Extra
|
||||
|
||||
|
||||
class ServerVariable(BaseModel):
|
||||
"""An object representing a Server Variable for server URL template substitution."""
|
||||
|
||||
enum: Optional[List[str]] = None
|
||||
"""
|
||||
An enumeration of string values to be used if the substitution options are from a
|
||||
limited set. The array SHOULD NOT be empty.
|
||||
"""
|
||||
|
||||
default: str
|
||||
"""
|
||||
**REQUIRED**. The default value to use for substitution,
|
||||
which SHALL be sent if an alternate value is _not_ supplied.
|
||||
Note this behavior is different than the [Schema Object's](#schemaObject) treatment
|
||||
of default values, because in those cases parameter values are optional.
|
||||
If the [`enum`](#serverVariableEnum) is defined, the value MUST exist in the enum's
|
||||
values.
|
||||
"""
|
||||
|
||||
description: Optional[str] = None
|
||||
"""
|
||||
An optional description for the server variable.
|
||||
[CommonMark syntax](https://spec.commonmark.org/) MAY be used for rich text
|
||||
representation.
|
||||
"""
|
||||
|
||||
if PYDANTIC_V2:
|
||||
model_config = ConfigDict(
|
||||
extra="allow",
|
||||
)
|
||||
|
||||
else:
|
||||
|
||||
class Config:
|
||||
extra = Extra.allow
|
47
openapi_pydantic/v3/v3_1/tag.py
Normal file
47
openapi_pydantic/v3/v3_1/tag.py
Normal file
|
@ -0,0 +1,47 @@
|
|||
from typing import Optional
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
from openapi_pydantic.compat import PYDANTIC_V2, ConfigDict, Extra
|
||||
|
||||
from .external_documentation import ExternalDocumentation
|
||||
|
||||
_examples = [{"name": "pet", "description": "Pets operations"}]
|
||||
|
||||
|
||||
class Tag(BaseModel):
|
||||
"""
|
||||
Adds metadata to a single tag that is used by the
|
||||
[Operation Object](#operationObject).
|
||||
It is not mandatory to have a Tag Object per tag defined in the Operation Object
|
||||
instances.
|
||||
"""
|
||||
|
||||
name: str
|
||||
"""
|
||||
**REQUIRED**. The name of the tag.
|
||||
"""
|
||||
|
||||
description: Optional[str] = None
|
||||
"""
|
||||
A short description for the tag.
|
||||
[CommonMark syntax](https://spec.commonmark.org/) MAY be used for rich text
|
||||
representation.
|
||||
"""
|
||||
|
||||
externalDocs: Optional[ExternalDocumentation] = None
|
||||
"""
|
||||
Additional external documentation for this tag.
|
||||
"""
|
||||
|
||||
if PYDANTIC_V2:
|
||||
model_config = ConfigDict(
|
||||
extra="allow",
|
||||
json_schema_extra={"examples": _examples},
|
||||
)
|
||||
|
||||
else:
|
||||
|
||||
class Config:
|
||||
extra = Extra.allow
|
||||
schema_extra = {"examples": _examples}
|
72
openapi_pydantic/v3/v3_1/xml.py
Normal file
72
openapi_pydantic/v3/v3_1/xml.py
Normal file
|
@ -0,0 +1,72 @@
|
|||
from typing import Optional
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
from openapi_pydantic.compat import PYDANTIC_V2, ConfigDict, Extra
|
||||
|
||||
_examples = [
|
||||
{"name": "animal"},
|
||||
{"attribute": True},
|
||||
{"wrapped": True},
|
||||
{"namespace": "http://example.com/schema/sample", "prefix": "sample"},
|
||||
{"name": "aliens", "wrapped": True},
|
||||
]
|
||||
|
||||
|
||||
class XML(BaseModel):
|
||||
"""
|
||||
A metadata object that allows for more fine-tuned XML model definitions.
|
||||
|
||||
When using arrays, XML element names are *not* inferred (for singular/plural forms)
|
||||
and the `name` property SHOULD be used to add that information.
|
||||
See examples for expected behavior.
|
||||
"""
|
||||
|
||||
name: Optional[str] = None
|
||||
"""
|
||||
Replaces the name of the element/attribute used for the described schema property.
|
||||
When defined within `items`, it will affect the name of the individual XML elements
|
||||
within the list.
|
||||
When defined alongside `type` being `array` (outside the `items`),
|
||||
it will affect the wrapping element and only if `wrapped` is `true`.
|
||||
If `wrapped` is `false`, it will be ignored.
|
||||
"""
|
||||
|
||||
namespace: Optional[str] = None
|
||||
"""
|
||||
The URI of the namespace definition.
|
||||
Value MUST be in the form of an absolute URI.
|
||||
"""
|
||||
|
||||
prefix: Optional[str] = None
|
||||
"""
|
||||
The prefix to be used for the [name](#xmlName).
|
||||
"""
|
||||
|
||||
attribute: bool = False
|
||||
"""
|
||||
Declares whether the property definition translates to an attribute instead of an
|
||||
element. Default value is `false`.
|
||||
"""
|
||||
|
||||
wrapped: bool = False
|
||||
"""
|
||||
MAY be used only for an array definition.
|
||||
Signifies whether the array is wrapped
|
||||
(for example, `<books><book/><book/></books>`) or unwrapped (`<book/><book/>`).
|
||||
Default value is `false`.
|
||||
The definition takes effect only when defined alongside `type` being `array`
|
||||
(outside the `items`).
|
||||
"""
|
||||
|
||||
if PYDANTIC_V2:
|
||||
model_config = ConfigDict(
|
||||
extra="allow",
|
||||
json_schema_extra={"examples": _examples},
|
||||
)
|
||||
|
||||
else:
|
||||
|
||||
class Config:
|
||||
extra = Extra.allow
|
||||
schema_extra = {"examples": _examples}
|
Loading…
Add table
Add a link
Reference in a new issue