Skip to content

Commit 0571ffe

Browse files
authored
Merge pull request #6 from mike-oakley/u/mike/linting-fixes
feat: Setup and linting improvements.
2 parents 7b60a47 + 0199946 commit 0571ffe

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

71 files changed

+1751
-550
lines changed

.devcontainer/devcontainer.json

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
{
2+
"name": "openapi-schema-pydantic",
3+
"image": "mcr.microsoft.com/devcontainers/python:0-3.11",
4+
"features": {
5+
"ghcr.io/devcontainers-contrib/features/poetry:2": {
6+
"version": "latest"
7+
}
8+
},
9+
"containerEnv": {
10+
"POETRY_VIRTUALENVS_IN_PROJECT": "true"
11+
},
12+
"postCreateCommand": "poetry install",
13+
"customizations": {
14+
"vscode": {
15+
"extensions": [
16+
"ms-python.python",
17+
"ms-python.vscode-pylance",
18+
"ms-python.black-formatter",
19+
"charliermarsh.ruff"
20+
]
21+
}
22+
}
23+
}

.gitignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
/*.egg-info
22
/.idea
33
/.pytest_cache
4+
/.mypy_cache
5+
/.ruff_cache
46
/build
57
/dist
6-
__pycache__
8+
/.venv
9+
__pycache__

.vscode/settings.json

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"python.testing.pytestArgs": [
3+
"tests"
4+
],
5+
"python.testing.unittestEnabled": false,
6+
"python.testing.pytestEnabled": true,
7+
"python.analysis.typeCheckingMode": "basic",
8+
"python.linting.enabled": true,
9+
"editor.formatOnSave": true,
10+
"editor.codeActionsOnSave": {
11+
"source.fixAll": true,
12+
"source.organizeImports": true
13+
},
14+
"editor.defaultFormatter": "ms-python.black-formatter"
15+
}
Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,35 @@
11
import logging
22

3-
from .v3 import *
4-
3+
from .v3 import XML as XML
4+
from .v3 import Callback as Callback
5+
from .v3 import Components as Components
6+
from .v3 import Contact as Contact
7+
from .v3 import Discriminator as Discriminator
8+
from .v3 import Encoding as Encoding
9+
from .v3 import Example as Example
10+
from .v3 import ExternalDocumentation as ExternalDocumentation
11+
from .v3 import Header as Header
12+
from .v3 import Info as Info
13+
from .v3 import License as License
14+
from .v3 import Link as Link
15+
from .v3 import MediaType as MediaType
16+
from .v3 import OAuthFlow as OAuthFlow
17+
from .v3 import OAuthFlows as OAuthFlows
18+
from .v3 import OpenAPI as OpenAPI
19+
from .v3 import Operation as Operation
20+
from .v3 import Parameter as Parameter
21+
from .v3 import ParameterLocation as ParameterLocation
22+
from .v3 import PathItem as PathItem
23+
from .v3 import Paths as Paths
24+
from .v3 import Reference as Reference
25+
from .v3 import RequestBody as RequestBody
26+
from .v3 import Response as Response
27+
from .v3 import Responses as Responses
28+
from .v3 import Schema as Schema
29+
from .v3 import SecurityRequirement as SecurityRequirement
30+
from .v3 import SecurityScheme as SecurityScheme
31+
from .v3 import Server as Server
32+
from .v3 import ServerVariable as ServerVariable
33+
from .v3 import Tag as Tag
534

635
logging.getLogger(__name__).addHandler(logging.NullHandler())

openapi_schema_pydantic/util.py

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -26,21 +26,27 @@ def construct_open_api_with_schema_class(
2626
by_alias: bool = True,
2727
) -> OpenAPI:
2828
"""
29-
Construct a new OpenAPI object, with the use of pydantic classes to produce JSON schemas
29+
Construct a new OpenAPI object, utilising pydantic classes to produce JSON schemas
3030
3131
:param open_api: the base `OpenAPI` object
32-
:param schema_classes: pydanitic classes that their schema will be used "#/components/schemas" values
33-
:param scan_for_pydantic_schema_reference: flag to indicate if scanning for `PydanticSchemaReference` class
34-
is needed for "#/components/schemas" value updates
32+
:param schema_classes: pydanitic classes that their schema will be used
33+
"#/components/schemas" values
34+
:param scan_for_pydantic_schema_reference: flag to indicate if scanning for
35+
`PydanticSchemaReference` class is
36+
needed for "#/components/schemas" value
37+
updates
3538
:param by_alias: construct schema by alias (default is True)
3639
:return: new OpenAPI object with "#/components/schemas" values updated.
37-
If there is no update in "#/components/schemas" values, the original `open_api` will be returned.
40+
If there is no update in "#/components/schemas" values, the original
41+
`open_api` will be returned.
3842
"""
3943
new_open_api: OpenAPI = open_api.copy(deep=True)
4044
if scan_for_pydantic_schema_reference:
4145
extracted_schema_classes = _handle_pydantic_schema(new_open_api)
4246
if schema_classes:
43-
schema_classes = list({*schema_classes, *_handle_pydantic_schema(new_open_api)})
47+
schema_classes = list(
48+
{*schema_classes, *_handle_pydantic_schema(new_open_api)}
49+
)
4450
else:
4551
schema_classes = extracted_schema_classes
4652

@@ -51,7 +57,9 @@ def construct_open_api_with_schema_class(
5157
logger.debug(f"schema_classes{schema_classes}")
5258

5359
# update new_open_api with new #/components/schemas
54-
schema_definitions = schema(schema_classes, by_alias=by_alias, ref_prefix=ref_prefix)
60+
schema_definitions = schema(
61+
schema_classes, by_alias=by_alias, ref_prefix=ref_prefix
62+
)
5563
if not new_open_api.components:
5664
new_open_api.components = Components()
5765
if new_open_api.components.schemas:
@@ -62,11 +70,15 @@ def construct_open_api_with_schema_class(
6270
f'The value of "{ref_prefix}{existing_key}" will be overwritten.'
6371
)
6472
new_open_api.components.schemas.update(
65-
{key: Schema.parse_obj(schema_dict) for key, schema_dict in schema_definitions["definitions"].items()}
73+
{
74+
key: Schema.parse_obj(schema_dict)
75+
for key, schema_dict in schema_definitions["definitions"].items()
76+
}
6677
)
6778
else:
6879
new_open_api.components.schemas = {
69-
key: Schema.parse_obj(schema_dict) for key, schema_dict in schema_definitions["definitions"].items()
80+
key: Schema.parse_obj(schema_dict)
81+
for key, schema_dict in schema_definitions["definitions"].items()
7082
}
7183
return new_open_api
7284

@@ -75,7 +87,8 @@ def _handle_pydantic_schema(open_api: OpenAPI) -> List[Type[BaseModel]]:
7587
"""
7688
This function traverses the `OpenAPI` object and
7789
78-
1. Replaces the `PydanticSchema` object with `Reference` object, with correct ref value;
90+
1. Replaces the `PydanticSchema` object with `Reference` object, with correct ref
91+
value;
7992
2. Extracts the involved schema class from `PydanticSchema` object.
8093
8194
**This function will mutate the input `OpenAPI` object.**
@@ -92,7 +105,9 @@ def _traverse(obj: Any) -> None:
92105
for field in fields:
93106
child_obj = obj.__getattribute__(field)
94107
if isinstance(child_obj, PydanticSchema):
95-
logger.debug(f"PydanticSchema found in {obj.__repr_name__()}: {child_obj}")
108+
logger.debug(
109+
f"PydanticSchema found in {obj.__repr_name__()}: {child_obj}"
110+
)
96111
obj.__setattr__(field, _construct_ref_obj(child_obj))
97112
pydantic_types.add(child_obj.schema_class)
98113
else:
Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,31 @@
1-
from .v3_1_0 import *
1+
from .v3_1_0 import XML as XML
2+
from .v3_1_0 import Callback as Callback
3+
from .v3_1_0 import Components as Components
4+
from .v3_1_0 import Contact as Contact
5+
from .v3_1_0 import Discriminator as Discriminator
6+
from .v3_1_0 import Encoding as Encoding
7+
from .v3_1_0 import Example as Example
8+
from .v3_1_0 import ExternalDocumentation as ExternalDocumentation
9+
from .v3_1_0 import Header as Header
10+
from .v3_1_0 import Info as Info
11+
from .v3_1_0 import License as License
12+
from .v3_1_0 import Link as Link
13+
from .v3_1_0 import MediaType as MediaType
14+
from .v3_1_0 import OAuthFlow as OAuthFlow
15+
from .v3_1_0 import OAuthFlows as OAuthFlows
16+
from .v3_1_0 import OpenAPI as OpenAPI
17+
from .v3_1_0 import Operation as Operation
18+
from .v3_1_0 import Parameter as Parameter
19+
from .v3_1_0 import ParameterLocation as ParameterLocation
20+
from .v3_1_0 import PathItem as PathItem
21+
from .v3_1_0 import Paths as Paths
22+
from .v3_1_0 import Reference as Reference
23+
from .v3_1_0 import RequestBody as RequestBody
24+
from .v3_1_0 import Response as Response
25+
from .v3_1_0 import Responses as Responses
26+
from .v3_1_0 import Schema as Schema
27+
from .v3_1_0 import SecurityRequirement as SecurityRequirement
28+
from .v3_1_0 import SecurityScheme as SecurityScheme
29+
from .v3_1_0 import Server as Server
30+
from .v3_1_0 import ServerVariable as ServerVariable
31+
from .v3_1_0 import Tag as Tag

openapi_schema_pydantic/v3/v3_0_3/callback.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from typing import Dict, TYPE_CHECKING
1+
from typing import TYPE_CHECKING, Dict
22

33
if TYPE_CHECKING:
44
from .path_item import PathItem
@@ -8,9 +8,10 @@
88
"""
99
A map of possible out-of band callbacks related to the parent operation.
1010
Each value in the map is a [Path Item Object](#pathItemObject)
11-
that describes a set of requests that may be initiated by the API provider and the expected responses.
12-
The key value used to identify the path item object is an expression, evaluated at runtime,
13-
that identifies a URL to use for the callback operation.
11+
that describes a set of requests that may be initiated by the API provider and the
12+
expected responses. The key value used to identify the path item object is an
13+
expression, evaluated at runtime, that identifies a URL to use for the callback
14+
operation.
1415
"""
1516

1617
"""Patterned Fields"""

openapi_schema_pydantic/v3/v3_0_3/components.py

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,11 +63,17 @@ class Config:
6363
},
6464
"Category": {
6565
"type": "object",
66-
"properties": {"id": {"type": "integer", "format": "int64"}, "name": {"type": "string"}},
66+
"properties": {
67+
"id": {"type": "integer", "format": "int64"},
68+
"name": {"type": "string"},
69+
},
6770
},
6871
"Tag": {
6972
"type": "object",
70-
"properties": {"id": {"type": "integer", "format": "int64"}, "name": {"type": "string"}},
73+
"properties": {
74+
"id": {"type": "integer", "format": "int64"},
75+
"name": {"type": "string"},
76+
},
7177
},
7278
},
7379
"parameters": {
@@ -91,11 +97,21 @@ class Config:
9197
"IllegalInput": {"description": "Illegal input for operation."},
9298
"GeneralError": {
9399
"description": "General Error",
94-
"content": {"application/json": {"schema": {"$ref": "#/components/schemas/GeneralError"}}},
100+
"content": {
101+
"application/json": {
102+
"schema": {
103+
"$ref": "#/components/schemas/GeneralError"
104+
}
105+
}
106+
},
95107
},
96108
},
97109
"securitySchemes": {
98-
"api_key": {"type": "apiKey", "name": "api_key", "in": "header"},
110+
"api_key": {
111+
"type": "apiKey",
112+
"name": "api_key",
113+
"in": "header",
114+
},
99115
"petstore_auth": {
100116
"type": "oauth2",
101117
"flows": {

openapi_schema_pydantic/v3/v3_0_3/contact.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ class Config:
2929
extra = Extra.allow
3030
schema_extra = {
3131
"examples": [
32-
{"name": "API Support", "url": "http://www.example.com/support", "email": "[email protected]"}
32+
{
33+
"name": "API Support",
34+
"url": "http://www.example.com/support",
35+
"email": "[email protected]",
36+
}
3337
]
3438
}

openapi_schema_pydantic/v3/v3_0_3/discriminator.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,21 @@
55

66
class Discriminator(BaseModel):
77
"""
8-
When request bodies or response payloads may be one of a number of different schemas,
9-
a `discriminator` object can be used to aid in serialization, deserialization, and validation.
8+
When request bodies or response payloads may be one of a number of different
9+
schemas, a `discriminator` object can be used to aid in serialization,
10+
deserialization, and validation.
1011
11-
The discriminator is a specific object in a schema which is used to inform the consumer of the specification
12-
of an alternative schema based on the value associated with it.
12+
The discriminator is a specific object in a schema which is used to inform the
13+
consumer of the specification of an alternative schema based on the value
14+
associated with it.
1315
1416
When using the discriminator, _inline_ schemas will not be considered.
1517
"""
1618

1719
propertyName: str
1820
"""
19-
**REQUIRED**. The name of the property in the payload that will hold the discriminator value.
21+
**REQUIRED**. The name of the property in the payload that will hold the
22+
discriminator value.
2023
"""
2124

2225
mapping: Optional[Dict[str, str]] = None

0 commit comments

Comments
 (0)