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.
Files changed (52) hide show
  1. README.md +581 -8
  2. otterapi/__init__.py +73 -0
  3. otterapi/cli.py +327 -29
  4. otterapi/codegen/__init__.py +115 -0
  5. otterapi/codegen/ast_utils.py +134 -5
  6. otterapi/codegen/client.py +1271 -0
  7. otterapi/codegen/codegen.py +1736 -0
  8. otterapi/codegen/dataframes.py +392 -0
  9. otterapi/codegen/emitter.py +473 -0
  10. otterapi/codegen/endpoints.py +2597 -343
  11. otterapi/codegen/pagination.py +1026 -0
  12. otterapi/codegen/schema.py +593 -0
  13. otterapi/codegen/splitting.py +1397 -0
  14. otterapi/codegen/types.py +1345 -0
  15. otterapi/codegen/utils.py +180 -1
  16. otterapi/config.py +1017 -24
  17. otterapi/exceptions.py +231 -0
  18. otterapi/openapi/__init__.py +46 -0
  19. otterapi/openapi/v2/__init__.py +86 -0
  20. otterapi/openapi/v2/spec.json +1607 -0
  21. otterapi/openapi/v2/v2.py +1776 -0
  22. otterapi/openapi/v3/__init__.py +131 -0
  23. otterapi/openapi/v3/spec.json +1651 -0
  24. otterapi/openapi/v3/v3.py +1557 -0
  25. otterapi/openapi/v3_1/__init__.py +133 -0
  26. otterapi/openapi/v3_1/spec.json +1411 -0
  27. otterapi/openapi/v3_1/v3_1.py +798 -0
  28. otterapi/openapi/v3_2/__init__.py +133 -0
  29. otterapi/openapi/v3_2/spec.json +1666 -0
  30. otterapi/openapi/v3_2/v3_2.py +777 -0
  31. otterapi/tests/__init__.py +3 -0
  32. otterapi/tests/fixtures/__init__.py +455 -0
  33. otterapi/tests/test_ast_utils.py +680 -0
  34. otterapi/tests/test_codegen.py +610 -0
  35. otterapi/tests/test_dataframe.py +1038 -0
  36. otterapi/tests/test_exceptions.py +493 -0
  37. otterapi/tests/test_openapi_support.py +616 -0
  38. otterapi/tests/test_openapi_upgrade.py +215 -0
  39. otterapi/tests/test_pagination.py +1101 -0
  40. otterapi/tests/test_splitting_config.py +319 -0
  41. otterapi/tests/test_splitting_integration.py +427 -0
  42. otterapi/tests/test_splitting_resolver.py +512 -0
  43. otterapi/tests/test_splitting_tree.py +525 -0
  44. otterapi-0.0.6.dist-info/METADATA +627 -0
  45. otterapi-0.0.6.dist-info/RECORD +48 -0
  46. {otterapi-0.0.5.dist-info → otterapi-0.0.6.dist-info}/WHEEL +1 -1
  47. otterapi/codegen/generator.py +0 -358
  48. otterapi/codegen/openapi_processor.py +0 -27
  49. otterapi/codegen/type_generator.py +0 -559
  50. otterapi-0.0.5.dist-info/METADATA +0 -54
  51. otterapi-0.0.5.dist-info/RECORD +0 -16
  52. {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()