otterapi 0.0.5__py3-none-any.whl → 0.0.6__py3-none-any.whl
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.
- README.md +581 -8
- otterapi/__init__.py +73 -0
- otterapi/cli.py +327 -29
- otterapi/codegen/__init__.py +115 -0
- otterapi/codegen/ast_utils.py +134 -5
- otterapi/codegen/client.py +1271 -0
- otterapi/codegen/codegen.py +1736 -0
- otterapi/codegen/dataframes.py +392 -0
- otterapi/codegen/emitter.py +473 -0
- otterapi/codegen/endpoints.py +2597 -343
- otterapi/codegen/pagination.py +1026 -0
- otterapi/codegen/schema.py +593 -0
- otterapi/codegen/splitting.py +1397 -0
- otterapi/codegen/types.py +1345 -0
- otterapi/codegen/utils.py +180 -1
- otterapi/config.py +1017 -24
- otterapi/exceptions.py +231 -0
- otterapi/openapi/__init__.py +46 -0
- otterapi/openapi/v2/__init__.py +86 -0
- otterapi/openapi/v2/spec.json +1607 -0
- otterapi/openapi/v2/v2.py +1776 -0
- otterapi/openapi/v3/__init__.py +131 -0
- otterapi/openapi/v3/spec.json +1651 -0
- otterapi/openapi/v3/v3.py +1557 -0
- otterapi/openapi/v3_1/__init__.py +133 -0
- otterapi/openapi/v3_1/spec.json +1411 -0
- otterapi/openapi/v3_1/v3_1.py +798 -0
- otterapi/openapi/v3_2/__init__.py +133 -0
- otterapi/openapi/v3_2/spec.json +1666 -0
- otterapi/openapi/v3_2/v3_2.py +777 -0
- otterapi/tests/__init__.py +3 -0
- otterapi/tests/fixtures/__init__.py +455 -0
- otterapi/tests/test_ast_utils.py +680 -0
- otterapi/tests/test_codegen.py +610 -0
- otterapi/tests/test_dataframe.py +1038 -0
- otterapi/tests/test_exceptions.py +493 -0
- otterapi/tests/test_openapi_support.py +616 -0
- otterapi/tests/test_openapi_upgrade.py +215 -0
- otterapi/tests/test_pagination.py +1101 -0
- otterapi/tests/test_splitting_config.py +319 -0
- otterapi/tests/test_splitting_integration.py +427 -0
- otterapi/tests/test_splitting_resolver.py +512 -0
- otterapi/tests/test_splitting_tree.py +525 -0
- otterapi-0.0.6.dist-info/METADATA +627 -0
- otterapi-0.0.6.dist-info/RECORD +48 -0
- {otterapi-0.0.5.dist-info → otterapi-0.0.6.dist-info}/WHEEL +1 -1
- otterapi/codegen/generator.py +0 -358
- otterapi/codegen/openapi_processor.py +0 -27
- otterapi/codegen/type_generator.py +0 -559
- otterapi-0.0.5.dist-info/METADATA +0 -54
- otterapi-0.0.5.dist-info/RECORD +0 -16
- {otterapi-0.0.5.dist-info → otterapi-0.0.6.dist-info}/entry_points.txt +0 -0
|
@@ -0,0 +1,777 @@
|
|
|
1
|
+
"""OpenAPI 3.2 specification models.
|
|
2
|
+
|
|
3
|
+
This module provides Pydantic models for the OpenAPI 3.2 specification,
|
|
4
|
+
building on top of OpenAPI 3.1 with additional features.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
from enum import Enum
|
|
10
|
+
from typing import Annotated, Any, Union
|
|
11
|
+
|
|
12
|
+
from pydantic import (
|
|
13
|
+
AnyUrl,
|
|
14
|
+
BaseModel,
|
|
15
|
+
ConfigDict,
|
|
16
|
+
Field,
|
|
17
|
+
PositiveFloat,
|
|
18
|
+
RootModel,
|
|
19
|
+
StringConstraints,
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class Reference(BaseModel):
|
|
24
|
+
"""Reference object for OpenAPI 3.2."""
|
|
25
|
+
|
|
26
|
+
ref: str = Field(..., alias='$ref')
|
|
27
|
+
summary: str | None = None
|
|
28
|
+
description: str | None = None
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class Contact(BaseModel):
|
|
32
|
+
"""Contact information for the API."""
|
|
33
|
+
|
|
34
|
+
model_config = ConfigDict(extra='forbid')
|
|
35
|
+
|
|
36
|
+
name: str | None = None
|
|
37
|
+
url: str | None = None
|
|
38
|
+
email: str | None = None
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class License(BaseModel):
|
|
42
|
+
"""License information for the API."""
|
|
43
|
+
|
|
44
|
+
model_config = ConfigDict(extra='forbid')
|
|
45
|
+
|
|
46
|
+
name: str
|
|
47
|
+
identifier: str | None = None
|
|
48
|
+
url: str | None = None
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
class ServerVariable(BaseModel):
|
|
52
|
+
"""Server variable for URL templating."""
|
|
53
|
+
|
|
54
|
+
model_config = ConfigDict(extra='forbid')
|
|
55
|
+
|
|
56
|
+
enum: list[str] | None = None
|
|
57
|
+
default: str
|
|
58
|
+
description: str | None = None
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
class Type(Enum):
|
|
62
|
+
"""JSON Schema types."""
|
|
63
|
+
|
|
64
|
+
array = 'array'
|
|
65
|
+
boolean = 'boolean'
|
|
66
|
+
integer = 'integer'
|
|
67
|
+
number = 'number'
|
|
68
|
+
object = 'object'
|
|
69
|
+
string = 'string'
|
|
70
|
+
null = 'null'
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
class Discriminator(BaseModel):
|
|
74
|
+
"""Discriminator for polymorphism."""
|
|
75
|
+
|
|
76
|
+
propertyName: str
|
|
77
|
+
mapping: dict[str, str] | None = None
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
class XML(BaseModel):
|
|
81
|
+
"""XML representation metadata."""
|
|
82
|
+
|
|
83
|
+
model_config = ConfigDict(extra='forbid')
|
|
84
|
+
|
|
85
|
+
name: str | None = None
|
|
86
|
+
namespace: AnyUrl | None = None
|
|
87
|
+
prefix: str | None = None
|
|
88
|
+
attribute: bool | None = False
|
|
89
|
+
wrapped: bool | None = False
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
class Example(BaseModel):
|
|
93
|
+
"""Example object."""
|
|
94
|
+
|
|
95
|
+
model_config = ConfigDict(extra='forbid')
|
|
96
|
+
|
|
97
|
+
summary: str | None = None
|
|
98
|
+
description: str | None = None
|
|
99
|
+
value: Any | None = None
|
|
100
|
+
externalValue: str | None = None
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
class Style(Enum):
|
|
104
|
+
"""Parameter style for simple parameters."""
|
|
105
|
+
|
|
106
|
+
simple = 'simple'
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
class SecurityRequirement(RootModel[dict[str, list[str]]]):
|
|
110
|
+
"""Security requirement object."""
|
|
111
|
+
|
|
112
|
+
root: dict[str, list[str]]
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
class ExternalDocumentation(BaseModel):
|
|
116
|
+
"""External documentation reference."""
|
|
117
|
+
|
|
118
|
+
model_config = ConfigDict(extra='forbid')
|
|
119
|
+
|
|
120
|
+
description: str | None = None
|
|
121
|
+
url: str
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
class ExampleXORExamples(RootModel[Any]):
|
|
125
|
+
"""Ensures example and examples are mutually exclusive."""
|
|
126
|
+
|
|
127
|
+
root: Any = Field(..., description='Example and examples are mutually exclusive')
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
class SchemaXORContent1(BaseModel):
|
|
131
|
+
"""Helper for schema/content mutual exclusion."""
|
|
132
|
+
|
|
133
|
+
pass
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
class SchemaXORContent(RootModel[Any | SchemaXORContent1]):
|
|
137
|
+
"""Ensures schema and content are mutually exclusive."""
|
|
138
|
+
|
|
139
|
+
root: Any | SchemaXORContent1 = Field(
|
|
140
|
+
...,
|
|
141
|
+
description='Schema and content are mutually exclusive, at least one is required',
|
|
142
|
+
)
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
class In(Enum):
|
|
146
|
+
"""Path parameter location."""
|
|
147
|
+
|
|
148
|
+
path = 'path'
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
class Style1(Enum):
|
|
152
|
+
"""Path parameter styles."""
|
|
153
|
+
|
|
154
|
+
matrix = 'matrix'
|
|
155
|
+
label = 'label'
|
|
156
|
+
simple = 'simple'
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
class Required(Enum):
|
|
160
|
+
"""Required enum for path parameters."""
|
|
161
|
+
|
|
162
|
+
bool_True = True
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
class PathParameter(BaseModel):
|
|
166
|
+
"""Path parameter definition."""
|
|
167
|
+
|
|
168
|
+
in_: In | None = Field(None, alias='in')
|
|
169
|
+
style: Style1 | None = 'simple'
|
|
170
|
+
required: Required
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
class In1(Enum):
|
|
174
|
+
"""Query parameter location."""
|
|
175
|
+
|
|
176
|
+
query = 'query'
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
class Style2(Enum):
|
|
180
|
+
"""Query parameter styles."""
|
|
181
|
+
|
|
182
|
+
form = 'form'
|
|
183
|
+
spaceDelimited = 'spaceDelimited'
|
|
184
|
+
pipeDelimited = 'pipeDelimited'
|
|
185
|
+
deepObject = 'deepObject'
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
class QueryParameter(BaseModel):
|
|
189
|
+
"""Query parameter definition."""
|
|
190
|
+
|
|
191
|
+
in_: In1 | None = Field(None, alias='in')
|
|
192
|
+
style: Style2 | None = 'form'
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
class In2(Enum):
|
|
196
|
+
"""Header parameter location."""
|
|
197
|
+
|
|
198
|
+
header = 'header'
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
class Style3(Enum):
|
|
202
|
+
"""Header parameter style."""
|
|
203
|
+
|
|
204
|
+
simple = 'simple'
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
class HeaderParameter(BaseModel):
|
|
208
|
+
"""Header parameter definition."""
|
|
209
|
+
|
|
210
|
+
in_: In2 | None = Field(None, alias='in')
|
|
211
|
+
style: Style3 | None = 'simple'
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
class In3(Enum):
|
|
215
|
+
"""Cookie parameter location."""
|
|
216
|
+
|
|
217
|
+
cookie = 'cookie'
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
class Style4(Enum):
|
|
221
|
+
"""Cookie parameter style."""
|
|
222
|
+
|
|
223
|
+
form = 'form'
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
class CookieParameter(BaseModel):
|
|
227
|
+
"""Cookie parameter definition."""
|
|
228
|
+
|
|
229
|
+
in_: In3 | None = Field(None, alias='in')
|
|
230
|
+
style: Style4 | None = 'form'
|
|
231
|
+
|
|
232
|
+
|
|
233
|
+
class Type1(Enum):
|
|
234
|
+
"""API Key security type."""
|
|
235
|
+
|
|
236
|
+
apiKey = 'apiKey'
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
class In4(Enum):
|
|
240
|
+
"""API Key location."""
|
|
241
|
+
|
|
242
|
+
header = 'header'
|
|
243
|
+
query = 'query'
|
|
244
|
+
cookie = 'cookie'
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
class APIKeySecurityScheme(BaseModel):
|
|
248
|
+
"""API Key security scheme."""
|
|
249
|
+
|
|
250
|
+
model_config = ConfigDict(extra='forbid')
|
|
251
|
+
|
|
252
|
+
type: Type1
|
|
253
|
+
name: str
|
|
254
|
+
in_: In4 = Field(..., alias='in')
|
|
255
|
+
description: str | None = None
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
class Type2(Enum):
|
|
259
|
+
"""HTTP security type."""
|
|
260
|
+
|
|
261
|
+
http = 'http'
|
|
262
|
+
|
|
263
|
+
|
|
264
|
+
class HTTPSecurityScheme1(BaseModel):
|
|
265
|
+
"""HTTP Bearer security scheme."""
|
|
266
|
+
|
|
267
|
+
model_config = ConfigDict(extra='forbid')
|
|
268
|
+
|
|
269
|
+
scheme: Annotated[str, StringConstraints(pattern=r'^[Bb][Ee][Aa][Rr][Ee][Rr]$')]
|
|
270
|
+
bearerFormat: str | None = None
|
|
271
|
+
description: str | None = None
|
|
272
|
+
type: Type2
|
|
273
|
+
|
|
274
|
+
|
|
275
|
+
class HTTPSecurityScheme2(BaseModel):
|
|
276
|
+
"""HTTP non-Bearer security scheme."""
|
|
277
|
+
|
|
278
|
+
model_config = ConfigDict(extra='forbid')
|
|
279
|
+
|
|
280
|
+
scheme: str
|
|
281
|
+
bearerFormat: str | None = None
|
|
282
|
+
description: str | None = None
|
|
283
|
+
type: Type2
|
|
284
|
+
|
|
285
|
+
|
|
286
|
+
class HTTPSecurityScheme(RootModel[HTTPSecurityScheme1 | HTTPSecurityScheme2]):
|
|
287
|
+
"""HTTP security scheme union."""
|
|
288
|
+
|
|
289
|
+
root: HTTPSecurityScheme1 | HTTPSecurityScheme2
|
|
290
|
+
|
|
291
|
+
|
|
292
|
+
class Type4(Enum):
|
|
293
|
+
"""OAuth2 security type."""
|
|
294
|
+
|
|
295
|
+
oauth2 = 'oauth2'
|
|
296
|
+
|
|
297
|
+
|
|
298
|
+
class Type5(Enum):
|
|
299
|
+
"""OpenID Connect security type."""
|
|
300
|
+
|
|
301
|
+
openIdConnect = 'openIdConnect'
|
|
302
|
+
|
|
303
|
+
|
|
304
|
+
class OpenIdConnectSecurityScheme(BaseModel):
|
|
305
|
+
"""OpenID Connect security scheme."""
|
|
306
|
+
|
|
307
|
+
model_config = ConfigDict(extra='forbid')
|
|
308
|
+
|
|
309
|
+
type: Type5
|
|
310
|
+
openIdConnectUrl: str
|
|
311
|
+
description: str | None = None
|
|
312
|
+
|
|
313
|
+
|
|
314
|
+
class ImplicitOAuthFlow(BaseModel):
|
|
315
|
+
"""OAuth2 implicit flow."""
|
|
316
|
+
|
|
317
|
+
model_config = ConfigDict(extra='forbid')
|
|
318
|
+
|
|
319
|
+
authorizationUrl: str
|
|
320
|
+
refreshUrl: str | None = None
|
|
321
|
+
scopes: dict[str, str]
|
|
322
|
+
|
|
323
|
+
|
|
324
|
+
class PasswordOAuthFlow(BaseModel):
|
|
325
|
+
"""OAuth2 password flow."""
|
|
326
|
+
|
|
327
|
+
model_config = ConfigDict(extra='forbid')
|
|
328
|
+
|
|
329
|
+
tokenUrl: str
|
|
330
|
+
refreshUrl: str | None = None
|
|
331
|
+
scopes: dict[str, str]
|
|
332
|
+
|
|
333
|
+
|
|
334
|
+
class ClientCredentialsFlow(BaseModel):
|
|
335
|
+
"""OAuth2 client credentials flow."""
|
|
336
|
+
|
|
337
|
+
model_config = ConfigDict(extra='forbid')
|
|
338
|
+
|
|
339
|
+
tokenUrl: str
|
|
340
|
+
refreshUrl: str | None = None
|
|
341
|
+
scopes: dict[str, str]
|
|
342
|
+
|
|
343
|
+
|
|
344
|
+
class AuthorizationCodeOAuthFlow(BaseModel):
|
|
345
|
+
"""OAuth2 authorization code flow."""
|
|
346
|
+
|
|
347
|
+
model_config = ConfigDict(extra='forbid')
|
|
348
|
+
|
|
349
|
+
authorizationUrl: str
|
|
350
|
+
tokenUrl: str
|
|
351
|
+
refreshUrl: str | None = None
|
|
352
|
+
scopes: dict[str, str]
|
|
353
|
+
|
|
354
|
+
|
|
355
|
+
class Callback(RootModel[dict[Annotated[str, StringConstraints(pattern=r'^x-')], Any]]):
|
|
356
|
+
"""Callback object."""
|
|
357
|
+
|
|
358
|
+
root: dict[Annotated[str, StringConstraints(pattern=r'^x-')], Any]
|
|
359
|
+
|
|
360
|
+
|
|
361
|
+
class Style5(Enum):
|
|
362
|
+
"""Encoding styles."""
|
|
363
|
+
|
|
364
|
+
form = 'form'
|
|
365
|
+
spaceDelimited = 'spaceDelimited'
|
|
366
|
+
pipeDelimited = 'pipeDelimited'
|
|
367
|
+
deepObject = 'deepObject'
|
|
368
|
+
|
|
369
|
+
|
|
370
|
+
class Info(BaseModel):
|
|
371
|
+
"""API metadata."""
|
|
372
|
+
|
|
373
|
+
model_config = ConfigDict(extra='forbid')
|
|
374
|
+
|
|
375
|
+
title: str
|
|
376
|
+
summary: str | None = None
|
|
377
|
+
description: str | None = None
|
|
378
|
+
termsOfService: str | None = None
|
|
379
|
+
contact: Contact | None = None
|
|
380
|
+
license: License | None = None
|
|
381
|
+
version: str
|
|
382
|
+
|
|
383
|
+
|
|
384
|
+
class Server(BaseModel):
|
|
385
|
+
"""Server object."""
|
|
386
|
+
|
|
387
|
+
model_config = ConfigDict(extra='forbid')
|
|
388
|
+
|
|
389
|
+
url: str
|
|
390
|
+
description: str | None = None
|
|
391
|
+
variables: dict[str, ServerVariable] | None = None
|
|
392
|
+
|
|
393
|
+
|
|
394
|
+
class Schema(BaseModel):
|
|
395
|
+
"""JSON Schema object for OpenAPI 3.2.
|
|
396
|
+
|
|
397
|
+
OpenAPI 3.2 continues to use JSON Schema 2020-12 with OpenAPI vocabulary.
|
|
398
|
+
"""
|
|
399
|
+
|
|
400
|
+
model_config = ConfigDict(extra='forbid')
|
|
401
|
+
|
|
402
|
+
# Core JSON Schema keywords
|
|
403
|
+
title: str | None = None
|
|
404
|
+
multipleOf: PositiveFloat | None = None
|
|
405
|
+
maximum: float | None = None
|
|
406
|
+
exclusiveMaximum: float | None = None
|
|
407
|
+
minimum: float | None = None
|
|
408
|
+
exclusiveMinimum: float | None = None
|
|
409
|
+
maxLength: Annotated[int, Field(ge=0)] | None = None
|
|
410
|
+
minLength: Annotated[int, Field(ge=0)] | None = 0
|
|
411
|
+
pattern: str | None = None
|
|
412
|
+
maxItems: Annotated[int, Field(ge=0)] | None = None
|
|
413
|
+
minItems: Annotated[int, Field(ge=0)] | None = 0
|
|
414
|
+
uniqueItems: bool | None = False
|
|
415
|
+
maxProperties: Annotated[int, Field(ge=0)] | None = None
|
|
416
|
+
minProperties: Annotated[int, Field(ge=0)] | None = 0
|
|
417
|
+
required: list[str] | None = None
|
|
418
|
+
enum: list[Any] | None = None
|
|
419
|
+
|
|
420
|
+
# Type can be an array for nullable types
|
|
421
|
+
type: Type | list[Type] | None = None
|
|
422
|
+
|
|
423
|
+
# Composition keywords
|
|
424
|
+
not_: Schema | Reference | None = Field(None, alias='not')
|
|
425
|
+
allOf: list[Schema | Reference] | None = None
|
|
426
|
+
oneOf: list[Schema | Reference] | None = None
|
|
427
|
+
anyOf: list[Schema | Reference] | None = None
|
|
428
|
+
|
|
429
|
+
# Array keywords
|
|
430
|
+
items: Schema | Reference | None = None
|
|
431
|
+
prefixItems: list[Schema | Reference] | None = None
|
|
432
|
+
contains: Schema | Reference | None = None # New in 3.2
|
|
433
|
+
|
|
434
|
+
# Object keywords
|
|
435
|
+
properties: dict[str, Schema | Reference] | None = None
|
|
436
|
+
additionalProperties: Schema | Reference | bool | None = True
|
|
437
|
+
patternProperties: dict[str, Schema | Reference] | None = None
|
|
438
|
+
propertyNames: Schema | Reference | None = None # New in 3.2
|
|
439
|
+
|
|
440
|
+
# String keywords
|
|
441
|
+
format: str | None = None
|
|
442
|
+
contentMediaType: str | None = None # New in 3.2
|
|
443
|
+
contentEncoding: str | None = None # New in 3.2
|
|
444
|
+
|
|
445
|
+
# Metadata
|
|
446
|
+
description: str | None = None
|
|
447
|
+
default: Any | None = None
|
|
448
|
+
|
|
449
|
+
# Conditional keywords
|
|
450
|
+
if_: Schema | Reference | None = Field(None, alias='if') # New in 3.2
|
|
451
|
+
then: Schema | Reference | None = None # New in 3.2
|
|
452
|
+
else_: Schema | Reference | None = Field(None, alias='else') # New in 3.2
|
|
453
|
+
dependentSchemas: dict[str, Schema | Reference] | None = None # New in 3.2
|
|
454
|
+
|
|
455
|
+
# OpenAPI-specific keywords
|
|
456
|
+
discriminator: Discriminator | None = None
|
|
457
|
+
readOnly: bool | None = False
|
|
458
|
+
writeOnly: bool | None = False
|
|
459
|
+
example: Any | None = None
|
|
460
|
+
examples: list[Any] | None = None
|
|
461
|
+
externalDocs: ExternalDocumentation | None = None
|
|
462
|
+
deprecated: bool | None = False
|
|
463
|
+
xml: XML | None = None
|
|
464
|
+
|
|
465
|
+
|
|
466
|
+
class Tag(BaseModel):
|
|
467
|
+
"""Tag for API operations."""
|
|
468
|
+
|
|
469
|
+
model_config = ConfigDict(extra='forbid')
|
|
470
|
+
|
|
471
|
+
name: str
|
|
472
|
+
description: str | None = None
|
|
473
|
+
externalDocs: ExternalDocumentation | None = None
|
|
474
|
+
|
|
475
|
+
|
|
476
|
+
class OAuthFlows(BaseModel):
|
|
477
|
+
"""OAuth2 flows configuration."""
|
|
478
|
+
|
|
479
|
+
model_config = ConfigDict(extra='forbid')
|
|
480
|
+
|
|
481
|
+
implicit: ImplicitOAuthFlow | None = None
|
|
482
|
+
password: PasswordOAuthFlow | None = None
|
|
483
|
+
clientCredentials: ClientCredentialsFlow | None = None
|
|
484
|
+
authorizationCode: AuthorizationCodeOAuthFlow | None = None
|
|
485
|
+
|
|
486
|
+
|
|
487
|
+
class Link(BaseModel):
|
|
488
|
+
"""Link object for response links."""
|
|
489
|
+
|
|
490
|
+
model_config = ConfigDict(extra='forbid')
|
|
491
|
+
|
|
492
|
+
operationId: str | None = None
|
|
493
|
+
operationRef: str | None = None
|
|
494
|
+
parameters: dict[str, Any] | None = None
|
|
495
|
+
requestBody: Any | None = None
|
|
496
|
+
description: str | None = None
|
|
497
|
+
server: Server | None = None
|
|
498
|
+
|
|
499
|
+
|
|
500
|
+
class OAuth2SecurityScheme(BaseModel):
|
|
501
|
+
"""OAuth2 security scheme."""
|
|
502
|
+
|
|
503
|
+
model_config = ConfigDict(extra='forbid')
|
|
504
|
+
|
|
505
|
+
type: Type4
|
|
506
|
+
flows: OAuthFlows
|
|
507
|
+
description: str | None = None
|
|
508
|
+
|
|
509
|
+
|
|
510
|
+
class SecurityScheme(
|
|
511
|
+
RootModel[
|
|
512
|
+
APIKeySecurityScheme
|
|
513
|
+
| HTTPSecurityScheme
|
|
514
|
+
| OAuth2SecurityScheme
|
|
515
|
+
| OpenIdConnectSecurityScheme
|
|
516
|
+
]
|
|
517
|
+
):
|
|
518
|
+
"""Security scheme union."""
|
|
519
|
+
|
|
520
|
+
root: (
|
|
521
|
+
APIKeySecurityScheme
|
|
522
|
+
| HTTPSecurityScheme
|
|
523
|
+
| OAuth2SecurityScheme
|
|
524
|
+
| OpenIdConnectSecurityScheme
|
|
525
|
+
)
|
|
526
|
+
|
|
527
|
+
|
|
528
|
+
class Components(BaseModel):
|
|
529
|
+
"""Components object for reusable definitions."""
|
|
530
|
+
|
|
531
|
+
model_config = ConfigDict(extra='forbid')
|
|
532
|
+
|
|
533
|
+
schemas: (
|
|
534
|
+
dict[
|
|
535
|
+
Annotated[str, StringConstraints(pattern=r'^[a-zA-Z0-9\.\-_]+$')],
|
|
536
|
+
Schema | Reference,
|
|
537
|
+
]
|
|
538
|
+
| None
|
|
539
|
+
) = None
|
|
540
|
+
responses: (
|
|
541
|
+
dict[
|
|
542
|
+
Annotated[str, StringConstraints(pattern=r'^[a-zA-Z0-9\.\-_]+$')],
|
|
543
|
+
Reference | Response,
|
|
544
|
+
]
|
|
545
|
+
| None
|
|
546
|
+
) = None
|
|
547
|
+
parameters: (
|
|
548
|
+
dict[
|
|
549
|
+
Annotated[str, StringConstraints(pattern=r'^[a-zA-Z0-9\.\-_]+$')],
|
|
550
|
+
Reference | Parameter,
|
|
551
|
+
]
|
|
552
|
+
| None
|
|
553
|
+
) = None
|
|
554
|
+
examples: (
|
|
555
|
+
dict[
|
|
556
|
+
Annotated[str, StringConstraints(pattern=r'^[a-zA-Z0-9\.\-_]+$')],
|
|
557
|
+
Reference | Example,
|
|
558
|
+
]
|
|
559
|
+
| None
|
|
560
|
+
) = None
|
|
561
|
+
requestBodies: (
|
|
562
|
+
dict[
|
|
563
|
+
Annotated[str, StringConstraints(pattern=r'^[a-zA-Z0-9\.\-_]+$')],
|
|
564
|
+
Reference | RequestBody,
|
|
565
|
+
]
|
|
566
|
+
| None
|
|
567
|
+
) = None
|
|
568
|
+
headers: (
|
|
569
|
+
dict[
|
|
570
|
+
Annotated[str, StringConstraints(pattern=r'^[a-zA-Z0-9\.\-_]+$')],
|
|
571
|
+
Reference | Header,
|
|
572
|
+
]
|
|
573
|
+
| None
|
|
574
|
+
) = None
|
|
575
|
+
securitySchemes: (
|
|
576
|
+
dict[
|
|
577
|
+
Annotated[str, StringConstraints(pattern=r'^[a-zA-Z0-9\.\-_]+$')],
|
|
578
|
+
Reference | SecurityScheme,
|
|
579
|
+
]
|
|
580
|
+
| None
|
|
581
|
+
) = None
|
|
582
|
+
links: (
|
|
583
|
+
dict[
|
|
584
|
+
Annotated[str, StringConstraints(pattern=r'^[a-zA-Z0-9\.\-_]+$')],
|
|
585
|
+
Reference | Link,
|
|
586
|
+
]
|
|
587
|
+
| None
|
|
588
|
+
) = None
|
|
589
|
+
callbacks: (
|
|
590
|
+
dict[
|
|
591
|
+
Annotated[str, StringConstraints(pattern=r'^[a-zA-Z0-9\.\-_]+$')],
|
|
592
|
+
Reference | Callback,
|
|
593
|
+
]
|
|
594
|
+
| None
|
|
595
|
+
) = None
|
|
596
|
+
pathItems: (
|
|
597
|
+
dict[
|
|
598
|
+
Annotated[str, StringConstraints(pattern=r'^[a-zA-Z0-9\.\-_]+$')],
|
|
599
|
+
Reference | PathItem,
|
|
600
|
+
]
|
|
601
|
+
| None
|
|
602
|
+
) = None
|
|
603
|
+
|
|
604
|
+
|
|
605
|
+
class Response(BaseModel):
|
|
606
|
+
"""Response object."""
|
|
607
|
+
|
|
608
|
+
model_config = ConfigDict(extra='forbid')
|
|
609
|
+
|
|
610
|
+
description: str
|
|
611
|
+
headers: dict[str, Header | Reference] | None = None
|
|
612
|
+
content: dict[str, MediaType] | None = None
|
|
613
|
+
links: dict[str, Link | Reference] | None = None
|
|
614
|
+
|
|
615
|
+
|
|
616
|
+
class MediaType(BaseModel):
|
|
617
|
+
"""Media type object."""
|
|
618
|
+
|
|
619
|
+
model_config = ConfigDict(extra='forbid')
|
|
620
|
+
|
|
621
|
+
schema_: Schema | Reference | None = Field(None, alias='schema')
|
|
622
|
+
example: Any | None = None
|
|
623
|
+
examples: dict[str, Example | Reference] | None = None
|
|
624
|
+
encoding: dict[str, Encoding] | None = None
|
|
625
|
+
|
|
626
|
+
|
|
627
|
+
class Header(BaseModel):
|
|
628
|
+
"""Header object."""
|
|
629
|
+
|
|
630
|
+
model_config = ConfigDict(extra='forbid')
|
|
631
|
+
|
|
632
|
+
description: str | None = None
|
|
633
|
+
required: bool | None = False
|
|
634
|
+
deprecated: bool | None = False
|
|
635
|
+
allowEmptyValue: bool | None = False
|
|
636
|
+
style: Style | None = 'simple'
|
|
637
|
+
explode: bool | None = None
|
|
638
|
+
allowReserved: bool | None = False
|
|
639
|
+
schema_: Schema | Reference | None = Field(None, alias='schema')
|
|
640
|
+
content: dict[str, MediaType] | None = None
|
|
641
|
+
example: Any | None = None
|
|
642
|
+
examples: dict[str, Example | Reference] | None = None
|
|
643
|
+
|
|
644
|
+
|
|
645
|
+
class Paths(RootModel[dict[str, 'PathItem']]):
|
|
646
|
+
"""Paths object.
|
|
647
|
+
|
|
648
|
+
Keys should be path templates (starting with /) or extensions (starting with x-).
|
|
649
|
+
"""
|
|
650
|
+
|
|
651
|
+
root: dict[str, PathItem]
|
|
652
|
+
|
|
653
|
+
|
|
654
|
+
class PathItem(BaseModel):
|
|
655
|
+
"""Path item object."""
|
|
656
|
+
|
|
657
|
+
model_config = ConfigDict(extra='forbid')
|
|
658
|
+
|
|
659
|
+
field_ref: str | None = Field(None, alias='$ref')
|
|
660
|
+
summary: str | None = None
|
|
661
|
+
description: str | None = None
|
|
662
|
+
get: Operation | None = None
|
|
663
|
+
put: Operation | None = None
|
|
664
|
+
post: Operation | None = None
|
|
665
|
+
delete: Operation | None = None
|
|
666
|
+
options: Operation | None = None
|
|
667
|
+
head: Operation | None = None
|
|
668
|
+
patch: Operation | None = None
|
|
669
|
+
trace: Operation | None = None
|
|
670
|
+
servers: list[Server] | None = None
|
|
671
|
+
parameters: list[Parameter | Reference] | None = None
|
|
672
|
+
|
|
673
|
+
|
|
674
|
+
class Operation(BaseModel):
|
|
675
|
+
"""Operation object."""
|
|
676
|
+
|
|
677
|
+
model_config = ConfigDict(extra='forbid')
|
|
678
|
+
|
|
679
|
+
tags: list[str] | None = None
|
|
680
|
+
summary: str | None = None
|
|
681
|
+
description: str | None = None
|
|
682
|
+
externalDocs: ExternalDocumentation | None = None
|
|
683
|
+
operationId: str | None = None
|
|
684
|
+
parameters: list[Parameter | Reference] | None = None
|
|
685
|
+
requestBody: RequestBody | Reference | None = None
|
|
686
|
+
responses: Responses | None = None
|
|
687
|
+
callbacks: dict[str, Callback | Reference] | None = None
|
|
688
|
+
deprecated: bool | None = False
|
|
689
|
+
security: list[SecurityRequirement] | None = None
|
|
690
|
+
servers: list[Server] | None = None
|
|
691
|
+
|
|
692
|
+
|
|
693
|
+
class Responses(RootModel[dict[str, Response | Reference]]):
|
|
694
|
+
pass
|
|
695
|
+
|
|
696
|
+
|
|
697
|
+
class Parameter(BaseModel):
|
|
698
|
+
"""Parameter object."""
|
|
699
|
+
|
|
700
|
+
model_config = ConfigDict(extra='forbid')
|
|
701
|
+
|
|
702
|
+
name: str
|
|
703
|
+
in_: str = Field(..., alias='in')
|
|
704
|
+
description: str | None = None
|
|
705
|
+
required: bool | None = False
|
|
706
|
+
deprecated: bool | None = False
|
|
707
|
+
allowEmptyValue: bool | None = False
|
|
708
|
+
style: str | None = None
|
|
709
|
+
explode: bool | None = None
|
|
710
|
+
allowReserved: bool | None = False
|
|
711
|
+
schema_: Schema | Reference | None = Field(None, alias='schema')
|
|
712
|
+
content: dict[str, MediaType] | None = None
|
|
713
|
+
example: Any | None = None
|
|
714
|
+
examples: dict[str, Example | Reference] | None = None
|
|
715
|
+
|
|
716
|
+
|
|
717
|
+
class RequestBody(BaseModel):
|
|
718
|
+
"""Request body object."""
|
|
719
|
+
|
|
720
|
+
model_config = ConfigDict(extra='forbid')
|
|
721
|
+
|
|
722
|
+
description: str | None = None
|
|
723
|
+
content: dict[str, MediaType]
|
|
724
|
+
required: bool | None = False
|
|
725
|
+
|
|
726
|
+
|
|
727
|
+
class Encoding(BaseModel):
|
|
728
|
+
"""Encoding object."""
|
|
729
|
+
|
|
730
|
+
model_config = ConfigDict(extra='forbid')
|
|
731
|
+
|
|
732
|
+
contentType: str | None = None
|
|
733
|
+
headers: dict[str, Header | Reference] | None = None
|
|
734
|
+
style: Style5 | None = None
|
|
735
|
+
explode: bool | None = None
|
|
736
|
+
allowReserved: bool | None = False
|
|
737
|
+
|
|
738
|
+
|
|
739
|
+
class Webhook(RootModel[dict[str, Union['PathItem', Reference]]]):
|
|
740
|
+
"""Webhook object."""
|
|
741
|
+
|
|
742
|
+
root: dict[str, PathItem | Reference]
|
|
743
|
+
|
|
744
|
+
|
|
745
|
+
class OpenAPI(BaseModel):
|
|
746
|
+
"""OpenAPI 3.2 root document."""
|
|
747
|
+
|
|
748
|
+
model_config = ConfigDict(extra='forbid')
|
|
749
|
+
|
|
750
|
+
openapi: Annotated[
|
|
751
|
+
str, StringConstraints(pattern=r'^3\.2\.\d+(-.+)?$')
|
|
752
|
+
] # Updated for 3.2.x
|
|
753
|
+
info: Info
|
|
754
|
+
jsonSchemaDialect: str | None = (
|
|
755
|
+
'https://spec.openapis.org/oas/3.2/dialect/base' # Updated for 3.2
|
|
756
|
+
)
|
|
757
|
+
servers: list[Server] | None = None
|
|
758
|
+
paths: Paths | None = None
|
|
759
|
+
webhooks: dict[str, PathItem | Reference] | None = None
|
|
760
|
+
components: Components | None = None
|
|
761
|
+
security: list[SecurityRequirement] | None = None
|
|
762
|
+
tags: list[Tag] | None = None
|
|
763
|
+
externalDocs: ExternalDocumentation | None = None
|
|
764
|
+
|
|
765
|
+
|
|
766
|
+
# Rebuild models to resolve forward references
|
|
767
|
+
Schema.model_rebuild()
|
|
768
|
+
OpenAPI.model_rebuild()
|
|
769
|
+
Components.model_rebuild()
|
|
770
|
+
Response.model_rebuild()
|
|
771
|
+
MediaType.model_rebuild()
|
|
772
|
+
Paths.model_rebuild()
|
|
773
|
+
PathItem.model_rebuild()
|
|
774
|
+
Operation.model_rebuild()
|
|
775
|
+
Parameter.model_rebuild()
|
|
776
|
+
Header.model_rebuild()
|
|
777
|
+
Webhook.model_rebuild()
|