jentic-openapi-datamodels 1.0.0a2__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.
- jentic/apitools/openapi/datamodels/low/v30/__init__.py +28 -0
- jentic/apitools/openapi/datamodels/low/v30/discriminator.py +91 -0
- jentic/apitools/openapi/datamodels/low/v30/external_documentation.py +79 -0
- jentic/apitools/openapi/datamodels/low/v30/oauth_flow.py +140 -0
- jentic/apitools/openapi/datamodels/low/v30/oauth_flows.py +165 -0
- jentic/apitools/openapi/datamodels/low/v30/py.typed +0 -0
- jentic/apitools/openapi/datamodels/low/v30/reference.py +64 -0
- jentic/apitools/openapi/datamodels/low/v30/schema.py +626 -0
- jentic/apitools/openapi/datamodels/low/v30/security_requirement.py +91 -0
- jentic/apitools/openapi/datamodels/low/v30/security_scheme.py +301 -0
- jentic/apitools/openapi/datamodels/low/v30/specification_object.py +217 -0
- jentic/apitools/openapi/datamodels/low/v30/tag.py +132 -0
- jentic/apitools/openapi/datamodels/low/v30/xml.py +134 -0
- jentic_openapi_datamodels-1.0.0a2.dist-info/METADATA +52 -0
- jentic_openapi_datamodels-1.0.0a2.dist-info/RECORD +18 -0
- jentic_openapi_datamodels-1.0.0a2.dist-info/WHEEL +4 -0
- jentic_openapi_datamodels-1.0.0a2.dist-info/licenses/LICENSE +202 -0
- jentic_openapi_datamodels-1.0.0a2.dist-info/licenses/NOTICE +4 -0
|
@@ -0,0 +1,626 @@
|
|
|
1
|
+
"""
|
|
2
|
+
OpenAPI 3.0.4 Schema Object model.
|
|
3
|
+
|
|
4
|
+
The Schema Object allows the definition of input and output data types.
|
|
5
|
+
These types can be objects, but also primitives and arrays.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
from collections.abc import Mapping, Sequence
|
|
11
|
+
from typing import Any
|
|
12
|
+
|
|
13
|
+
from jentic.apitools.openapi.datamodels.low.v30.discriminator import Discriminator
|
|
14
|
+
from jentic.apitools.openapi.datamodels.low.v30.external_documentation import (
|
|
15
|
+
ExternalDocumentation,
|
|
16
|
+
)
|
|
17
|
+
from jentic.apitools.openapi.datamodels.low.v30.reference import Reference
|
|
18
|
+
from jentic.apitools.openapi.datamodels.low.v30.specification_object import SpecificationObject
|
|
19
|
+
from jentic.apitools.openapi.datamodels.low.v30.xml import XML
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
__all__ = ["Schema"]
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class Schema(SpecificationObject):
|
|
26
|
+
"""
|
|
27
|
+
Represents a Schema Object from OpenAPI 3.0.4.
|
|
28
|
+
|
|
29
|
+
The Schema Object allows the definition of input and output data types.
|
|
30
|
+
Based on a subset of JSON Schema Draft 4/5 with OpenAPI-specific extensions.
|
|
31
|
+
|
|
32
|
+
Supports specification extensions (x-* fields).
|
|
33
|
+
|
|
34
|
+
Example:
|
|
35
|
+
>>> # String schema with constraints
|
|
36
|
+
>>> schema = Schema({
|
|
37
|
+
... "type": "string",
|
|
38
|
+
... "minLength": 1,
|
|
39
|
+
... "maxLength": 100
|
|
40
|
+
... })
|
|
41
|
+
>>> schema.type
|
|
42
|
+
'string'
|
|
43
|
+
|
|
44
|
+
>>> # Object schema with properties
|
|
45
|
+
>>> schema = Schema({
|
|
46
|
+
... "type": "object",
|
|
47
|
+
... "required": ["name"],
|
|
48
|
+
... "properties": {
|
|
49
|
+
... "name": {"type": "string"},
|
|
50
|
+
... "age": {"type": "integer"}
|
|
51
|
+
... }
|
|
52
|
+
... })
|
|
53
|
+
>>> schema.required
|
|
54
|
+
['name']
|
|
55
|
+
|
|
56
|
+
>>> # Schema with discriminator
|
|
57
|
+
>>> schema = Schema({
|
|
58
|
+
... "discriminator": {
|
|
59
|
+
... "propertyName": "petType"
|
|
60
|
+
... }
|
|
61
|
+
... })
|
|
62
|
+
>>> schema.discriminator.property_name
|
|
63
|
+
'petType'
|
|
64
|
+
"""
|
|
65
|
+
|
|
66
|
+
_supports_extensions: bool = True
|
|
67
|
+
_fixed_fields: frozenset[str] = frozenset(
|
|
68
|
+
{
|
|
69
|
+
# JSON Schema Core
|
|
70
|
+
"title",
|
|
71
|
+
"multipleOf",
|
|
72
|
+
"maximum",
|
|
73
|
+
"exclusiveMaximum",
|
|
74
|
+
"minimum",
|
|
75
|
+
"exclusiveMinimum",
|
|
76
|
+
"maxLength",
|
|
77
|
+
"minLength",
|
|
78
|
+
"pattern",
|
|
79
|
+
"maxItems",
|
|
80
|
+
"minItems",
|
|
81
|
+
"uniqueItems",
|
|
82
|
+
"maxProperties",
|
|
83
|
+
"minProperties",
|
|
84
|
+
"required",
|
|
85
|
+
"enum",
|
|
86
|
+
# JSON Schema Type
|
|
87
|
+
"type",
|
|
88
|
+
"allOf",
|
|
89
|
+
"oneOf",
|
|
90
|
+
"anyOf",
|
|
91
|
+
"not",
|
|
92
|
+
"items",
|
|
93
|
+
"properties",
|
|
94
|
+
"additionalProperties",
|
|
95
|
+
# JSON Schema Metadata
|
|
96
|
+
"description",
|
|
97
|
+
"format",
|
|
98
|
+
"default",
|
|
99
|
+
# OpenAPI Extensions
|
|
100
|
+
"nullable",
|
|
101
|
+
"discriminator",
|
|
102
|
+
"readOnly",
|
|
103
|
+
"writeOnly",
|
|
104
|
+
"xml",
|
|
105
|
+
"externalDocs",
|
|
106
|
+
"example",
|
|
107
|
+
"deprecated",
|
|
108
|
+
}
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
def __init__(self, data: Mapping[str, Any] | None = None):
|
|
112
|
+
"""
|
|
113
|
+
Initialize a Schema object.
|
|
114
|
+
|
|
115
|
+
Automatically marshals nested objects (discriminator, xml, externalDocs, and nested schemas).
|
|
116
|
+
|
|
117
|
+
Args:
|
|
118
|
+
data: Optional mapping to initialize the object with
|
|
119
|
+
"""
|
|
120
|
+
super().__init__()
|
|
121
|
+
if data:
|
|
122
|
+
for key, value in data.items():
|
|
123
|
+
# Marshal specific nested objects
|
|
124
|
+
if (
|
|
125
|
+
key == "discriminator"
|
|
126
|
+
and isinstance(value, Mapping)
|
|
127
|
+
and not isinstance(value, Discriminator)
|
|
128
|
+
):
|
|
129
|
+
self[key] = Discriminator(value)
|
|
130
|
+
elif key == "xml" and isinstance(value, Mapping) and not isinstance(value, XML):
|
|
131
|
+
self[key] = XML(value)
|
|
132
|
+
elif (
|
|
133
|
+
key == "externalDocs"
|
|
134
|
+
and isinstance(value, Mapping)
|
|
135
|
+
and not isinstance(value, ExternalDocumentation)
|
|
136
|
+
):
|
|
137
|
+
self[key] = ExternalDocumentation(value)
|
|
138
|
+
# Unmarshal schema composition lists (allOf, oneOf, anyOf)
|
|
139
|
+
elif (
|
|
140
|
+
key in ("allOf", "oneOf", "anyOf")
|
|
141
|
+
and isinstance(value, Sequence)
|
|
142
|
+
and not isinstance(value, str)
|
|
143
|
+
):
|
|
144
|
+
self[key] = [self._unmarshal_schema_or_reference(item) for item in value]
|
|
145
|
+
# Unmarshal single schema fields (not, items)
|
|
146
|
+
elif key in ("not", "items") and isinstance(value, Mapping):
|
|
147
|
+
self[key] = self._unmarshal_schema_or_reference(value)
|
|
148
|
+
# Unmarshal properties dict
|
|
149
|
+
elif key == "properties" and isinstance(value, Mapping):
|
|
150
|
+
self[key] = {
|
|
151
|
+
k: self._unmarshal_schema_or_reference(v) for k, v in value.items()
|
|
152
|
+
}
|
|
153
|
+
# Unmarshal additionalProperties (can be bool or schema)
|
|
154
|
+
elif key == "additionalProperties":
|
|
155
|
+
if isinstance(value, bool):
|
|
156
|
+
self[key] = value
|
|
157
|
+
elif isinstance(value, Mapping):
|
|
158
|
+
self[key] = self._unmarshal_schema_or_reference(value)
|
|
159
|
+
else:
|
|
160
|
+
self[key] = self._copy_value(value)
|
|
161
|
+
else:
|
|
162
|
+
# Store as-is (with defensive copy)
|
|
163
|
+
self[key] = self._copy_value(value)
|
|
164
|
+
|
|
165
|
+
# JSON Schema Core - Metadata
|
|
166
|
+
@property
|
|
167
|
+
def title(self) -> str | None:
|
|
168
|
+
"""A title for the schema."""
|
|
169
|
+
return self.get("title")
|
|
170
|
+
|
|
171
|
+
@title.setter
|
|
172
|
+
def title(self, value: str | None) -> None:
|
|
173
|
+
if value is None:
|
|
174
|
+
self.pop("title", None)
|
|
175
|
+
else:
|
|
176
|
+
self["title"] = value
|
|
177
|
+
|
|
178
|
+
# JSON Schema Core - Numeric validation
|
|
179
|
+
@property
|
|
180
|
+
def multiple_of(self) -> float | int | None:
|
|
181
|
+
"""Value must be multiple of this number."""
|
|
182
|
+
return self.get("multipleOf")
|
|
183
|
+
|
|
184
|
+
@multiple_of.setter
|
|
185
|
+
def multiple_of(self, value: float | int | None) -> None:
|
|
186
|
+
if value is None:
|
|
187
|
+
self.pop("multipleOf", None)
|
|
188
|
+
else:
|
|
189
|
+
self["multipleOf"] = value
|
|
190
|
+
|
|
191
|
+
@property
|
|
192
|
+
def maximum(self) -> float | int | None:
|
|
193
|
+
"""Maximum value (inclusive)."""
|
|
194
|
+
return self.get("maximum")
|
|
195
|
+
|
|
196
|
+
@maximum.setter
|
|
197
|
+
def maximum(self, value: float | int | None) -> None:
|
|
198
|
+
if value is None:
|
|
199
|
+
self.pop("maximum", None)
|
|
200
|
+
else:
|
|
201
|
+
self["maximum"] = value
|
|
202
|
+
|
|
203
|
+
@property
|
|
204
|
+
def exclusive_maximum(self) -> float | int | None:
|
|
205
|
+
"""Maximum value (exclusive)."""
|
|
206
|
+
return self.get("exclusiveMaximum")
|
|
207
|
+
|
|
208
|
+
@exclusive_maximum.setter
|
|
209
|
+
def exclusive_maximum(self, value: float | int | None) -> None:
|
|
210
|
+
if value is None:
|
|
211
|
+
self.pop("exclusiveMaximum", None)
|
|
212
|
+
else:
|
|
213
|
+
self["exclusiveMaximum"] = value
|
|
214
|
+
|
|
215
|
+
@property
|
|
216
|
+
def minimum(self) -> float | int | None:
|
|
217
|
+
"""Minimum value (inclusive)."""
|
|
218
|
+
return self.get("minimum")
|
|
219
|
+
|
|
220
|
+
@minimum.setter
|
|
221
|
+
def minimum(self, value: float | int | None) -> None:
|
|
222
|
+
if value is None:
|
|
223
|
+
self.pop("minimum", None)
|
|
224
|
+
else:
|
|
225
|
+
self["minimum"] = value
|
|
226
|
+
|
|
227
|
+
@property
|
|
228
|
+
def exclusive_minimum(self) -> float | int | None:
|
|
229
|
+
"""Minimum value (exclusive)."""
|
|
230
|
+
return self.get("exclusiveMinimum")
|
|
231
|
+
|
|
232
|
+
@exclusive_minimum.setter
|
|
233
|
+
def exclusive_minimum(self, value: float | int | None) -> None:
|
|
234
|
+
if value is None:
|
|
235
|
+
self.pop("exclusiveMinimum", None)
|
|
236
|
+
else:
|
|
237
|
+
self["exclusiveMinimum"] = value
|
|
238
|
+
|
|
239
|
+
# String validation properties
|
|
240
|
+
@property
|
|
241
|
+
def max_length(self) -> int | None:
|
|
242
|
+
"""Maximum string length."""
|
|
243
|
+
return self.get("maxLength")
|
|
244
|
+
|
|
245
|
+
@max_length.setter
|
|
246
|
+
def max_length(self, value: int | None) -> None:
|
|
247
|
+
if value is None:
|
|
248
|
+
self.pop("maxLength", None)
|
|
249
|
+
else:
|
|
250
|
+
self["maxLength"] = value
|
|
251
|
+
|
|
252
|
+
@property
|
|
253
|
+
def min_length(self) -> int | None:
|
|
254
|
+
"""Minimum string length."""
|
|
255
|
+
return self.get("minLength")
|
|
256
|
+
|
|
257
|
+
@min_length.setter
|
|
258
|
+
def min_length(self, value: int | None) -> None:
|
|
259
|
+
if value is None:
|
|
260
|
+
self.pop("minLength", None)
|
|
261
|
+
else:
|
|
262
|
+
self["minLength"] = value
|
|
263
|
+
|
|
264
|
+
@property
|
|
265
|
+
def pattern(self) -> str | None:
|
|
266
|
+
"""Regular expression pattern for string validation."""
|
|
267
|
+
return self.get("pattern")
|
|
268
|
+
|
|
269
|
+
@pattern.setter
|
|
270
|
+
def pattern(self, value: str | None) -> None:
|
|
271
|
+
if value is None:
|
|
272
|
+
self.pop("pattern", None)
|
|
273
|
+
else:
|
|
274
|
+
self["pattern"] = value
|
|
275
|
+
|
|
276
|
+
# Array validation properties
|
|
277
|
+
@property
|
|
278
|
+
def max_items(self) -> int | None:
|
|
279
|
+
"""Maximum number of array items."""
|
|
280
|
+
return self.get("maxItems")
|
|
281
|
+
|
|
282
|
+
@max_items.setter
|
|
283
|
+
def max_items(self, value: int | None) -> None:
|
|
284
|
+
if value is None:
|
|
285
|
+
self.pop("maxItems", None)
|
|
286
|
+
else:
|
|
287
|
+
self["maxItems"] = value
|
|
288
|
+
|
|
289
|
+
@property
|
|
290
|
+
def min_items(self) -> int | None:
|
|
291
|
+
"""Minimum number of array items."""
|
|
292
|
+
return self.get("minItems")
|
|
293
|
+
|
|
294
|
+
@min_items.setter
|
|
295
|
+
def min_items(self, value: int | None) -> None:
|
|
296
|
+
if value is None:
|
|
297
|
+
self.pop("minItems", None)
|
|
298
|
+
else:
|
|
299
|
+
self["minItems"] = value
|
|
300
|
+
|
|
301
|
+
@property
|
|
302
|
+
def unique_items(self) -> bool | None:
|
|
303
|
+
"""Whether array items must be unique."""
|
|
304
|
+
return self.get("uniqueItems")
|
|
305
|
+
|
|
306
|
+
@unique_items.setter
|
|
307
|
+
def unique_items(self, value: bool | None) -> None:
|
|
308
|
+
if value is None:
|
|
309
|
+
self.pop("uniqueItems", None)
|
|
310
|
+
else:
|
|
311
|
+
self["uniqueItems"] = value
|
|
312
|
+
|
|
313
|
+
# JSON Schema Core - Object validation
|
|
314
|
+
@property
|
|
315
|
+
def max_properties(self) -> int | None:
|
|
316
|
+
"""Maximum number of object properties."""
|
|
317
|
+
return self.get("maxProperties")
|
|
318
|
+
|
|
319
|
+
@max_properties.setter
|
|
320
|
+
def max_properties(self, value: int | None) -> None:
|
|
321
|
+
if value is None:
|
|
322
|
+
self.pop("maxProperties", None)
|
|
323
|
+
else:
|
|
324
|
+
self["maxProperties"] = value
|
|
325
|
+
|
|
326
|
+
@property
|
|
327
|
+
def min_properties(self) -> int | None:
|
|
328
|
+
"""Minimum number of object properties."""
|
|
329
|
+
return self.get("minProperties")
|
|
330
|
+
|
|
331
|
+
@min_properties.setter
|
|
332
|
+
def min_properties(self, value: int | None) -> None:
|
|
333
|
+
if value is None:
|
|
334
|
+
self.pop("minProperties", None)
|
|
335
|
+
else:
|
|
336
|
+
self["minProperties"] = value
|
|
337
|
+
|
|
338
|
+
@property
|
|
339
|
+
def required(self) -> list[str] | None:
|
|
340
|
+
"""List of required property names (for object types)."""
|
|
341
|
+
return self.get("required")
|
|
342
|
+
|
|
343
|
+
@required.setter
|
|
344
|
+
def required(self, value: list[str] | None) -> None:
|
|
345
|
+
if value is None:
|
|
346
|
+
self.pop("required", None)
|
|
347
|
+
else:
|
|
348
|
+
self["required"] = value
|
|
349
|
+
|
|
350
|
+
@property
|
|
351
|
+
def enum(self) -> list[Any] | None:
|
|
352
|
+
"""Allowed values."""
|
|
353
|
+
return self.get("enum")
|
|
354
|
+
|
|
355
|
+
@enum.setter
|
|
356
|
+
def enum(self, value: list[Any] | None) -> None:
|
|
357
|
+
if value is None:
|
|
358
|
+
self.pop("enum", None)
|
|
359
|
+
else:
|
|
360
|
+
self["enum"] = value
|
|
361
|
+
|
|
362
|
+
# JSON Schema Type
|
|
363
|
+
@property
|
|
364
|
+
def type(self) -> str | None:
|
|
365
|
+
"""Type of the schema (string, number, integer, boolean, array, object, null)."""
|
|
366
|
+
return self.get("type")
|
|
367
|
+
|
|
368
|
+
@type.setter
|
|
369
|
+
def type(self, value: str | None) -> None:
|
|
370
|
+
if value is None:
|
|
371
|
+
self.pop("type", None)
|
|
372
|
+
else:
|
|
373
|
+
self["type"] = value
|
|
374
|
+
|
|
375
|
+
@property
|
|
376
|
+
def all_of(self) -> list[Schema | Reference] | None:
|
|
377
|
+
"""Schemas that must all be valid (list of Schema or Reference objects)."""
|
|
378
|
+
return self.get("allOf")
|
|
379
|
+
|
|
380
|
+
@all_of.setter
|
|
381
|
+
def all_of(self, value: list[Schema | Reference] | None) -> None:
|
|
382
|
+
if value is None:
|
|
383
|
+
self.pop("allOf", None)
|
|
384
|
+
else:
|
|
385
|
+
self["allOf"] = value
|
|
386
|
+
|
|
387
|
+
@property
|
|
388
|
+
def one_of(self) -> list[Schema | Reference] | None:
|
|
389
|
+
"""Schemas where exactly one must be valid (list of Schema or Reference objects)."""
|
|
390
|
+
return self.get("oneOf")
|
|
391
|
+
|
|
392
|
+
@one_of.setter
|
|
393
|
+
def one_of(self, value: list[Schema | Reference] | None) -> None:
|
|
394
|
+
if value is None:
|
|
395
|
+
self.pop("oneOf", None)
|
|
396
|
+
else:
|
|
397
|
+
self["oneOf"] = value
|
|
398
|
+
|
|
399
|
+
@property
|
|
400
|
+
def any_of(self) -> list[Schema | Reference] | None:
|
|
401
|
+
"""Schemas where at least one must be valid (list of Schema or Reference objects)."""
|
|
402
|
+
return self.get("anyOf")
|
|
403
|
+
|
|
404
|
+
@any_of.setter
|
|
405
|
+
def any_of(self, value: list[Schema | Reference] | None) -> None:
|
|
406
|
+
if value is None:
|
|
407
|
+
self.pop("anyOf", None)
|
|
408
|
+
else:
|
|
409
|
+
self["anyOf"] = value
|
|
410
|
+
|
|
411
|
+
@property
|
|
412
|
+
def not_(self) -> Schema | Reference | None:
|
|
413
|
+
"""Schema that must NOT be valid."""
|
|
414
|
+
return self.get("not")
|
|
415
|
+
|
|
416
|
+
@not_.setter
|
|
417
|
+
def not_(self, value: Schema | Reference | None) -> None:
|
|
418
|
+
if value is None:
|
|
419
|
+
self.pop("not", None)
|
|
420
|
+
else:
|
|
421
|
+
self["not"] = value
|
|
422
|
+
|
|
423
|
+
@property
|
|
424
|
+
def items_(self) -> Schema | Reference | None:
|
|
425
|
+
"""
|
|
426
|
+
Schema for array items (Schema or Reference object).
|
|
427
|
+
|
|
428
|
+
Note: Property named 'items_' (with underscore) to avoid conflict with
|
|
429
|
+
MutableMapping.items() method. Dict access still uses the standard field name:
|
|
430
|
+
schema["items"].
|
|
431
|
+
"""
|
|
432
|
+
return self.get("items")
|
|
433
|
+
|
|
434
|
+
@items_.setter
|
|
435
|
+
def items_(self, value: Schema | Reference | None) -> None:
|
|
436
|
+
if value is None:
|
|
437
|
+
self.pop("items", None)
|
|
438
|
+
else:
|
|
439
|
+
self["items"] = value
|
|
440
|
+
|
|
441
|
+
@property
|
|
442
|
+
def properties(self) -> dict[str, Schema | Reference] | None:
|
|
443
|
+
"""Object properties (map of property name to Schema or Reference)."""
|
|
444
|
+
return self.get("properties")
|
|
445
|
+
|
|
446
|
+
@properties.setter
|
|
447
|
+
def properties(self, value: Mapping[str, Schema | Reference] | None) -> None:
|
|
448
|
+
if value is None:
|
|
449
|
+
self.pop("properties", None)
|
|
450
|
+
else:
|
|
451
|
+
self["properties"] = dict(value) if isinstance(value, Mapping) else value
|
|
452
|
+
|
|
453
|
+
@property
|
|
454
|
+
def additional_properties(self) -> bool | Schema | Reference | None:
|
|
455
|
+
"""Schema for additional properties (bool or Schema or Reference object)."""
|
|
456
|
+
return self.get("additionalProperties")
|
|
457
|
+
|
|
458
|
+
@additional_properties.setter
|
|
459
|
+
def additional_properties(self, value: bool | Schema | Reference | None) -> None:
|
|
460
|
+
if value is None:
|
|
461
|
+
self.pop("additionalProperties", None)
|
|
462
|
+
else:
|
|
463
|
+
self["additionalProperties"] = value
|
|
464
|
+
|
|
465
|
+
# JSON Schema Metadata
|
|
466
|
+
@property
|
|
467
|
+
def description(self) -> str | None:
|
|
468
|
+
"""A description of the schema."""
|
|
469
|
+
return self.get("description")
|
|
470
|
+
|
|
471
|
+
@description.setter
|
|
472
|
+
def description(self, value: str | None) -> None:
|
|
473
|
+
if value is None:
|
|
474
|
+
self.pop("description", None)
|
|
475
|
+
else:
|
|
476
|
+
self["description"] = value
|
|
477
|
+
|
|
478
|
+
@property
|
|
479
|
+
def format(self) -> str | None:
|
|
480
|
+
"""Format hint for the type (e.g., date-time, email, uuid)."""
|
|
481
|
+
return self.get("format")
|
|
482
|
+
|
|
483
|
+
@format.setter
|
|
484
|
+
def format(self, value: str | None) -> None:
|
|
485
|
+
if value is None:
|
|
486
|
+
self.pop("format", None)
|
|
487
|
+
else:
|
|
488
|
+
self["format"] = value
|
|
489
|
+
|
|
490
|
+
@property
|
|
491
|
+
def default(self) -> Any:
|
|
492
|
+
"""Default value."""
|
|
493
|
+
return self.get("default")
|
|
494
|
+
|
|
495
|
+
@default.setter
|
|
496
|
+
def default(self, value: Any) -> None:
|
|
497
|
+
if value is None:
|
|
498
|
+
self.pop("default", None)
|
|
499
|
+
else:
|
|
500
|
+
self["default"] = value
|
|
501
|
+
|
|
502
|
+
# OpenAPI Extensions
|
|
503
|
+
@property
|
|
504
|
+
def nullable(self) -> bool | None:
|
|
505
|
+
"""Whether the value can be null (OpenAPI extension)."""
|
|
506
|
+
return self.get("nullable")
|
|
507
|
+
|
|
508
|
+
@nullable.setter
|
|
509
|
+
def nullable(self, value: bool | None) -> None:
|
|
510
|
+
if value is None:
|
|
511
|
+
self.pop("nullable", None)
|
|
512
|
+
else:
|
|
513
|
+
self["nullable"] = value
|
|
514
|
+
|
|
515
|
+
@property
|
|
516
|
+
def discriminator(self) -> Discriminator | None:
|
|
517
|
+
"""Discriminator for polymorphism (OpenAPI extension)."""
|
|
518
|
+
return self.get("discriminator")
|
|
519
|
+
|
|
520
|
+
@discriminator.setter
|
|
521
|
+
def discriminator(self, value: Discriminator | None) -> None:
|
|
522
|
+
if value is None:
|
|
523
|
+
self.pop("discriminator", None)
|
|
524
|
+
else:
|
|
525
|
+
self["discriminator"] = value
|
|
526
|
+
|
|
527
|
+
@property
|
|
528
|
+
def read_only(self) -> bool | None:
|
|
529
|
+
"""Whether the property is read-only (OpenAPI extension)."""
|
|
530
|
+
return self.get("readOnly")
|
|
531
|
+
|
|
532
|
+
@read_only.setter
|
|
533
|
+
def read_only(self, value: bool | None) -> None:
|
|
534
|
+
if value is None:
|
|
535
|
+
self.pop("readOnly", None)
|
|
536
|
+
else:
|
|
537
|
+
self["readOnly"] = value
|
|
538
|
+
|
|
539
|
+
@property
|
|
540
|
+
def write_only(self) -> bool | None:
|
|
541
|
+
"""Whether the property is write-only (OpenAPI extension)."""
|
|
542
|
+
return self.get("writeOnly")
|
|
543
|
+
|
|
544
|
+
@write_only.setter
|
|
545
|
+
def write_only(self, value: bool | None) -> None:
|
|
546
|
+
if value is None:
|
|
547
|
+
self.pop("writeOnly", None)
|
|
548
|
+
else:
|
|
549
|
+
self["writeOnly"] = value
|
|
550
|
+
|
|
551
|
+
@property
|
|
552
|
+
def xml(self) -> XML | None:
|
|
553
|
+
"""XML representation metadata (OpenAPI extension)."""
|
|
554
|
+
return self.get("xml")
|
|
555
|
+
|
|
556
|
+
@xml.setter
|
|
557
|
+
def xml(self, value: XML | None) -> None:
|
|
558
|
+
if value is None:
|
|
559
|
+
self.pop("xml", None)
|
|
560
|
+
else:
|
|
561
|
+
self["xml"] = value
|
|
562
|
+
|
|
563
|
+
@property
|
|
564
|
+
def external_docs(self) -> ExternalDocumentation | None:
|
|
565
|
+
"""External documentation (OpenAPI extension)."""
|
|
566
|
+
return self.get("externalDocs")
|
|
567
|
+
|
|
568
|
+
@external_docs.setter
|
|
569
|
+
def external_docs(self, value: ExternalDocumentation | None) -> None:
|
|
570
|
+
if value is None:
|
|
571
|
+
self.pop("externalDocs", None)
|
|
572
|
+
else:
|
|
573
|
+
self["externalDocs"] = value
|
|
574
|
+
|
|
575
|
+
@property
|
|
576
|
+
def example(self) -> Any:
|
|
577
|
+
"""Example value (OpenAPI extension)."""
|
|
578
|
+
return self.get("example")
|
|
579
|
+
|
|
580
|
+
@example.setter
|
|
581
|
+
def example(self, value: Any) -> None:
|
|
582
|
+
if value is None:
|
|
583
|
+
self.pop("example", None)
|
|
584
|
+
else:
|
|
585
|
+
self["example"] = value
|
|
586
|
+
|
|
587
|
+
@property
|
|
588
|
+
def deprecated(self) -> bool | None:
|
|
589
|
+
"""Whether the schema is deprecated (OpenAPI extension)."""
|
|
590
|
+
return self.get("deprecated")
|
|
591
|
+
|
|
592
|
+
@deprecated.setter
|
|
593
|
+
def deprecated(self, value: bool | None) -> None:
|
|
594
|
+
if value is None:
|
|
595
|
+
self.pop("deprecated", None)
|
|
596
|
+
else:
|
|
597
|
+
self["deprecated"] = value
|
|
598
|
+
|
|
599
|
+
# Helper methods
|
|
600
|
+
@classmethod
|
|
601
|
+
def _unmarshal_schema_or_reference(cls, value: Any) -> Schema | Reference | Any:
|
|
602
|
+
"""
|
|
603
|
+
Unmarshal a value into Schema or Reference if it's a Mapping.
|
|
604
|
+
|
|
605
|
+
Converts raw data (dict/Mapping) into Schema or Reference objects during construction.
|
|
606
|
+
Uses the actual class (or subclass) for creating Schema instances.
|
|
607
|
+
|
|
608
|
+
Args:
|
|
609
|
+
value: Value to unmarshal
|
|
610
|
+
|
|
611
|
+
Returns:
|
|
612
|
+
Schema or Reference instance, or value as-is
|
|
613
|
+
"""
|
|
614
|
+
if not isinstance(value, Mapping):
|
|
615
|
+
return value
|
|
616
|
+
|
|
617
|
+
# Already unmarshaled
|
|
618
|
+
if isinstance(value, (Schema, Reference)):
|
|
619
|
+
return value
|
|
620
|
+
|
|
621
|
+
# Check if it's a reference (has $ref field)
|
|
622
|
+
if "$ref" in value:
|
|
623
|
+
return Reference(value)
|
|
624
|
+
else:
|
|
625
|
+
# Otherwise treat as Schema (or subclass)
|
|
626
|
+
return cls(value)
|