diff --git a/openapi_schema_pydantic/util.py b/openapi_schema_pydantic/util.py index cb57969..d758e8f 100644 --- a/openapi_schema_pydantic/util.py +++ b/openapi_schema_pydantic/util.py @@ -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 @@ -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: @@ -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 @@ -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: @@ -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 diff --git a/openapi_schema_pydantic/v3/v3_0_3/__init__.py b/openapi_schema_pydantic/v3/v3_0_3/__init__.py index 666664a..1985c6b 100644 --- a/openapi_schema_pydantic/v3/v3_0_3/__init__.py +++ b/openapi_schema_pydantic/v3/v3_0_3/__init__.py @@ -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 diff --git a/openapi_schema_pydantic/v3/v3_0_3/callback.py b/openapi_schema_pydantic/v3/v3_0_3/callback.py index 35bea75..e849bf6 100644 --- a/openapi_schema_pydantic/v3/v3_0_3/callback.py +++ b/openapi_schema_pydantic/v3/v3_0_3/callback.py @@ -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"] diff --git a/openapi_schema_pydantic/v3/v3_0_3/discriminator.py b/openapi_schema_pydantic/v3/v3_0_3/discriminator.py index 699d4ea..525c25b 100644 --- a/openapi_schema_pydantic/v3/v3_0_3/discriminator.py +++ b/openapi_schema_pydantic/v3/v3_0_3/discriminator.py @@ -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. """ diff --git a/openapi_schema_pydantic/v3/v3_0_3/encoding.py b/openapi_schema_pydantic/v3/v3_0_3/encoding.py index 2821da4..16f2dad 100644 --- a/openapi_schema_pydantic/v3/v3_0_3/encoding.py +++ b/openapi_schema_pydantic/v3/v3_0_3/encoding.py @@ -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.""" diff --git a/openapi_schema_pydantic/v3/v3_0_3/external_documentation.py b/openapi_schema_pydantic/v3/v3_0_3/external_documentation.py index 599778c..0da41c3 100644 --- a/openapi_schema_pydantic/v3/v3_0_3/external_documentation.py +++ b/openapi_schema_pydantic/v3/v3_0_3/external_documentation.py @@ -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. diff --git a/openapi_schema_pydantic/v3/v3_0_3/info.py b/openapi_schema_pydantic/v3/v3_0_3/info.py index ee12e09..937ba8c 100644 --- a/openapi_schema_pydantic/v3/v3_0_3/info.py +++ b/openapi_schema_pydantic/v3/v3_0_3/info.py @@ -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. """ @@ -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). diff --git a/openapi_schema_pydantic/v3/v3_0_3/license.py b/openapi_schema_pydantic/v3/v3_0_3/license.py index 29c97ab..e483712 100644 --- a/openapi_schema_pydantic/v3/v3_0_3/license.py +++ b/openapi_schema_pydantic/v3/v3_0_3/license.py @@ -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. """ diff --git a/openapi_schema_pydantic/v3/v3_0_3/oauth_flow.py b/openapi_schema_pydantic/v3/v3_0_3/oauth_flow.py index ce76309..37abfb7 100644 --- a/openapi_schema_pydantic/v3/v3_0_3/oauth_flow.py +++ b/openapi_schema_pydantic/v3/v3_0_3/oauth_flow.py @@ -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. diff --git a/openapi_schema_pydantic/v3/v3_0_3/open_api.py b/openapi_schema_pydantic/v3/v3_0_3/open_api.py index 6b332e8..bcf8cbf 100644 --- a/openapi_schema_pydantic/v3/v3_0_3/open_api.py +++ b/openapi_schema_pydantic/v3/v3_0_3/open_api.py @@ -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. """ @@ -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. """ diff --git a/openapi_schema_pydantic/v3/v3_0_3/operation.py b/openapi_schema_pydantic/v3/v3_0_3/operation.py index aa28a44..8917d9d 100644 --- a/openapi_schema_pydantic/v3/v3_0_3/operation.py +++ b/openapi_schema_pydantic/v3/v3_0_3/operation.py @@ -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. """ diff --git a/openapi_schema_pydantic/v3/v3_0_3/parameter.py b/openapi_schema_pydantic/v3/v3_0_3/parameter.py index 0f72df3..5b7ab78 100644 --- a/openapi_schema_pydantic/v3/v3_0_3/parameter.py +++ b/openapi_schema_pydantic/v3/v3_0_3/parameter.py @@ -17,7 +17,7 @@ class Parameter(BaseModel): """Fixed Fields""" - name: str = ... + name: str """ **REQUIRED**. The name of the parameter. Parameter names are *case sensitive*. diff --git a/openapi_schema_pydantic/v3/v3_0_3/request_body.py b/openapi_schema_pydantic/v3/v3_0_3/request_body.py index 1bf58ce..fe64ab2 100644 --- a/openapi_schema_pydantic/v3/v3_0_3/request_body.py +++ b/openapi_schema_pydantic/v3/v3_0_3/request_body.py @@ -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) diff --git a/openapi_schema_pydantic/v3/v3_0_3/response.py b/openapi_schema_pydantic/v3/v3_0_3/response.py index 1f7042c..1a5f135 100644 --- a/openapi_schema_pydantic/v3/v3_0_3/response.py +++ b/openapi_schema_pydantic/v3/v3_0_3/response.py @@ -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. diff --git a/openapi_schema_pydantic/v3/v3_0_3/security_scheme.py b/openapi_schema_pydantic/v3/v3_0_3/security_scheme.py index df54c64..a093679 100644 --- a/openapi_schema_pydantic/v3/v3_0_3/security_scheme.py +++ b/openapi_schema_pydantic/v3/v3_0_3/security_scheme.py @@ -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"`. diff --git a/openapi_schema_pydantic/v3/v3_0_3/server.py b/openapi_schema_pydantic/v3/v3_0_3/server.py index aeeefd5..4470a2a 100644 --- a/openapi_schema_pydantic/v3/v3_0_3/server.py +++ b/openapi_schema_pydantic/v3/v3_0_3/server.py @@ -8,7 +8,7 @@ class Server(BaseModel): """An object representing a Server.""" - url: str = ... + url: str """ **REQUIRED**. A URL to the target host. diff --git a/openapi_schema_pydantic/v3/v3_0_3/server_variable.py b/openapi_schema_pydantic/v3/v3_0_3/server_variable.py index 8808e4a..6bab91c 100644 --- a/openapi_schema_pydantic/v3/v3_0_3/server_variable.py +++ b/openapi_schema_pydantic/v3/v3_0_3/server_variable.py @@ -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. diff --git a/openapi_schema_pydantic/v3/v3_0_3/tag.py b/openapi_schema_pydantic/v3/v3_0_3/tag.py index 24e926a..dbb7cc5 100644 --- a/openapi_schema_pydantic/v3/v3_0_3/tag.py +++ b/openapi_schema_pydantic/v3/v3_0_3/tag.py @@ -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. """ diff --git a/openapi_schema_pydantic/v3/v3_0_3/util.py b/openapi_schema_pydantic/v3/v3_0_3/util.py index cb57969..d758e8f 100644 --- a/openapi_schema_pydantic/v3/v3_0_3/util.py +++ b/openapi_schema_pydantic/v3/v3_0_3/util.py @@ -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 @@ -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: @@ -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 @@ -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: @@ -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 diff --git a/openapi_schema_pydantic/v3/v3_1_0/__init__.py b/openapi_schema_pydantic/v3/v3_1_0/__init__.py index dd938d1..bb579fe 100644 --- a/openapi_schema_pydantic/v3/v3_1_0/__init__.py +++ b/openapi_schema_pydantic/v3/v3_1_0/__init__.py @@ -6,36 +6,36 @@ https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.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 Encoding.update_forward_refs(Header=Header) diff --git a/openapi_schema_pydantic/v3/v3_1_0/callback.py b/openapi_schema_pydantic/v3/v3_1_0/callback.py index 254249a..5d71e5c 100644 --- a/openapi_schema_pydantic/v3/v3_1_0/callback.py +++ b/openapi_schema_pydantic/v3/v3_1_0/callback.py @@ -1,7 +1,10 @@ -from typing import Dict, Union +from typing import Dict, TYPE_CHECKING, Union from .reference import Reference +if TYPE_CHECKING: + from .path_item import PathItem + Callback = Dict[str, Union["PathItem", Reference]] """ diff --git a/openapi_schema_pydantic/v3/v3_1_0/discriminator.py b/openapi_schema_pydantic/v3/v3_1_0/discriminator.py index 699d4ea..525c25b 100644 --- a/openapi_schema_pydantic/v3/v3_1_0/discriminator.py +++ b/openapi_schema_pydantic/v3/v3_1_0/discriminator.py @@ -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. """ diff --git a/openapi_schema_pydantic/v3/v3_1_0/encoding.py b/openapi_schema_pydantic/v3/v3_1_0/encoding.py index 7dc6220..0057e46 100644 --- a/openapi_schema_pydantic/v3/v3_1_0/encoding.py +++ b/openapi_schema_pydantic/v3/v3_1_0/encoding.py @@ -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.""" diff --git a/openapi_schema_pydantic/v3/v3_1_0/external_documentation.py b/openapi_schema_pydantic/v3/v3_1_0/external_documentation.py index 0ce2747..e16eaab 100644 --- a/openapi_schema_pydantic/v3/v3_1_0/external_documentation.py +++ b/openapi_schema_pydantic/v3/v3_1_0/external_documentation.py @@ -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 form of a URL. diff --git a/openapi_schema_pydantic/v3/v3_1_0/info.py b/openapi_schema_pydantic/v3/v3_1_0/info.py index 5e8955b..4c315f6 100644 --- a/openapi_schema_pydantic/v3/v3_1_0/info.py +++ b/openapi_schema_pydantic/v3/v3_1_0/info.py @@ -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. """ @@ -45,7 +45,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). diff --git a/openapi_schema_pydantic/v3/v3_1_0/license.py b/openapi_schema_pydantic/v3/v3_1_0/license.py index f0ba1bb..04c440d 100644 --- a/openapi_schema_pydantic/v3/v3_1_0/license.py +++ b/openapi_schema_pydantic/v3/v3_1_0/license.py @@ -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. """ diff --git a/openapi_schema_pydantic/v3/v3_1_0/open_api.py b/openapi_schema_pydantic/v3/v3_1_0/open_api.py index dc1e534..c201d5e 100644 --- a/openapi_schema_pydantic/v3/v3_1_0/open_api.py +++ b/openapi_schema_pydantic/v3/v3_1_0/open_api.py @@ -24,7 +24,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. """ diff --git a/openapi_schema_pydantic/v3/v3_1_0/parameter.py b/openapi_schema_pydantic/v3/v3_1_0/parameter.py index e4f69c4..d34e639 100644 --- a/openapi_schema_pydantic/v3/v3_1_0/parameter.py +++ b/openapi_schema_pydantic/v3/v3_1_0/parameter.py @@ -17,7 +17,7 @@ class Parameter(BaseModel): """Fixed Fields""" - name: str = ... + name: str """ **REQUIRED**. The name of the parameter. Parameter names are *case sensitive*. diff --git a/openapi_schema_pydantic/v3/v3_1_0/request_body.py b/openapi_schema_pydantic/v3/v3_1_0/request_body.py index 1bf58ce..fe64ab2 100644 --- a/openapi_schema_pydantic/v3/v3_1_0/request_body.py +++ b/openapi_schema_pydantic/v3/v3_1_0/request_body.py @@ -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) diff --git a/openapi_schema_pydantic/v3/v3_1_0/response.py b/openapi_schema_pydantic/v3/v3_1_0/response.py index 1f7042c..1a5f135 100644 --- a/openapi_schema_pydantic/v3/v3_1_0/response.py +++ b/openapi_schema_pydantic/v3/v3_1_0/response.py @@ -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. diff --git a/openapi_schema_pydantic/v3/v3_1_0/security_scheme.py b/openapi_schema_pydantic/v3/v3_1_0/security_scheme.py index e1761d0..8f16477 100644 --- a/openapi_schema_pydantic/v3/v3_1_0/security_scheme.py +++ b/openapi_schema_pydantic/v3/v3_1_0/security_scheme.py @@ -21,7 +21,7 @@ class SecurityScheme(BaseModel): Recommended for most use case is Authorization Code Grant flow with PKCE. """ - type: str = ... + type: str """ **REQUIRED**. The type of the security scheme. Valid values are `"apiKey"`, `"http"`, "mutualTLS", `"oauth2"`, `"openIdConnect"`. diff --git a/openapi_schema_pydantic/v3/v3_1_0/server.py b/openapi_schema_pydantic/v3/v3_1_0/server.py index aeeefd5..4470a2a 100644 --- a/openapi_schema_pydantic/v3/v3_1_0/server.py +++ b/openapi_schema_pydantic/v3/v3_1_0/server.py @@ -8,7 +8,7 @@ class Server(BaseModel): """An object representing a Server.""" - url: str = ... + url: str """ **REQUIRED**. A URL to the target host. diff --git a/openapi_schema_pydantic/v3/v3_1_0/server_variable.py b/openapi_schema_pydantic/v3/v3_1_0/server_variable.py index ad3d989..ef54cac 100644 --- a/openapi_schema_pydantic/v3/v3_1_0/server_variable.py +++ b/openapi_schema_pydantic/v3/v3_1_0/server_variable.py @@ -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. diff --git a/openapi_schema_pydantic/v3/v3_1_0/tag.py b/openapi_schema_pydantic/v3/v3_1_0/tag.py index 24e926a..dbb7cc5 100644 --- a/openapi_schema_pydantic/v3/v3_1_0/tag.py +++ b/openapi_schema_pydantic/v3/v3_1_0/tag.py @@ -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. """ diff --git a/pyproject.toml b/pyproject.toml index 59123ca..8e7d7e3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -19,3 +19,7 @@ exclude = ''' )/ ) ''' + +[tool.mypy] +strict = true +files = ["openapi_schema_pydantic/", "tests/"] diff --git a/tests/schema_classes/test_schema.py b/tests/schema_classes/test_schema.py index 0fd8b8e..2cff6b4 100644 --- a/tests/schema_classes/test_schema.py +++ b/tests/schema_classes/test_schema.py @@ -6,7 +6,7 @@ from openapi_schema_pydantic import Schema, Reference -def test_schema(): +def test_schema() -> None: schema = Schema.parse_obj( { "title": "reference list", @@ -21,7 +21,7 @@ def test_schema(): assert schema.allOf[0].ref == "#/definitions/TestType" -def test_issue_4(): +def test_issue_4() -> None: """https://github.com/kuimono/openapi-schema-pydantic/issues/4""" class TestModel(BaseModel): diff --git a/tests/schema_classes/test_security_scheme.py b/tests/schema_classes/test_security_scheme.py index c768dd9..e97f09d 100644 --- a/tests/schema_classes/test_security_scheme.py +++ b/tests/schema_classes/test_security_scheme.py @@ -3,7 +3,7 @@ from openapi_schema_pydantic import SecurityScheme -def test_security_scheme_issue_5(): +def test_security_scheme_issue_5() -> None: """https://github.com/kuimono/openapi-schema-pydantic/issues/5""" security_scheme_1 = SecurityScheme(type="openIdConnect", openIdConnectUrl="https://example.com/openIdConnect") diff --git a/tests/test_alias.py b/tests/test_alias.py index 2cd0b0f..ea4bca8 100644 --- a/tests/test_alias.py +++ b/tests/test_alias.py @@ -1,14 +1,14 @@ from openapi_schema_pydantic import Header, MediaType, Parameter, PathItem, Reference, Schema, SecurityScheme -def test_header_alias(): +def test_header_alias() -> None: header_1 = Header(param_in="header") header_2 = Header.parse_obj({"param_in": "header"}) header_3 = Header.parse_obj({"in": "header"}) assert header_1 == header_2 == header_3 -def test_media_type_alias(): +def test_media_type_alias() -> None: media_type_1 = MediaType(media_type_schema=Schema()) media_type_2 = MediaType(schema=Schema()) media_type_3 = MediaType.parse_obj({"media_type_schema": Schema()}) @@ -16,7 +16,7 @@ def test_media_type_alias(): assert media_type_1 == media_type_2 == media_type_3 == media_type_4 -def test_parameter_alias(): +def test_parameter_alias() -> None: parameter_1 = Parameter(name="test", param_in="path", param_schema=Schema()) parameter_2 = Parameter(name="test", param_in="path", schema=Schema()) parameter_3 = Parameter.parse_obj({"name": "test", "param_in": "path", "param_schema": Schema()}) @@ -24,28 +24,28 @@ def test_parameter_alias(): assert parameter_1 == parameter_2 == parameter_3 == parameter_4 -def test_path_item_alias(): +def test_path_item_alias() -> None: path_item_1 = PathItem(ref="#/dummy") path_item_2 = PathItem.parse_obj({"ref": "#/dummy"}) path_item_3 = PathItem.parse_obj({"$ref": "#/dummy"}) assert path_item_1 == path_item_2 == path_item_3 -def test_reference_alias(): +def test_reference_alias() -> None: reference_1 = Reference(ref="#/dummy") reference_2 = Reference.parse_obj({"ref": "#/dummy"}) reference_3 = Reference.parse_obj({"$ref": "#/dummy"}) assert reference_1 == reference_2 == reference_3 -def test_security_scheme(): +def test_security_scheme() -> None: security_scheme_1 = SecurityScheme(type="apiKey", security_scheme_in="header") security_scheme_2 = SecurityScheme.parse_obj({"type": "apiKey", "security_scheme_in": "header"}) security_scheme_3 = SecurityScheme.parse_obj({"type": "apiKey", "in": "header"}) assert security_scheme_1 == security_scheme_2 == security_scheme_3 -def test_schema(): +def test_schema() -> None: schema_1 = Schema(schema_not=Schema(), schema_format="email") schema_2 = Schema.parse_obj({"schema_not": Schema(), "schema_format": "email"}) schema_3 = Schema.parse_obj({"not": Schema(), "format": "email"}) diff --git a/tests/test_config_example.py b/tests/test_config_example.py index 29394d4..76f9dc1 100644 --- a/tests/test_config_example.py +++ b/tests/test_config_example.py @@ -32,7 +32,7 @@ ) -def test_config_example(): +def test_config_example() -> None: all_types = [ OpenAPI, Info, @@ -69,9 +69,11 @@ def test_config_example(): _assert_config_examples(schema_type) -def _assert_config_examples(schema_type): - if getattr(schema_type, "Config", None) and getattr(schema_type.Config, "schema_extra", None): - examples = schema_type.Config.schema_extra.get("examples") +def _assert_config_examples(schema_type: object) -> None: + Config = getattr(schema_type, "Config", None) + schema_extra = getattr(Config, "schema_extra", None) + if schema_extra is not None: + examples = schema_extra["examples"] for example_dict in examples: - obj = schema_type(**example_dict) + obj = schema_type(**example_dict) # type: ignore[operator] assert obj.__fields_set__ diff --git a/tests/test_example.py b/tests/test_example.py index 1a2e9a0..9280fd2 100644 --- a/tests/test_example.py +++ b/tests/test_example.py @@ -3,7 +3,7 @@ from openapi_schema_pydantic import Info, OpenAPI, Operation, PathItem, Response -def test_readme_example(): +def test_readme_example() -> None: open_api_1 = readme_example_1() assert open_api_1 open_api_json_1 = open_api_1.json(by_alias=True, exclude_none=True, indent=2) diff --git a/tests/test_swagger_openapi_v3.py b/tests/test_swagger_openapi_v3.py index 86b70f8..759c7f4 100644 --- a/tests/test_swagger_openapi_v3.py +++ b/tests/test_swagger_openapi_v3.py @@ -5,7 +5,7 @@ from openapi_schema_pydantic import OpenAPI, Operation, PathItem -def test_swagger_openapi_v3(): +def test_swagger_openapi_v3() -> None: open_api = ExtendedOpenAPI.parse_file("tests/data/swagger_openapi_v3.0.1.json") assert open_api @@ -31,4 +31,4 @@ class ExtendedPathItem(PathItem): class ExtendedOpenAPI(OpenAPI): - paths: Dict[str, ExtendedPathItem] = ... + paths: Dict[str, ExtendedPathItem] # type: ignore[assignment] diff --git a/tests/util/test_pydantic_field.py b/tests/util/test_pydantic_field.py index e5e72e9..8b45c24 100644 --- a/tests/util/test_pydantic_field.py +++ b/tests/util/test_pydantic_field.py @@ -19,7 +19,7 @@ from openapi_schema_pydantic.util import PydanticSchema, construct_open_api_with_schema_class -def test_pydantic_discriminator_schema_generation(): +def test_pydantic_discriminator_schema_generation() -> None: """https://github.com/kuimono/openapi-schema-pydantic/issues/8""" json_schema = schema([RequestModel]) @@ -56,10 +56,12 @@ def test_pydantic_discriminator_schema_generation(): } -def test_pydantic_discriminator_openapi_generation(): +def test_pydantic_discriminator_openapi_generation() -> None: """https://github.com/kuimono/openapi-schema-pydantic/issues/8""" open_api = construct_open_api_with_schema_class(construct_base_open_api()) + assert open_api.components is not None + assert open_api.components.schemas is not None json_schema = open_api.components.schemas["RequestModel"] assert json_schema.properties == { "data": Schema( diff --git a/tests/util/test_util.py b/tests/util/test_util.py index a280106..cba08c0 100644 --- a/tests/util/test_util.py +++ b/tests/util/test_util.py @@ -6,7 +6,7 @@ from openapi_schema_pydantic.util import PydanticSchema, construct_open_api_with_schema_class -def test_construct_open_api_with_schema_class_1(): +def test_construct_open_api_with_schema_class_1() -> None: open_api = construct_base_open_api_1() result_open_api_1 = construct_open_api_with_schema_class(open_api) result_open_api_2 = construct_open_api_with_schema_class(open_api, [PingRequest, PingResponse]) @@ -17,7 +17,7 @@ def test_construct_open_api_with_schema_class_1(): logging.debug(open_api_json) -def test_construct_open_api_with_schema_class_2(): +def test_construct_open_api_with_schema_class_2() -> None: open_api_1 = construct_base_open_api_1() open_api_2 = construct_base_open_api_2() result_open_api_1 = construct_open_api_with_schema_class(open_api_1) @@ -25,11 +25,14 @@ def test_construct_open_api_with_schema_class_2(): assert result_open_api_1 == result_open_api_2 -def test_construct_open_api_with_schema_class_3(): +def test_construct_open_api_with_schema_class_3() -> None: open_api_3 = construct_base_open_api_3() result_with_alias_1 = construct_open_api_with_schema_class(open_api_3) + assert result_with_alias_1.components is not None + assert result_with_alias_1.components.schemas is not None schema_with_alias = result_with_alias_1.components.schemas["PongResponse"] + assert schema_with_alias.properties is not None assert "pong_foo" in schema_with_alias.properties assert "pong_bar" in schema_with_alias.properties @@ -37,7 +40,10 @@ def test_construct_open_api_with_schema_class_3(): assert result_with_alias_1 == result_with_alias_2 result_without_alias = construct_open_api_with_schema_class(open_api_3, by_alias=False) + assert result_without_alias.components is not None + assert result_without_alias.components.schemas is not None schema_without_alias = result_without_alias.components.schemas["PongResponse"] + assert schema_without_alias.properties is not None assert "resp_foo" in schema_without_alias.properties assert "resp_bar" in schema_without_alias.properties diff --git a/tests/v3_0_3/test_config_example.py b/tests/v3_0_3/test_config_example.py index 2fb3f16..d882b40 100644 --- a/tests/v3_0_3/test_config_example.py +++ b/tests/v3_0_3/test_config_example.py @@ -32,7 +32,7 @@ ) -def test_config_example(): +def test_config_example() -> None: all_types = [ OpenAPI, Info, @@ -69,9 +69,11 @@ def test_config_example(): _assert_config_examples(schema_type) -def _assert_config_examples(schema_type): - if getattr(schema_type, "Config", None) and getattr(schema_type.Config, "schema_extra", None): - examples = schema_type.Config.schema_extra.get("examples") +def _assert_config_examples(schema_type: object) -> None: + Config = getattr(schema_type, "Config", None) + schema_extra = getattr(Config, "schema_extra", None) + if schema_extra is not None: + examples = schema_extra.get("examples") for example_dict in examples: - obj = schema_type(**example_dict) + obj = schema_type(**example_dict) # type: ignore[operator] assert obj.__fields_set__ diff --git a/tests/v3_0_3/test_util.py b/tests/v3_0_3/test_util.py index 8193726..97a5a29 100644 --- a/tests/v3_0_3/test_util.py +++ b/tests/v3_0_3/test_util.py @@ -11,11 +11,12 @@ Reference, RequestBody, Response, + Schema, ) from openapi_schema_pydantic.v3.v3_0_3.util import PydanticSchema, construct_open_api_with_schema_class -def test_construct_open_api_with_schema_class_1(): +def test_construct_open_api_with_schema_class_1() -> None: open_api = construct_base_open_api_1() result_open_api_1 = construct_open_api_with_schema_class(open_api) result_open_api_2 = construct_open_api_with_schema_class(open_api, [PingRequest, PingResponse]) @@ -26,7 +27,7 @@ def test_construct_open_api_with_schema_class_1(): logging.debug(open_api_json) -def test_construct_open_api_with_schema_class_2(): +def test_construct_open_api_with_schema_class_2() -> None: open_api_1 = construct_base_open_api_1() open_api_2 = construct_base_open_api_2() result_open_api_1 = construct_open_api_with_schema_class(open_api_1) @@ -34,11 +35,15 @@ def test_construct_open_api_with_schema_class_2(): assert result_open_api_1 == result_open_api_2 -def test_construct_open_api_with_schema_class_3(): +def test_construct_open_api_with_schema_class_3() -> None: open_api_3 = construct_base_open_api_3() result_with_alias_1 = construct_open_api_with_schema_class(open_api_3) + assert result_with_alias_1.components is not None + assert result_with_alias_1.components.schemas is not None schema_with_alias = result_with_alias_1.components.schemas["PongResponse"] + assert isinstance(schema_with_alias, Schema) + assert schema_with_alias.properties is not None assert "pong_foo" in schema_with_alias.properties assert "pong_bar" in schema_with_alias.properties @@ -46,7 +51,11 @@ def test_construct_open_api_with_schema_class_3(): assert result_with_alias_1 == result_with_alias_2 result_without_alias = construct_open_api_with_schema_class(open_api_3, by_alias=False) + assert result_without_alias.components is not None + assert result_without_alias.components.schemas is not None schema_without_alias = result_without_alias.components.schemas["PongResponse"] + assert isinstance(schema_without_alias, Schema) + assert schema_without_alias.properties is not None assert "resp_foo" in schema_without_alias.properties assert "resp_bar" in schema_without_alias.properties diff --git a/tests/v3_1_0/__init__.py b/tests/v3_1_0/__init__.py index df2a9c0..f0cbec1 100644 --- a/tests/v3_1_0/__init__.py +++ b/tests/v3_1_0/__init__.py @@ -1,6 +1,6 @@ from openapi_schema_pydantic.v3.v3_1_0.schema import Schema -def test_empty_schema(): +def test_empty_schema() -> None: schema = Schema.parse_obj({}) assert schema == Schema()