fastapi_swagger2 0.2.5__tar.gz → 0.2.7__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {fastapi_swagger2-0.2.5 → fastapi_swagger2-0.2.7}/PKG-INFO +12 -12
- {fastapi_swagger2-0.2.5 → fastapi_swagger2-0.2.7}/README.md +1 -1
- {fastapi_swagger2-0.2.5 → fastapi_swagger2-0.2.7}/pyproject.toml +13 -17
- {fastapi_swagger2-0.2.5 → fastapi_swagger2-0.2.7}/scripts/format.sh +1 -1
- {fastapi_swagger2-0.2.5 → fastapi_swagger2-0.2.7}/scripts/lint.sh +1 -1
- {fastapi_swagger2-0.2.5 → fastapi_swagger2-0.2.7}/src/fastapi_swagger2/__init__.py +1 -1
- {fastapi_swagger2-0.2.5 → fastapi_swagger2-0.2.7}/src/fastapi_swagger2/models.py +107 -22
- {fastapi_swagger2-0.2.5 → fastapi_swagger2-0.2.7}/src/fastapi_swagger2/utils.py +97 -15
- {fastapi_swagger2-0.2.5 → fastapi_swagger2-0.2.7}/.gitignore +0 -0
- {fastapi_swagger2-0.2.5 → fastapi_swagger2-0.2.7}/LICENSE +0 -0
- {fastapi_swagger2-0.2.5 → fastapi_swagger2-0.2.7}/requirements-dev.txt +0 -0
- {fastapi_swagger2-0.2.5 → fastapi_swagger2-0.2.7}/requirements.txt +0 -0
- {fastapi_swagger2-0.2.5 → fastapi_swagger2-0.2.7}/scripts/build.sh +0 -0
- {fastapi_swagger2-0.2.5 → fastapi_swagger2-0.2.7}/scripts/clean.sh +0 -0
- {fastapi_swagger2-0.2.5 → fastapi_swagger2-0.2.7}/scripts/publish.sh +0 -0
- {fastapi_swagger2-0.2.5 → fastapi_swagger2-0.2.7}/scripts/test.sh +0 -0
- {fastapi_swagger2-0.2.5 → fastapi_swagger2-0.2.7}/setup.cfg +0 -0
- {fastapi_swagger2-0.2.5 → fastapi_swagger2-0.2.7}/src/fastapi_swagger2/constants.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: fastapi_swagger2
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.7
|
|
4
4
|
Summary: Swagger2 support for FastAPI framework
|
|
5
5
|
Project-URL: Homepage, https://github.com/virajkanwade/fastapi_swagger2
|
|
6
6
|
Project-URL: Documentation, https://github.com/virajkanwade/fastapi_swagger2
|
|
@@ -53,19 +53,19 @@ Classifier: Topic :: Software Development :: Libraries
|
|
|
53
53
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
54
54
|
Classifier: Typing :: Typed
|
|
55
55
|
Requires-Python: >=3.9
|
|
56
|
-
Requires-Dist: fastapi
|
|
56
|
+
Requires-Dist: fastapi<0.119.0,>=0.100.0
|
|
57
57
|
Provides-Extra: all
|
|
58
|
-
Requires-Dist: httpx>=0.
|
|
58
|
+
Requires-Dist: httpx>=0.28.1; extra == 'all'
|
|
59
59
|
Provides-Extra: dev
|
|
60
|
-
Requires-Dist: ruff==0.
|
|
60
|
+
Requires-Dist: ruff==0.14.10; extra == 'dev'
|
|
61
61
|
Provides-Extra: test
|
|
62
|
-
Requires-Dist: black==
|
|
63
|
-
Requires-Dist: coverage[toml]<8.0,>=
|
|
64
|
-
Requires-Dist: httpx
|
|
65
|
-
Requires-Dist: isort
|
|
66
|
-
Requires-Dist: mypy==1.
|
|
67
|
-
Requires-Dist: pytest<
|
|
68
|
-
Requires-Dist: ruff==0.
|
|
62
|
+
Requires-Dist: black==25.12.0; extra == 'test'
|
|
63
|
+
Requires-Dist: coverage[toml]<8.0,>=7.13.1; extra == 'test'
|
|
64
|
+
Requires-Dist: httpx>=0.28.1; extra == 'test'
|
|
65
|
+
Requires-Dist: isort>=7.0.0; extra == 'test'
|
|
66
|
+
Requires-Dist: mypy==1.19.1; extra == 'test'
|
|
67
|
+
Requires-Dist: pytest<10.0.0,>=9.0.2; extra == 'test'
|
|
68
|
+
Requires-Dist: ruff==0.14.10; extra == 'test'
|
|
69
69
|
Description-Content-Type: text/markdown
|
|
70
70
|
|
|
71
71
|
# fastapi_swagger2
|
|
@@ -96,7 +96,7 @@ Python 3.9+
|
|
|
96
96
|
* 0.0.3 - FastAPI >= 0.79.0, <= 0.98.0
|
|
97
97
|
* 0.1.1 - FastAPI >= 0.99.0, <= 0.99.1
|
|
98
98
|
* 0.2.4 - FastAPI >= 0.100.0
|
|
99
|
-
* 0.2.
|
|
99
|
+
* 0.2.7 - FastAPI >= 0.100.0, < 0.119.0 > + Pydantic v1/v2
|
|
100
100
|
|
|
101
101
|
## Installation
|
|
102
102
|
|
|
@@ -26,7 +26,7 @@ Python 3.9+
|
|
|
26
26
|
* 0.0.3 - FastAPI >= 0.79.0, <= 0.98.0
|
|
27
27
|
* 0.1.1 - FastAPI >= 0.99.0, <= 0.99.1
|
|
28
28
|
* 0.2.4 - FastAPI >= 0.100.0
|
|
29
|
-
* 0.2.
|
|
29
|
+
* 0.2.7 - FastAPI >= 0.100.0, < 0.119.0 > + Pydantic v1/v2
|
|
30
30
|
|
|
31
31
|
## Installation
|
|
32
32
|
|
|
@@ -39,7 +39,7 @@ classifiers = [
|
|
|
39
39
|
"Topic :: Internet :: WWW/HTTP",
|
|
40
40
|
]
|
|
41
41
|
dependencies = [
|
|
42
|
-
"fastapi >=0.100.0",
|
|
42
|
+
"fastapi >=0.100.0,<0.119.0",
|
|
43
43
|
]
|
|
44
44
|
dynamic = ["version"]
|
|
45
45
|
|
|
@@ -49,19 +49,19 @@ Documentation = "https://github.com/virajkanwade/fastapi_swagger2"
|
|
|
49
49
|
|
|
50
50
|
[project.optional-dependencies]
|
|
51
51
|
test = [
|
|
52
|
-
"pytest >=
|
|
53
|
-
"coverage[toml] >=
|
|
54
|
-
"mypy ==1.
|
|
55
|
-
"ruff ==0.
|
|
56
|
-
"black ==
|
|
57
|
-
"isort >=
|
|
58
|
-
"httpx >=0.
|
|
52
|
+
"pytest >=9.0.2,<10.0.0",
|
|
53
|
+
"coverage[toml] >= 7.13.1,< 8.0",
|
|
54
|
+
"mypy ==1.19.1",
|
|
55
|
+
"ruff ==0.14.10",
|
|
56
|
+
"black == 25.12.0",
|
|
57
|
+
"isort >=7.0.0",
|
|
58
|
+
"httpx >=0.28.1",
|
|
59
59
|
]
|
|
60
60
|
dev = [
|
|
61
|
-
"ruff ==0.
|
|
61
|
+
"ruff ==0.14.10",
|
|
62
62
|
]
|
|
63
63
|
all = [
|
|
64
|
-
"httpx >=0.
|
|
64
|
+
"httpx >=0.28.1",
|
|
65
65
|
]
|
|
66
66
|
|
|
67
67
|
[tool.hatch.version]
|
|
@@ -74,7 +74,7 @@ known_third_party = ["fastapi", "pydantic", "starlette"]
|
|
|
74
74
|
[tool.mypy]
|
|
75
75
|
strict = true
|
|
76
76
|
|
|
77
|
-
[tool.ruff]
|
|
77
|
+
[tool.ruff.lint]
|
|
78
78
|
select = [
|
|
79
79
|
"E", # pycodestyle errors
|
|
80
80
|
"W", # pycodestyle warnings
|
|
@@ -88,9 +88,5 @@ ignore = [
|
|
|
88
88
|
"B008", # do not perform function calls in argument defaults
|
|
89
89
|
"C901", # too complex
|
|
90
90
|
]
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
"__init__.py" = ["F401"]
|
|
94
|
-
|
|
95
|
-
[tool.ruff.isort]
|
|
96
|
-
known-third-party = ["fastapi", "pydantic", "starlette"]
|
|
91
|
+
per-file-ignores = { "__init__.py" = ["F401"] }
|
|
92
|
+
isort = { known-third-party = ["fastapi", "pydantic", "starlette"] }
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
from enum import Enum
|
|
2
2
|
from typing import Any, Callable, Dict, Iterable, List, Optional, Union
|
|
3
3
|
|
|
4
|
-
from fastapi._compat import _model_rebuild
|
|
4
|
+
from fastapi._compat import PYDANTIC_V2, _model_rebuild
|
|
5
5
|
from fastapi.logger import logger
|
|
6
|
-
from pydantic import AnyUrl, BaseModel, Field
|
|
6
|
+
from pydantic import AnyUrl, BaseModel, Extra, Field
|
|
7
|
+
|
|
8
|
+
if PYDANTIC_V2:
|
|
9
|
+
from pydantic import ConfigDict
|
|
7
10
|
|
|
8
11
|
try:
|
|
9
12
|
import email_validator # type: ignore
|
|
@@ -31,14 +34,24 @@ class Contact(BaseModel):
|
|
|
31
34
|
url: Optional[AnyUrl] = None
|
|
32
35
|
email: Optional[EmailStr] = None
|
|
33
36
|
|
|
34
|
-
|
|
37
|
+
if PYDANTIC_V2:
|
|
38
|
+
model_config = ConfigDict(extra=Extra.allow)
|
|
39
|
+
else:
|
|
40
|
+
|
|
41
|
+
class Config:
|
|
42
|
+
extra = "allow"
|
|
35
43
|
|
|
36
44
|
|
|
37
45
|
class License(BaseModel):
|
|
38
46
|
name: str
|
|
39
47
|
url: Optional[AnyUrl] = None
|
|
40
48
|
|
|
41
|
-
|
|
49
|
+
if PYDANTIC_V2:
|
|
50
|
+
model_config = ConfigDict(extra=Extra.allow)
|
|
51
|
+
else:
|
|
52
|
+
|
|
53
|
+
class Config:
|
|
54
|
+
extra = "allow"
|
|
42
55
|
|
|
43
56
|
|
|
44
57
|
class Info(BaseModel):
|
|
@@ -49,7 +62,12 @@ class Info(BaseModel):
|
|
|
49
62
|
license: Optional[License] = None
|
|
50
63
|
version: str
|
|
51
64
|
|
|
52
|
-
|
|
65
|
+
if PYDANTIC_V2:
|
|
66
|
+
model_config = ConfigDict(extra=Extra.allow)
|
|
67
|
+
else:
|
|
68
|
+
|
|
69
|
+
class Config:
|
|
70
|
+
extra = "allow"
|
|
53
71
|
|
|
54
72
|
|
|
55
73
|
# class URLHost(Field)
|
|
@@ -76,7 +94,12 @@ class ExternalDocumentation(BaseModel):
|
|
|
76
94
|
description: Optional[str] = None
|
|
77
95
|
url: AnyUrl
|
|
78
96
|
|
|
79
|
-
|
|
97
|
+
if PYDANTIC_V2:
|
|
98
|
+
model_config = ConfigDict(extra=Extra.allow)
|
|
99
|
+
else:
|
|
100
|
+
|
|
101
|
+
class Config:
|
|
102
|
+
extra = "allow"
|
|
80
103
|
|
|
81
104
|
|
|
82
105
|
class Reference(BaseModel):
|
|
@@ -90,7 +113,12 @@ class XML(BaseModel):
|
|
|
90
113
|
attribute: Optional[bool] = None
|
|
91
114
|
wrapped: Optional[bool] = None
|
|
92
115
|
|
|
93
|
-
|
|
116
|
+
if PYDANTIC_V2:
|
|
117
|
+
model_config = ConfigDict(extra=Extra.allow)
|
|
118
|
+
else:
|
|
119
|
+
|
|
120
|
+
class Config:
|
|
121
|
+
extra = "allow"
|
|
94
122
|
|
|
95
123
|
|
|
96
124
|
class Schema(BaseModel):
|
|
@@ -128,8 +156,12 @@ class Schema(BaseModel):
|
|
|
128
156
|
externalDocs: Optional[ExternalDocumentation] = None
|
|
129
157
|
example: Optional[Any] = None
|
|
130
158
|
|
|
131
|
-
|
|
132
|
-
|
|
159
|
+
if PYDANTIC_V2:
|
|
160
|
+
model_config = ConfigDict(extra=Extra.allow)
|
|
161
|
+
else:
|
|
162
|
+
|
|
163
|
+
class Config:
|
|
164
|
+
extra = "allow"
|
|
133
165
|
|
|
134
166
|
|
|
135
167
|
class _Schema2(BaseModel):
|
|
@@ -151,15 +183,23 @@ class _Schema2(BaseModel):
|
|
|
151
183
|
enum: Optional[List[Any]] = None
|
|
152
184
|
multipleOf: Optional[float] = None
|
|
153
185
|
|
|
154
|
-
|
|
155
|
-
|
|
186
|
+
if PYDANTIC_V2:
|
|
187
|
+
model_config = ConfigDict(extra=Extra.allow)
|
|
188
|
+
else:
|
|
189
|
+
|
|
190
|
+
class Config:
|
|
191
|
+
extra = "allow"
|
|
156
192
|
|
|
157
193
|
|
|
158
194
|
class ParameterSchema(_Schema2):
|
|
159
195
|
allowEmptyValue: bool = False
|
|
160
196
|
|
|
161
|
-
|
|
162
|
-
|
|
197
|
+
if PYDANTIC_V2:
|
|
198
|
+
model_config = ConfigDict(extra=Extra.allow)
|
|
199
|
+
else:
|
|
200
|
+
|
|
201
|
+
class Config:
|
|
202
|
+
extra = "allow"
|
|
163
203
|
|
|
164
204
|
|
|
165
205
|
class ParameterInType(Enum):
|
|
@@ -176,7 +216,12 @@ class ParameterBase(BaseModel):
|
|
|
176
216
|
description: Optional[str] = None
|
|
177
217
|
required: Optional[bool] = None
|
|
178
218
|
|
|
179
|
-
|
|
219
|
+
if PYDANTIC_V2:
|
|
220
|
+
model_config = ConfigDict(extra=Extra.allow)
|
|
221
|
+
else:
|
|
222
|
+
|
|
223
|
+
class Config:
|
|
224
|
+
extra = "allow"
|
|
180
225
|
|
|
181
226
|
|
|
182
227
|
class ParameterBody(ParameterBase):
|
|
@@ -188,7 +233,12 @@ class ParameterBody(ParameterBase):
|
|
|
188
233
|
class ParameterNotBody(ParameterBase, ParameterSchema):
|
|
189
234
|
pass
|
|
190
235
|
|
|
191
|
-
|
|
236
|
+
if PYDANTIC_V2:
|
|
237
|
+
model_config = ConfigDict(extra=Extra.allow)
|
|
238
|
+
else:
|
|
239
|
+
|
|
240
|
+
class Config:
|
|
241
|
+
extra = "allow"
|
|
192
242
|
|
|
193
243
|
|
|
194
244
|
class Header(_Schema2):
|
|
@@ -201,7 +251,12 @@ class Response(BaseModel):
|
|
|
201
251
|
headers: Optional[Dict[str, Union[Header, Reference]]] = None
|
|
202
252
|
examples: Optional[Any] = None # XXX
|
|
203
253
|
|
|
204
|
-
|
|
254
|
+
if PYDANTIC_V2:
|
|
255
|
+
model_config = ConfigDict(extra=Extra.allow)
|
|
256
|
+
else:
|
|
257
|
+
|
|
258
|
+
class Config:
|
|
259
|
+
extra = "allow"
|
|
205
260
|
|
|
206
261
|
|
|
207
262
|
class Operation(BaseModel):
|
|
@@ -219,7 +274,12 @@ class Operation(BaseModel):
|
|
|
219
274
|
deprecated: Optional[bool] = None
|
|
220
275
|
security: Optional[List[Dict[str, List[str]]]] = None
|
|
221
276
|
|
|
222
|
-
|
|
277
|
+
if PYDANTIC_V2:
|
|
278
|
+
model_config = ConfigDict(extra=Extra.allow)
|
|
279
|
+
else:
|
|
280
|
+
|
|
281
|
+
class Config:
|
|
282
|
+
extra = "allow"
|
|
223
283
|
|
|
224
284
|
|
|
225
285
|
class PathItem(BaseModel):
|
|
@@ -233,7 +293,12 @@ class PathItem(BaseModel):
|
|
|
233
293
|
patch: Optional[Operation] = None
|
|
234
294
|
parameters: Optional[List[Union[ParameterBody, ParameterNotBody]]] = None
|
|
235
295
|
|
|
236
|
-
|
|
296
|
+
if PYDANTIC_V2:
|
|
297
|
+
model_config = ConfigDict(extra=Extra.allow)
|
|
298
|
+
else:
|
|
299
|
+
|
|
300
|
+
class Config:
|
|
301
|
+
extra = "allow"
|
|
237
302
|
|
|
238
303
|
|
|
239
304
|
class SecuritySchemeType(Enum):
|
|
@@ -246,7 +311,12 @@ class SecurityBase(BaseModel):
|
|
|
246
311
|
type_: SecuritySchemeType = Field(alias="type")
|
|
247
312
|
description: Optional[str] = None
|
|
248
313
|
|
|
249
|
-
|
|
314
|
+
if PYDANTIC_V2:
|
|
315
|
+
model_config = ConfigDict(extra=Extra.allow)
|
|
316
|
+
else:
|
|
317
|
+
|
|
318
|
+
class Config:
|
|
319
|
+
extra = "allow"
|
|
250
320
|
|
|
251
321
|
|
|
252
322
|
class BasicAuth(SecurityBase):
|
|
@@ -275,7 +345,12 @@ class OAuth2FlowBase(SecurityBase):
|
|
|
275
345
|
flow: OAuth2FlowIn
|
|
276
346
|
scopes: Dict[str, str] = {}
|
|
277
347
|
|
|
278
|
-
|
|
348
|
+
if PYDANTIC_V2:
|
|
349
|
+
model_config = ConfigDict(extra=Extra.allow)
|
|
350
|
+
else:
|
|
351
|
+
|
|
352
|
+
class Config:
|
|
353
|
+
extra = "allow"
|
|
279
354
|
|
|
280
355
|
|
|
281
356
|
class OAuth2Implicit(OAuth2FlowBase):
|
|
@@ -310,7 +385,12 @@ class Tag(BaseModel):
|
|
|
310
385
|
description: Optional[str] = None
|
|
311
386
|
externalDocs: Optional[ExternalDocumentation] = None
|
|
312
387
|
|
|
313
|
-
|
|
388
|
+
if PYDANTIC_V2:
|
|
389
|
+
model_config = ConfigDict(extra=Extra.allow)
|
|
390
|
+
else:
|
|
391
|
+
|
|
392
|
+
class Config:
|
|
393
|
+
extra = "allow"
|
|
314
394
|
|
|
315
395
|
|
|
316
396
|
class Swagger2(BaseModel):
|
|
@@ -332,7 +412,12 @@ class Swagger2(BaseModel):
|
|
|
332
412
|
tags: Optional[List[Tag]] = None
|
|
333
413
|
externalDocs: Optional[ExternalDocumentation] = None
|
|
334
414
|
|
|
335
|
-
|
|
415
|
+
if PYDANTIC_V2:
|
|
416
|
+
model_config = ConfigDict(extra=Extra.allow)
|
|
417
|
+
else:
|
|
418
|
+
|
|
419
|
+
class Config:
|
|
420
|
+
extra = "allow"
|
|
336
421
|
|
|
337
422
|
|
|
338
423
|
_model_rebuild(Schema)
|
|
@@ -9,7 +9,6 @@ from fastapi._compat import (
|
|
|
9
9
|
PYDANTIC_V2,
|
|
10
10
|
GenerateJsonSchema,
|
|
11
11
|
JsonSchemaValue,
|
|
12
|
-
ModelField,
|
|
13
12
|
Undefined,
|
|
14
13
|
get_compat_model_name_map,
|
|
15
14
|
lenient_issubclass,
|
|
@@ -39,8 +38,11 @@ from fastapi_swagger2.constants import REF_PREFIX, REF_TEMPLATE
|
|
|
39
38
|
from fastapi_swagger2.models import Swagger2
|
|
40
39
|
|
|
41
40
|
if PYDANTIC_V2:
|
|
42
|
-
from fastapi._compat import get_definitions, get_schema_from_model_field
|
|
41
|
+
from fastapi._compat import ModelField, get_definitions, get_schema_from_model_field
|
|
43
42
|
else:
|
|
43
|
+
from pydantic.fields import ( # type: ignore[attr-defined,no-redef,assignment,unused-ignore]
|
|
44
|
+
ModelField,
|
|
45
|
+
)
|
|
44
46
|
from pydantic.schema import (
|
|
45
47
|
field_schema,
|
|
46
48
|
get_flat_models_from_fields,
|
|
@@ -54,7 +56,6 @@ else:
|
|
|
54
56
|
) -> Dict[str, Any]:
|
|
55
57
|
definitions: Dict[str, Dict[str, Any]] = {}
|
|
56
58
|
for model in flat_models:
|
|
57
|
-
print(REF_PREFIX)
|
|
58
59
|
m_schema, m_definitions, m_nested_models = model_process_schema(
|
|
59
60
|
model, model_name_map=model_name_map, ref_prefix=REF_PREFIX
|
|
60
61
|
)
|
|
@@ -77,7 +78,7 @@ else:
|
|
|
77
78
|
],
|
|
78
79
|
Dict[str, Dict[str, Any]],
|
|
79
80
|
]:
|
|
80
|
-
models = get_flat_models_from_fields(fields, known_models=set())
|
|
81
|
+
models = get_flat_models_from_fields(fields, known_models=set()) # type: ignore[arg-type,unused-ignore]
|
|
81
82
|
return {}, get_model_definitions(
|
|
82
83
|
flat_models=models, model_name_map=model_name_map
|
|
83
84
|
)
|
|
@@ -93,8 +94,8 @@ else:
|
|
|
93
94
|
separate_input_output_schemas: bool = True,
|
|
94
95
|
) -> Dict[str, Any]:
|
|
95
96
|
# This expects that GenerateJsonSchema was already used to generate the definitions
|
|
96
|
-
return field_schema( # type: ignore[no-any-return]
|
|
97
|
-
field, model_name_map=model_name_map, ref_prefix=REF_PREFIX
|
|
97
|
+
return field_schema( # type: ignore[no-any-return,unused-ignore]
|
|
98
|
+
field, model_name_map=model_name_map, ref_prefix=REF_PREFIX # type: ignore[arg-type,unused-ignore]
|
|
98
99
|
)[0]
|
|
99
100
|
|
|
100
101
|
|
|
@@ -249,7 +250,10 @@ def get_swagger2_operation_parameters(
|
|
|
249
250
|
}
|
|
250
251
|
schema: Dict[str, Any] = param_schema
|
|
251
252
|
if field_info.in_.value == "body":
|
|
252
|
-
|
|
253
|
+
if "$ref" in schema:
|
|
254
|
+
parameter["schema"] = {"$ref", schema["$ref"]}
|
|
255
|
+
else:
|
|
256
|
+
parameter["schema"] = schema
|
|
253
257
|
else:
|
|
254
258
|
parameter.update({k: v for (k, v) in schema.items() if k != "title"})
|
|
255
259
|
if field_info.description:
|
|
@@ -287,7 +291,14 @@ def get_swagger2_operation_request_body(
|
|
|
287
291
|
if required:
|
|
288
292
|
request_body_oai["required"] = required
|
|
289
293
|
|
|
290
|
-
request_media_content: Dict[str, Any] = {
|
|
294
|
+
request_media_content: Dict[str, Any] = {}
|
|
295
|
+
if "$ref" in body_schema:
|
|
296
|
+
request_media_content["schema"] = {"$ref": body_schema["$ref"]}
|
|
297
|
+
request_media_content.update(
|
|
298
|
+
{k: v for (k, v) in body_schema.items() if k != "$ref"}
|
|
299
|
+
)
|
|
300
|
+
else:
|
|
301
|
+
request_media_content["schema"] = body_schema
|
|
291
302
|
if field_info.example != Undefined:
|
|
292
303
|
request_media_content["example"] = jsonable_encoder(field_info.example)
|
|
293
304
|
# request_body_oai["content"] = {request_media_type: request_media_content}
|
|
@@ -342,6 +353,7 @@ def get_swagger2_path(
|
|
|
342
353
|
model_name_map=model_name_map,
|
|
343
354
|
field_mapping=field_mapping,
|
|
344
355
|
)
|
|
356
|
+
|
|
345
357
|
parameters.extend(operation_parameters)
|
|
346
358
|
if parameters:
|
|
347
359
|
all_parameters = {
|
|
@@ -550,6 +562,59 @@ def get_swagger2(
|
|
|
550
562
|
if result:
|
|
551
563
|
path, security_schemes, path_definitions = result
|
|
552
564
|
|
|
565
|
+
for k, v in path.items():
|
|
566
|
+
for param in v["parameters"]:
|
|
567
|
+
if PYDANTIC_V2:
|
|
568
|
+
if "$ref" in param and param.get("in") != "body":
|
|
569
|
+
definition = definitions[
|
|
570
|
+
param.pop("$ref").split("/")[2]
|
|
571
|
+
]
|
|
572
|
+
param.update(
|
|
573
|
+
{
|
|
574
|
+
k: v
|
|
575
|
+
for (k, v) in definition.items()
|
|
576
|
+
if k != "title"
|
|
577
|
+
}
|
|
578
|
+
)
|
|
579
|
+
else:
|
|
580
|
+
if "allOf" in param:
|
|
581
|
+
all_of = param.pop("allOf")
|
|
582
|
+
if len(all_of) > 1:
|
|
583
|
+
logger.warning(
|
|
584
|
+
f"fastapi_swagger2: Unable to handle allOf in path params {all_of}, using the first one."
|
|
585
|
+
)
|
|
586
|
+
|
|
587
|
+
if len(all_of) > 0:
|
|
588
|
+
definition = definitions[
|
|
589
|
+
all_of[0]["$ref"].split("/")[2]
|
|
590
|
+
]
|
|
591
|
+
param.update(
|
|
592
|
+
{
|
|
593
|
+
k: v
|
|
594
|
+
for (k, v) in definition.items()
|
|
595
|
+
if k != "title"
|
|
596
|
+
}
|
|
597
|
+
)
|
|
598
|
+
if param.get("in") == "body" and "allOf" in param.get(
|
|
599
|
+
"schema", {}
|
|
600
|
+
):
|
|
601
|
+
schema = param.pop("schema")
|
|
602
|
+
all_of = schema.pop("allOf")
|
|
603
|
+
if len(all_of) > 1:
|
|
604
|
+
logger.warning(
|
|
605
|
+
f"fastapi_swagger2: Unable to handle allOf in path params {all_of}, using the first one."
|
|
606
|
+
)
|
|
607
|
+
|
|
608
|
+
if len(all_of) > 0:
|
|
609
|
+
param["schema"] = {"$ref": all_of[0]["$ref"]}
|
|
610
|
+
param.update(
|
|
611
|
+
{
|
|
612
|
+
k: v
|
|
613
|
+
for (k, v) in schema.items()
|
|
614
|
+
if k != "title"
|
|
615
|
+
}
|
|
616
|
+
)
|
|
617
|
+
|
|
553
618
|
if path:
|
|
554
619
|
paths.setdefault(route.path_format, {}).update(path)
|
|
555
620
|
|
|
@@ -569,16 +634,33 @@ def get_swagger2(
|
|
|
569
634
|
for k in sorted(definitions):
|
|
570
635
|
properties = definitions[k].get("properties", [])
|
|
571
636
|
for p in properties:
|
|
572
|
-
if "anyOf" in properties[p]
|
|
637
|
+
if "anyOf" in properties[p]:
|
|
573
638
|
any_of = properties[p].pop("anyOf")
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
639
|
+
|
|
640
|
+
if len(any_of) == 1:
|
|
641
|
+
# Single item - just use it directly
|
|
642
|
+
properties[p].update(any_of[0])
|
|
643
|
+
elif len(any_of) == 2:
|
|
644
|
+
# Handle the 2-item case (type + null)
|
|
645
|
+
ref_item = None
|
|
646
|
+
has_null = False
|
|
647
|
+
|
|
648
|
+
for item in any_of:
|
|
649
|
+
if item == {"type": "null"}:
|
|
650
|
+
has_null = True
|
|
651
|
+
elif "$ref" in item:
|
|
652
|
+
ref_item = item
|
|
578
653
|
else:
|
|
579
|
-
properties[p].update(
|
|
654
|
+
properties[p].update(item)
|
|
655
|
+
|
|
656
|
+
if ref_item and has_null:
|
|
657
|
+
properties[p]["allOf"] = [ref_item]
|
|
658
|
+
properties[p]["x-nullable"] = True
|
|
659
|
+
elif has_null:
|
|
660
|
+
properties[p]["x-nullable"] = True
|
|
580
661
|
else:
|
|
581
|
-
|
|
662
|
+
# Fallback for complex anyOf cases (len > 2) or empty (len == 0)
|
|
663
|
+
properties[p]["type"] = "string"
|
|
582
664
|
logger.warning(
|
|
583
665
|
f"fastapi_swagger2: Unable to handle anyOf in definitions {any_of}, defaulting to string type."
|
|
584
666
|
)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|