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

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 11 additions & 11 deletions openapi_schema_pydantic/util.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import logging
from typing import Any, List, Set, Type, TypeVar
from typing import Any, Generic, List, Optional, Set, Type, TypeVar

from pydantic import BaseModel
from pydantic.schema import schema
Expand All @@ -12,16 +12,16 @@
ref_prefix = "#/components/schemas/"


class PydanticSchema(Schema):
class PydanticSchema(Schema, Generic[PydanticType]):
"""Special `Schema` class to indicate a reference from pydantic class"""

schema_class: Type[PydanticType] = ...
schema_class: Type[PydanticType]
"""the class that is used for generate the schema"""


def construct_open_api_with_schema_class(
open_api: OpenAPI,
schema_classes: List[Type[PydanticType]] = None,
schema_classes: Optional[List[Type[BaseModel]]] = None,
scan_for_pydantic_schema_reference: bool = True,
by_alias: bool = True,
) -> OpenAPI:
Expand Down Expand Up @@ -56,22 +56,22 @@ def construct_open_api_with_schema_class(
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.get("definitions"):
if existing_key in schema_definitions["definitions"]:
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(
{key: Schema.parse_obj(schema_dict) for key, schema_dict in schema_definitions.get("definitions").items()}
{key: Schema.parse_obj(schema_dict) for key, schema_dict in schema_definitions["definitions"].items()}
)
else:
new_open_api.components.schemas = {
key: Schema.parse_obj(schema_dict) for key, schema_dict in schema_definitions.get("definitions").items()
key: Schema.parse_obj(schema_dict) for key, schema_dict in schema_definitions["definitions"].items()
}
return new_open_api


def _handle_pydantic_schema(open_api: OpenAPI) -> List[Type[PydanticType]]:
def _handle_pydantic_schema(open_api: OpenAPI) -> List[Type[BaseModel]]:
"""
This function traverses the `OpenAPI` object and

Expand All @@ -84,9 +84,9 @@ def _handle_pydantic_schema(open_api: OpenAPI) -> List[Type[PydanticType]]:
:return: a list of schema classes extracted from `PydanticSchema` objects
"""

pydantic_types: Set[Type[PydanticType]] = set()
pydantic_types: Set[Type[BaseModel]] = set()

def _traverse(obj: Any):
def _traverse(obj: Any) -> None:
if isinstance(obj, BaseModel):
fields = obj.__fields_set__
for field in fields:
Expand Down Expand Up @@ -118,7 +118,7 @@ def _traverse(obj: Any):
return list(pydantic_types)


def _construct_ref_obj(pydantic_schema: PydanticSchema):
def _construct_ref_obj(pydantic_schema: PydanticSchema[PydanticType]) -> Reference:
ref_obj = Reference(ref=ref_prefix + pydantic_schema.schema_class.__name__)
logger.debug(f"ref_obj={ref_obj}")
return ref_obj
60 changes: 30 additions & 30 deletions openapi_schema_pydantic/v3/v3_0_3/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,36 +6,36 @@
https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.3.md#table-of-contents
"""

from .open_api import OpenAPI
from .info import Info
from .contact import Contact
from .license import License
from .server import Server
from .server_variable import ServerVariable
from .components import Components
from .paths import Paths
from .path_item import PathItem
from .operation import Operation
from .external_documentation import ExternalDocumentation
from .parameter import Parameter
from .request_body import RequestBody
from .media_type import MediaType
from .encoding import Encoding
from .responses import Responses
from .response import Response
from .callback import Callback
from .example import Example
from .link import Link
from .header import Header
from .tag import Tag
from .reference import Reference
from .schema import Schema
from .discriminator import Discriminator
from .xml import XML
from .security_scheme import SecurityScheme
from .oauth_flows import OAuthFlows
from .oauth_flow import OAuthFlow
from .security_requirement import SecurityRequirement
from .open_api import OpenAPI as OpenAPI
from .info import Info as Info
from .contact import Contact as Contact
from .license import License as License
from .server import Server as Server
from .server_variable import ServerVariable as ServerVariable
from .components import Components as Components
from .paths import Paths as Paths
from .path_item import PathItem as PathItem
from .operation import Operation as Operation
from .external_documentation import ExternalDocumentation as ExternalDocumentation
from .parameter import Parameter as Parameter
from .request_body import RequestBody as RequestBody
from .media_type import MediaType as MediaType
from .encoding import Encoding as Encoding
from .responses import Responses as Responses
from .response import Response as Response
from .callback import Callback as Callback
from .example import Example as Example
from .link import Link as Link
from .header import Header as Header
from .tag import Tag as Tag
from .reference import Reference as Reference
from .schema import Schema as Schema
from .discriminator import Discriminator as Discriminator
from .xml import XML as XML
from .security_scheme import SecurityScheme as SecurityScheme
from .oauth_flows import OAuthFlows as OAuthFlows
from .oauth_flow import OAuthFlow as OAuthFlow
from .security_requirement import SecurityRequirement as SecurityRequirement


# resolve forward references
Expand Down
5 changes: 4 additions & 1 deletion openapi_schema_pydantic/v3/v3_0_3/callback.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
from typing import Dict
from typing import Dict, TYPE_CHECKING

if TYPE_CHECKING:
from .path_item import PathItem


Callback = Dict[str, "PathItem"]
Expand Down
2 changes: 1 addition & 1 deletion openapi_schema_pydantic/v3/v3_0_3/discriminator.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class Discriminator(BaseModel):
When using the discriminator, _inline_ schemas will not be considered.
"""

propertyName: str = ...
propertyName: str
"""
**REQUIRED**. The name of the property in the payload that will hold the discriminator value.
"""
Expand Down
5 changes: 4 additions & 1 deletion openapi_schema_pydantic/v3/v3_0_3/encoding.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
from typing import Dict, Optional, Union
from typing import Dict, Optional, TYPE_CHECKING, Union

from pydantic import BaseModel, Extra

from .reference import Reference

if TYPE_CHECKING:
from .header import Header


class Encoding(BaseModel):
"""A single encoding definition applied to a single schema property."""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class ExternalDocumentation(BaseModel):
[CommonMark syntax](https://spec.commonmark.org/) MAY be used for rich text representation.
"""

url: AnyUrl = ...
url: AnyUrl
"""
**REQUIRED**. The URL for the target documentation.
Value MUST be in the format of a URL.
Expand Down
4 changes: 2 additions & 2 deletions openapi_schema_pydantic/v3/v3_0_3/info.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class Info(BaseModel):
and MAY be presented in editing or documentation generation tools for convenience.
"""

title: str = ...
title: str
"""
**REQUIRED**. The title of the API.
"""
Expand All @@ -40,7 +40,7 @@ class Info(BaseModel):
The license information for the exposed API.
"""

version: str = ...
version: str
"""
**REQUIRED**. The version of the OpenAPI document
(which is distinct from the [OpenAPI Specification version](#oasVersion) or the API implementation version).
Expand Down
2 changes: 1 addition & 1 deletion openapi_schema_pydantic/v3/v3_0_3/license.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ class License(BaseModel):
License information for the exposed API.
"""

name: str = ...
name: str
"""
**REQUIRED**. The license name used for the API.
"""
Expand Down
2 changes: 1 addition & 1 deletion openapi_schema_pydantic/v3/v3_0_3/oauth_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ class OAuthFlow(BaseModel):
The URL to be used for obtaining refresh tokens. This MUST be in the form of a URL.
"""

scopes: Dict[str, str] = ...
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.
Expand Down
4 changes: 2 additions & 2 deletions openapi_schema_pydantic/v3/v3_0_3/open_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class OpenAPI(BaseModel):
This is *not* related to the API [`info.version`](#infoVersion) string.
"""

info: Info = ...
info: Info
"""
**REQUIRED**. Provides metadata about the API. The metadata MAY be used by tooling as required.
"""
Expand All @@ -34,7 +34,7 @@ class OpenAPI(BaseModel):
the default value would be a [Server Object](#serverObject) with a [url](#serverUrl) value of `/`.
"""

paths: Paths = ...
paths: Paths
"""
**REQUIRED**. The available paths and operations for the API.
"""
Expand Down
2 changes: 1 addition & 1 deletion openapi_schema_pydantic/v3/v3_0_3/operation.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ class Operation(BaseModel):
In other cases where the HTTP spec is vague, `requestBody` SHALL be ignored by consumers.
"""

responses: Responses = ...
responses: Responses
"""
**REQUIRED**. The list of possible responses as they are returned from executing this operation.
"""
Expand Down
2 changes: 1 addition & 1 deletion openapi_schema_pydantic/v3/v3_0_3/parameter.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class Parameter(BaseModel):

"""Fixed Fields"""

name: str = ...
name: str
"""
**REQUIRED**. The name of the parameter.
Parameter names are *case sensitive*.
Expand Down
2 changes: 1 addition & 1 deletion openapi_schema_pydantic/v3/v3_0_3/request_body.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class RequestBody(BaseModel):
[CommonMark syntax](https://spec.commonmark.org/) MAY be used for rich text representation.
"""

content: Dict[str, MediaType] = ...
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)
Expand Down
2 changes: 1 addition & 1 deletion openapi_schema_pydantic/v3/v3_0_3/response.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class Response(BaseModel):
static `links` to operations based on the response.
"""

description: str = ...
description: str
"""
**REQUIRED**. A short description of the response.
[CommonMark syntax](https://spec.commonmark.org/) MAY be used for rich text representation.
Expand Down
2 changes: 1 addition & 1 deletion openapi_schema_pydantic/v3/v3_0_3/security_scheme.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class SecurityScheme(BaseModel):
and [OpenID Connect Discovery](https://tools.ietf.org/html/draft-ietf-oauth-discovery-06).
"""

type: str = ...
type: str
"""
**REQUIRED**. The type of the security scheme.
Valid values are `"apiKey"`, `"http"`, `"oauth2"`, `"openIdConnect"`.
Expand Down
2 changes: 1 addition & 1 deletion openapi_schema_pydantic/v3/v3_0_3/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
class Server(BaseModel):
"""An object representing a Server."""

url: str = ...
url: str
"""
**REQUIRED**. A URL to the target host.

Expand Down
2 changes: 1 addition & 1 deletion openapi_schema_pydantic/v3/v3_0_3/server_variable.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class ServerVariable(BaseModel):
The array SHOULD NOT be empty.
"""

default: str = ...
default: str
"""
**REQUIRED**. The default value to use for substitution,
which SHALL be sent if an alternate value is _not_ supplied.
Expand Down
2 changes: 1 addition & 1 deletion openapi_schema_pydantic/v3/v3_0_3/tag.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ class Tag(BaseModel):
It is not mandatory to have a Tag Object per tag defined in the Operation Object instances.
"""

name: str = ...
name: str
"""
**REQUIRED**. The name of the tag.
"""
Expand Down
22 changes: 11 additions & 11 deletions openapi_schema_pydantic/v3/v3_0_3/util.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import logging
from typing import Any, List, Set, Type, TypeVar
from typing import Any, Generic, List, Optional, Set, Type, TypeVar

from pydantic import BaseModel
from pydantic.schema import schema
Expand All @@ -12,16 +12,16 @@
ref_prefix = "#/components/schemas/"


class PydanticSchema(Schema):
class PydanticSchema(Schema, Generic[PydanticType]):
"""Special `Schema` class to indicate a reference from pydantic class"""

schema_class: Type[PydanticType] = ...
schema_class: Type[PydanticType]
"""the class that is used for generate the schema"""


def construct_open_api_with_schema_class(
open_api: OpenAPI,
schema_classes: List[Type[PydanticType]] = None,
schema_classes: Optional[List[Type[BaseModel]]] = None,
scan_for_pydantic_schema_reference: bool = True,
by_alias: bool = True,
) -> OpenAPI:
Expand Down Expand Up @@ -56,22 +56,22 @@ def construct_open_api_with_schema_class(
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.get("definitions"):
if existing_key in schema_definitions["definitions"]:
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(
{key: Schema.parse_obj(schema_dict) for key, schema_dict in schema_definitions.get("definitions").items()}
{key: Schema.parse_obj(schema_dict) for key, schema_dict in schema_definitions["definitions"].items()}
)
else:
new_open_api.components.schemas = {
key: Schema.parse_obj(schema_dict) for key, schema_dict in schema_definitions.get("definitions").items()
key: Schema.parse_obj(schema_dict) for key, schema_dict in schema_definitions["definitions"].items()
}
return new_open_api


def _handle_pydantic_schema(open_api: OpenAPI) -> List[Type[PydanticType]]:
def _handle_pydantic_schema(open_api: OpenAPI) -> List[Type[BaseModel]]:
"""
This function traverses the `OpenAPI` object and

Expand All @@ -84,9 +84,9 @@ def _handle_pydantic_schema(open_api: OpenAPI) -> List[Type[PydanticType]]:
:return: a list of schema classes extracted from `PydanticSchema` objects
"""

pydantic_types: Set[Type[PydanticType]] = set()
pydantic_types: Set[Type[BaseModel]] = set()

def _traverse(obj: Any):
def _traverse(obj: Any) -> None:
if isinstance(obj, BaseModel):
fields = obj.__fields_set__
for field in fields:
Expand Down Expand Up @@ -118,7 +118,7 @@ def _traverse(obj: Any):
return list(pydantic_types)


def _construct_ref_obj(pydantic_schema: PydanticSchema):
def _construct_ref_obj(pydantic_schema: PydanticSchema[PydanticType]) -> Reference:
ref_obj = Reference(ref=ref_prefix + pydantic_schema.schema_class.__name__)
logger.debug(f"ref_obj={ref_obj}")
return ref_obj
Loading