jentic-openapi-datamodels 1.0.0a18__py3-none-any.whl → 1.0.0a19__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/extractors.py +3 -3
- jentic/apitools/openapi/datamodels/low/v30/__init__.py +76 -0
- jentic/apitools/openapi/datamodels/low/v30/builders/__init__.py +312 -0
- jentic/apitools/openapi/datamodels/low/v30/callback.py +131 -0
- jentic/apitools/openapi/datamodels/low/v30/components.py +236 -0
- jentic/apitools/openapi/datamodels/low/v30/contact.py +4 -10
- jentic/apitools/openapi/datamodels/low/v30/discriminator.py +4 -9
- jentic/apitools/openapi/datamodels/low/v30/encoding.py +81 -0
- jentic/apitools/openapi/datamodels/low/v30/example.py +91 -0
- jentic/apitools/openapi/datamodels/low/v30/external_documentation.py +4 -10
- jentic/apitools/openapi/datamodels/low/v30/header.py +120 -0
- jentic/apitools/openapi/datamodels/low/v30/info.py +14 -23
- jentic/apitools/openapi/datamodels/low/v30/license.py +4 -10
- jentic/apitools/openapi/datamodels/low/v30/link.py +141 -0
- jentic/apitools/openapi/datamodels/low/v30/media_type.py +110 -0
- jentic/apitools/openapi/datamodels/low/v30/oauth_flow.py +4 -10
- jentic/apitools/openapi/datamodels/low/v30/oauth_flows.py +7 -15
- jentic/apitools/openapi/datamodels/low/v30/openapi.py +149 -0
- jentic/apitools/openapi/datamodels/low/v30/operation.py +134 -0
- jentic/apitools/openapi/datamodels/low/v30/parameter.py +123 -0
- jentic/apitools/openapi/datamodels/low/v30/path_item.py +125 -0
- jentic/apitools/openapi/datamodels/low/v30/paths.py +108 -0
- jentic/apitools/openapi/datamodels/low/v30/reference.py +5 -9
- jentic/apitools/openapi/datamodels/low/v30/request_body.py +108 -0
- jentic/apitools/openapi/datamodels/low/v30/response.py +104 -0
- jentic/apitools/openapi/datamodels/low/v30/responses.py +109 -0
- jentic/apitools/openapi/datamodels/low/v30/schema.py +81 -97
- jentic/apitools/openapi/datamodels/low/v30/security_requirement.py +14 -9
- jentic/apitools/openapi/datamodels/low/v30/security_scheme.py +42 -22
- jentic/apitools/openapi/datamodels/low/v30/server.py +111 -0
- jentic/apitools/openapi/datamodels/low/v30/server_variable.py +4 -10
- jentic/apitools/openapi/datamodels/low/v30/tag.py +8 -46
- jentic/apitools/openapi/datamodels/low/v30/xml.py +4 -10
- jentic/apitools/openapi/datamodels/low/v31/__init__.py +77 -0
- jentic/apitools/openapi/datamodels/low/v31/builders/__init__.py +347 -0
- jentic/apitools/openapi/datamodels/low/v31/callback.py +131 -0
- jentic/apitools/openapi/datamodels/low/v31/components.py +240 -0
- jentic/apitools/openapi/datamodels/low/v31/contact.py +61 -0
- jentic/apitools/openapi/datamodels/low/v31/discriminator.py +62 -0
- jentic/apitools/openapi/datamodels/low/v31/encoding.py +81 -0
- jentic/apitools/openapi/datamodels/low/v31/example.py +91 -0
- jentic/apitools/openapi/datamodels/low/v31/external_documentation.py +59 -0
- jentic/apitools/openapi/datamodels/low/v31/header.py +120 -0
- jentic/apitools/openapi/datamodels/low/v31/info.py +116 -0
- jentic/apitools/openapi/datamodels/low/v31/license.py +61 -0
- jentic/apitools/openapi/datamodels/low/v31/link.py +141 -0
- jentic/apitools/openapi/datamodels/low/v31/media_type.py +110 -0
- jentic/apitools/openapi/datamodels/low/v31/oauth_flow.py +65 -0
- jentic/apitools/openapi/datamodels/low/v31/oauth_flows.py +108 -0
- jentic/apitools/openapi/datamodels/low/v31/openapi.py +168 -0
- jentic/apitools/openapi/datamodels/low/v31/operation.py +133 -0
- jentic/apitools/openapi/datamodels/low/v31/parameter.py +123 -0
- jentic/apitools/openapi/datamodels/low/v31/path_item.py +125 -0
- jentic/apitools/openapi/datamodels/low/v31/paths.py +108 -0
- jentic/apitools/openapi/datamodels/low/v31/reference.py +65 -0
- jentic/apitools/openapi/datamodels/low/v31/request_body.py +108 -0
- jentic/apitools/openapi/datamodels/low/v31/response.py +104 -0
- jentic/apitools/openapi/datamodels/low/v31/responses.py +109 -0
- jentic/apitools/openapi/datamodels/low/v31/schema.py +498 -0
- jentic/apitools/openapi/datamodels/low/v31/security_requirement.py +106 -0
- jentic/apitools/openapi/datamodels/low/v31/security_scheme.py +129 -0
- jentic/apitools/openapi/datamodels/low/v31/server.py +111 -0
- jentic/apitools/openapi/datamodels/low/v31/server_variable.py +70 -0
- jentic/apitools/openapi/datamodels/low/v31/tag.py +63 -0
- jentic/apitools/openapi/datamodels/low/v31/xml.py +54 -0
- jentic_openapi_datamodels-1.0.0a19.dist-info/METADATA +372 -0
- jentic_openapi_datamodels-1.0.0a19.dist-info/RECORD +75 -0
- jentic/apitools/openapi/datamodels/low/model_builder.py +0 -129
- jentic_openapi_datamodels-1.0.0a18.dist-info/METADATA +0 -211
- jentic_openapi_datamodels-1.0.0a18.dist-info/RECORD +0 -27
- {jentic_openapi_datamodels-1.0.0a18.dist-info → jentic_openapi_datamodels-1.0.0a19.dist-info}/WHEEL +0 -0
- {jentic_openapi_datamodels-1.0.0a18.dist-info → jentic_openapi_datamodels-1.0.0a19.dist-info}/licenses/LICENSE +0 -0
- {jentic_openapi_datamodels-1.0.0a18.dist-info → jentic_openapi_datamodels-1.0.0a19.dist-info}/licenses/NOTICE +0 -0
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
from dataclasses import dataclass, field, replace
|
|
2
|
+
|
|
3
|
+
from ruamel import yaml
|
|
4
|
+
|
|
5
|
+
from ..context import Context
|
|
6
|
+
from ..fields import fixed_field
|
|
7
|
+
from ..sources import FieldSource, KeySource, ValueSource, YAMLInvalidValue, YAMLValue
|
|
8
|
+
from .builders import build_field_source, build_model
|
|
9
|
+
from .callback import Callback
|
|
10
|
+
from .example import Example, build_example_or_reference
|
|
11
|
+
from .header import Header
|
|
12
|
+
from .link import Link
|
|
13
|
+
from .parameter import Parameter, build_parameter_or_reference
|
|
14
|
+
from .reference import Reference
|
|
15
|
+
from .request_body import RequestBody, build_request_body_or_reference
|
|
16
|
+
from .response import Response, build_response_or_reference
|
|
17
|
+
from .schema import Schema, build_schema_or_reference
|
|
18
|
+
from .security_scheme import SecurityScheme, build_security_scheme_or_reference
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
__all__ = ["Components", "build"]
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
@dataclass(frozen=True, slots=True)
|
|
25
|
+
class Components:
|
|
26
|
+
r"""
|
|
27
|
+
Components Object representation for OpenAPI 3.0.
|
|
28
|
+
|
|
29
|
+
Holds reusable objects for different aspects of the OAS. All objects defined within
|
|
30
|
+
the components object have no effect on the API unless they are explicitly referenced
|
|
31
|
+
from properties outside the components object.
|
|
32
|
+
|
|
33
|
+
All component keys MUST match the regex pattern: ^[a-zA-Z0-9\.\-_]+$
|
|
34
|
+
(Note: This is a validation concern and not enforced by this low-level model)
|
|
35
|
+
|
|
36
|
+
Attributes:
|
|
37
|
+
root_node: The top-level node representing the entire Components object in the original source file
|
|
38
|
+
schemas: Reusable Schema Objects or Reference Objects
|
|
39
|
+
responses: Reusable Response Objects or Reference Objects
|
|
40
|
+
parameters: Reusable Parameter Objects or Reference Objects
|
|
41
|
+
examples: Reusable Example Objects or Reference Objects
|
|
42
|
+
request_bodies: Reusable Request Body Objects or Reference Objects
|
|
43
|
+
headers: Reusable Header Objects or Reference Objects
|
|
44
|
+
security_schemes: Reusable Security Scheme Objects or Reference Objects
|
|
45
|
+
links: Reusable Link Objects or Reference Objects
|
|
46
|
+
callbacks: Reusable Callback Objects or Reference Objects
|
|
47
|
+
extensions: Specification extensions (x-* fields)
|
|
48
|
+
"""
|
|
49
|
+
|
|
50
|
+
root_node: yaml.Node
|
|
51
|
+
schemas: FieldSource[dict[KeySource[str], Schema | Reference]] | None = fixed_field()
|
|
52
|
+
responses: FieldSource[dict[KeySource[str], Response | Reference]] | None = fixed_field()
|
|
53
|
+
parameters: FieldSource[dict[KeySource[str], Parameter | Reference]] | None = fixed_field()
|
|
54
|
+
examples: FieldSource[dict[KeySource[str], Example | Reference]] | None = fixed_field()
|
|
55
|
+
request_bodies: FieldSource[dict[KeySource[str], RequestBody | Reference]] | None = fixed_field(
|
|
56
|
+
metadata={"yaml_name": "requestBodies"}
|
|
57
|
+
)
|
|
58
|
+
headers: FieldSource[dict[KeySource[str], "Header | Reference"]] | None = fixed_field()
|
|
59
|
+
security_schemes: FieldSource[dict[KeySource[str], SecurityScheme | Reference]] | None = (
|
|
60
|
+
fixed_field(metadata={"yaml_name": "securitySchemes"})
|
|
61
|
+
)
|
|
62
|
+
links: FieldSource[dict[KeySource[str], "Link | Reference"]] | None = fixed_field()
|
|
63
|
+
callbacks: FieldSource[dict[KeySource[str], "Callback | Reference"]] | None = fixed_field()
|
|
64
|
+
extensions: dict[KeySource[str], ValueSource[YAMLValue]] = field(default_factory=dict)
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def build(
|
|
68
|
+
root: yaml.Node, context: Context | None = None
|
|
69
|
+
) -> Components | ValueSource[YAMLInvalidValue]:
|
|
70
|
+
"""
|
|
71
|
+
Build a Components object from a YAML node.
|
|
72
|
+
|
|
73
|
+
Preserves all source data as-is, regardless of type. This is a low-level/plumbing
|
|
74
|
+
model that provides complete source fidelity for inspection and validation.
|
|
75
|
+
|
|
76
|
+
Args:
|
|
77
|
+
root: The YAML node to parse (should be a MappingNode)
|
|
78
|
+
context: Optional parsing context. If None, a default context will be created.
|
|
79
|
+
|
|
80
|
+
Returns:
|
|
81
|
+
A Components object if the node is valid, or a ValueSource containing
|
|
82
|
+
the invalid data if the root is not a MappingNode (preserving the invalid data
|
|
83
|
+
and its source location for validation).
|
|
84
|
+
|
|
85
|
+
Example:
|
|
86
|
+
from ruamel.yaml import YAML
|
|
87
|
+
yaml = YAML()
|
|
88
|
+
root = yaml.compose('''
|
|
89
|
+
schemas:
|
|
90
|
+
User:
|
|
91
|
+
type: object
|
|
92
|
+
properties:
|
|
93
|
+
id:
|
|
94
|
+
type: integer
|
|
95
|
+
name:
|
|
96
|
+
type: string
|
|
97
|
+
responses:
|
|
98
|
+
NotFound:
|
|
99
|
+
description: Entity not found
|
|
100
|
+
''')
|
|
101
|
+
components = build(root)
|
|
102
|
+
assert 'User' in {k.value for k in components.schemas.value.keys()}
|
|
103
|
+
"""
|
|
104
|
+
context = context or Context()
|
|
105
|
+
|
|
106
|
+
# Use build_model for initial construction
|
|
107
|
+
components_obj = build_model(root, Components, context=context)
|
|
108
|
+
|
|
109
|
+
# If build_model returned ValueSource (invalid node), return it immediately
|
|
110
|
+
if not isinstance(components_obj, Components):
|
|
111
|
+
return components_obj
|
|
112
|
+
|
|
113
|
+
# Manually handle nested complex fields that aren't covered by build_model
|
|
114
|
+
replacements = {}
|
|
115
|
+
for key_node, value_node in root.value:
|
|
116
|
+
key = context.yaml_constructor.construct_yaml_str(key_node)
|
|
117
|
+
|
|
118
|
+
if key == "schemas":
|
|
119
|
+
# Handle schemas field - map of Schema or Reference objects
|
|
120
|
+
if isinstance(value_node, yaml.MappingNode):
|
|
121
|
+
schemas_dict = {}
|
|
122
|
+
for schema_key_node, schema_value_node in value_node.value:
|
|
123
|
+
schema_key = context.yaml_constructor.construct_yaml_str(schema_key_node)
|
|
124
|
+
schema_or_reference = build_schema_or_reference(schema_value_node, context)
|
|
125
|
+
schemas_dict[KeySource(value=schema_key, key_node=schema_key_node)] = (
|
|
126
|
+
schema_or_reference
|
|
127
|
+
)
|
|
128
|
+
replacements["schemas"] = FieldSource(
|
|
129
|
+
value=schemas_dict, key_node=key_node, value_node=value_node
|
|
130
|
+
)
|
|
131
|
+
else:
|
|
132
|
+
# Not a mapping - preserve as-is for validation
|
|
133
|
+
replacements["schemas"] = build_field_source(key_node, value_node, context)
|
|
134
|
+
|
|
135
|
+
elif key == "responses":
|
|
136
|
+
# Handle responses field - map of Response or Reference objects
|
|
137
|
+
if isinstance(value_node, yaml.MappingNode):
|
|
138
|
+
responses_dict = {}
|
|
139
|
+
for response_key_node, response_value_node in value_node.value:
|
|
140
|
+
response_key = context.yaml_constructor.construct_yaml_str(response_key_node)
|
|
141
|
+
response_or_reference = build_response_or_reference(
|
|
142
|
+
response_value_node, context
|
|
143
|
+
)
|
|
144
|
+
responses_dict[KeySource(value=response_key, key_node=response_key_node)] = (
|
|
145
|
+
response_or_reference
|
|
146
|
+
)
|
|
147
|
+
replacements["responses"] = FieldSource(
|
|
148
|
+
value=responses_dict, key_node=key_node, value_node=value_node
|
|
149
|
+
)
|
|
150
|
+
else:
|
|
151
|
+
# Not a mapping - preserve as-is for validation
|
|
152
|
+
replacements["responses"] = build_field_source(key_node, value_node, context)
|
|
153
|
+
|
|
154
|
+
elif key == "parameters":
|
|
155
|
+
# Handle parameters field - map of Parameter or Reference objects
|
|
156
|
+
if isinstance(value_node, yaml.MappingNode):
|
|
157
|
+
parameters_dict = {}
|
|
158
|
+
for parameter_key_node, parameter_value_node in value_node.value:
|
|
159
|
+
parameter_key = context.yaml_constructor.construct_yaml_str(parameter_key_node)
|
|
160
|
+
parameter_or_reference = build_parameter_or_reference(
|
|
161
|
+
parameter_value_node, context
|
|
162
|
+
)
|
|
163
|
+
parameters_dict[KeySource(value=parameter_key, key_node=parameter_key_node)] = (
|
|
164
|
+
parameter_or_reference
|
|
165
|
+
)
|
|
166
|
+
replacements["parameters"] = FieldSource(
|
|
167
|
+
value=parameters_dict, key_node=key_node, value_node=value_node
|
|
168
|
+
)
|
|
169
|
+
else:
|
|
170
|
+
# Not a mapping - preserve as-is for validation
|
|
171
|
+
replacements["parameters"] = build_field_source(key_node, value_node, context)
|
|
172
|
+
|
|
173
|
+
elif key == "examples":
|
|
174
|
+
# Handle examples field - map of Example or Reference objects
|
|
175
|
+
if isinstance(value_node, yaml.MappingNode):
|
|
176
|
+
examples_dict = {}
|
|
177
|
+
for example_key_node, example_value_node in value_node.value:
|
|
178
|
+
example_key = context.yaml_constructor.construct_yaml_str(example_key_node)
|
|
179
|
+
example_or_reference = build_example_or_reference(example_value_node, context)
|
|
180
|
+
examples_dict[KeySource(value=example_key, key_node=example_key_node)] = (
|
|
181
|
+
example_or_reference
|
|
182
|
+
)
|
|
183
|
+
replacements["examples"] = FieldSource(
|
|
184
|
+
value=examples_dict, key_node=key_node, value_node=value_node
|
|
185
|
+
)
|
|
186
|
+
else:
|
|
187
|
+
# Not a mapping - preserve as-is for validation
|
|
188
|
+
replacements["examples"] = build_field_source(key_node, value_node, context)
|
|
189
|
+
|
|
190
|
+
elif key == "requestBodies":
|
|
191
|
+
# Handle requestBodies field - map of RequestBody or Reference objects
|
|
192
|
+
if isinstance(value_node, yaml.MappingNode):
|
|
193
|
+
request_bodies_dict = {}
|
|
194
|
+
for request_body_key_node, request_body_value_node in value_node.value:
|
|
195
|
+
request_body_key = context.yaml_constructor.construct_yaml_str(
|
|
196
|
+
request_body_key_node
|
|
197
|
+
)
|
|
198
|
+
request_body_or_reference = build_request_body_or_reference(
|
|
199
|
+
request_body_value_node, context
|
|
200
|
+
)
|
|
201
|
+
request_bodies_dict[
|
|
202
|
+
KeySource(value=request_body_key, key_node=request_body_key_node)
|
|
203
|
+
] = request_body_or_reference
|
|
204
|
+
replacements["request_bodies"] = FieldSource(
|
|
205
|
+
value=request_bodies_dict, key_node=key_node, value_node=value_node
|
|
206
|
+
)
|
|
207
|
+
else:
|
|
208
|
+
# Not a mapping - preserve as-is for validation
|
|
209
|
+
replacements["request_bodies"] = build_field_source(key_node, value_node, context)
|
|
210
|
+
|
|
211
|
+
elif key == "securitySchemes":
|
|
212
|
+
# Handle securitySchemes field - map of SecurityScheme or Reference objects
|
|
213
|
+
if isinstance(value_node, yaml.MappingNode):
|
|
214
|
+
security_schemes_dict = {}
|
|
215
|
+
for security_scheme_key_node, security_scheme_value_node in value_node.value:
|
|
216
|
+
security_scheme_key = context.yaml_constructor.construct_yaml_str(
|
|
217
|
+
security_scheme_key_node
|
|
218
|
+
)
|
|
219
|
+
security_scheme_or_reference = build_security_scheme_or_reference(
|
|
220
|
+
security_scheme_value_node, context
|
|
221
|
+
)
|
|
222
|
+
security_schemes_dict[
|
|
223
|
+
KeySource(value=security_scheme_key, key_node=security_scheme_key_node)
|
|
224
|
+
] = security_scheme_or_reference
|
|
225
|
+
replacements["security_schemes"] = FieldSource(
|
|
226
|
+
value=security_schemes_dict, key_node=key_node, value_node=value_node
|
|
227
|
+
)
|
|
228
|
+
else:
|
|
229
|
+
# Not a mapping - preserve as-is for validation
|
|
230
|
+
replacements["security_schemes"] = build_field_source(key_node, value_node, context)
|
|
231
|
+
|
|
232
|
+
# Apply all replacements at once
|
|
233
|
+
if replacements:
|
|
234
|
+
components_obj = replace(components_obj, **replacements)
|
|
235
|
+
|
|
236
|
+
return components_obj
|
|
@@ -2,16 +2,10 @@ from dataclasses import dataclass, field
|
|
|
2
2
|
|
|
3
3
|
from ruamel import yaml
|
|
4
4
|
|
|
5
|
-
from
|
|
6
|
-
from
|
|
7
|
-
from
|
|
8
|
-
from
|
|
9
|
-
FieldSource,
|
|
10
|
-
KeySource,
|
|
11
|
-
ValueSource,
|
|
12
|
-
YAMLInvalidValue,
|
|
13
|
-
YAMLValue,
|
|
14
|
-
)
|
|
5
|
+
from ..context import Context
|
|
6
|
+
from ..fields import fixed_field
|
|
7
|
+
from ..sources import FieldSource, KeySource, ValueSource, YAMLInvalidValue, YAMLValue
|
|
8
|
+
from .builders import build_model
|
|
15
9
|
|
|
16
10
|
|
|
17
11
|
__all__ = ["Contact", "build"]
|
|
@@ -2,15 +2,10 @@ from dataclasses import dataclass
|
|
|
2
2
|
|
|
3
3
|
from ruamel import yaml
|
|
4
4
|
|
|
5
|
-
from
|
|
6
|
-
from
|
|
7
|
-
from
|
|
8
|
-
from
|
|
9
|
-
FieldSource,
|
|
10
|
-
KeySource,
|
|
11
|
-
ValueSource,
|
|
12
|
-
YAMLInvalidValue,
|
|
13
|
-
)
|
|
5
|
+
from ..context import Context
|
|
6
|
+
from ..fields import fixed_field
|
|
7
|
+
from ..sources import FieldSource, KeySource, ValueSource, YAMLInvalidValue
|
|
8
|
+
from .builders import build_model
|
|
14
9
|
|
|
15
10
|
|
|
16
11
|
__all__ = ["Discriminator", "build"]
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
from dataclasses import dataclass, field
|
|
2
|
+
|
|
3
|
+
from ruamel import yaml
|
|
4
|
+
|
|
5
|
+
from ..context import Context
|
|
6
|
+
from ..fields import fixed_field
|
|
7
|
+
from ..sources import FieldSource, KeySource, ValueSource, YAMLInvalidValue, YAMLValue
|
|
8
|
+
from .builders import build_model
|
|
9
|
+
from .header import Header
|
|
10
|
+
from .reference import Reference
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
__all__ = ["Encoding", "build"]
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@dataclass(frozen=True, slots=True)
|
|
17
|
+
class Encoding:
|
|
18
|
+
"""
|
|
19
|
+
Encoding Object representation for OpenAPI 3.0.
|
|
20
|
+
|
|
21
|
+
A single encoding definition applied to a single schema property.
|
|
22
|
+
|
|
23
|
+
Attributes:
|
|
24
|
+
root_node: The top-level node representing the entire Encoding object in the original source file
|
|
25
|
+
contentType: The Content-Type for encoding a specific property. Default value depends on the property type:
|
|
26
|
+
for string with format being binary – application/octet-stream;
|
|
27
|
+
for other primitive types – text/plain;
|
|
28
|
+
for object - application/json;
|
|
29
|
+
for array – the default is defined based on the inner type.
|
|
30
|
+
headers: A map allowing additional information to be provided as headers. Content-Type is described
|
|
31
|
+
separately and SHALL be ignored if included.
|
|
32
|
+
style: Describes how a specific property value will be serialized depending on its type.
|
|
33
|
+
explode: When this is true, property values of type array or object generate separate parameters
|
|
34
|
+
for each value of the array, or key-value-pair of the map. For other data types this property
|
|
35
|
+
has no effect. Default value is true.
|
|
36
|
+
allowReserved: Determines whether the parameter value SHOULD allow reserved characters, as defined by
|
|
37
|
+
RFC3986 :/?#[]@!$&'()*+,;= to be included without percent-encoding. The default value is false.
|
|
38
|
+
extensions: Specification extensions (x-* fields)
|
|
39
|
+
"""
|
|
40
|
+
|
|
41
|
+
root_node: yaml.Node
|
|
42
|
+
contentType: FieldSource[str] | None = fixed_field()
|
|
43
|
+
headers: FieldSource[dict[KeySource[str], "Header | Reference"]] | None = fixed_field()
|
|
44
|
+
style: FieldSource[str] | None = fixed_field()
|
|
45
|
+
explode: FieldSource[bool] | None = fixed_field()
|
|
46
|
+
allowReserved: FieldSource[bool] | None = fixed_field()
|
|
47
|
+
extensions: dict[KeySource[str], ValueSource[YAMLValue]] = field(default_factory=dict)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def build(
|
|
51
|
+
root: yaml.Node, context: Context | None = None
|
|
52
|
+
) -> Encoding | ValueSource[YAMLInvalidValue]:
|
|
53
|
+
"""
|
|
54
|
+
Build an Encoding object from a YAML node.
|
|
55
|
+
|
|
56
|
+
Preserves all source data as-is, regardless of type. This is a low-level/plumbing
|
|
57
|
+
model that provides complete source fidelity for inspection and validation.
|
|
58
|
+
|
|
59
|
+
Args:
|
|
60
|
+
root: The YAML node to parse (should be a MappingNode)
|
|
61
|
+
context: Optional parsing context. If None, a default context will be created.
|
|
62
|
+
|
|
63
|
+
Returns:
|
|
64
|
+
An Encoding object if the node is valid, or a ValueSource containing
|
|
65
|
+
the invalid data if the root is not a MappingNode (preserving the invalid data
|
|
66
|
+
and its source location for validation).
|
|
67
|
+
|
|
68
|
+
Example:
|
|
69
|
+
from ruamel.yaml import YAML
|
|
70
|
+
yaml = YAML()
|
|
71
|
+
root = yaml.compose('''
|
|
72
|
+
contentType: application/xml
|
|
73
|
+
headers:
|
|
74
|
+
X-Rate-Limit:
|
|
75
|
+
schema:
|
|
76
|
+
type: integer
|
|
77
|
+
''')
|
|
78
|
+
encoding = build(root)
|
|
79
|
+
assert encoding.contentType.value == 'application/xml'
|
|
80
|
+
"""
|
|
81
|
+
return build_model(root, Encoding, context=context)
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
from dataclasses import dataclass, field
|
|
2
|
+
|
|
3
|
+
from ruamel import yaml
|
|
4
|
+
|
|
5
|
+
from ..context import Context
|
|
6
|
+
from ..fields import fixed_field
|
|
7
|
+
from ..sources import FieldSource, KeySource, ValueSource, YAMLInvalidValue, YAMLValue
|
|
8
|
+
from .builders import build_model
|
|
9
|
+
from .reference import Reference
|
|
10
|
+
from .reference import build as build_reference
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
__all__ = ["Example", "build", "build_example_or_reference"]
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@dataclass(frozen=True, slots=True)
|
|
17
|
+
class Example:
|
|
18
|
+
"""
|
|
19
|
+
Example Object representation for OpenAPI 3.0.
|
|
20
|
+
|
|
21
|
+
Attributes:
|
|
22
|
+
root_node: The top-level node representing the entire Example object in the original source file
|
|
23
|
+
summary: A short description of the example.
|
|
24
|
+
description: A long description for the example. CommonMark syntax MAY be used for rich text representation.
|
|
25
|
+
value: Embedded literal example. The value field and externalValue field are mutually exclusive.
|
|
26
|
+
external_value: A URL that points to the literal example. This provides the capability to reference
|
|
27
|
+
examples that cannot be inlined. The value field and externalValue field are mutually exclusive.
|
|
28
|
+
extensions: Specification extensions (x-* fields)
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
root_node: yaml.Node
|
|
32
|
+
summary: FieldSource[str] | None = fixed_field()
|
|
33
|
+
description: FieldSource[str] | None = fixed_field()
|
|
34
|
+
value: FieldSource[YAMLValue] | None = fixed_field()
|
|
35
|
+
external_value: FieldSource[str] | None = fixed_field(metadata={"yaml_name": "externalValue"})
|
|
36
|
+
extensions: dict[KeySource[str], ValueSource[YAMLValue]] = field(default_factory=dict)
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def build(
|
|
40
|
+
root: yaml.Node, context: Context | None = None
|
|
41
|
+
) -> Example | ValueSource[YAMLInvalidValue]:
|
|
42
|
+
"""
|
|
43
|
+
Build an Example object from a YAML node.
|
|
44
|
+
|
|
45
|
+
Preserves all source data as-is, regardless of type. This is a low-level/plumbing
|
|
46
|
+
model that provides complete source fidelity for inspection and validation.
|
|
47
|
+
|
|
48
|
+
Args:
|
|
49
|
+
root: The YAML node to parse (should be a MappingNode)
|
|
50
|
+
context: Optional parsing context. If None, a default context will be created.
|
|
51
|
+
|
|
52
|
+
Returns:
|
|
53
|
+
An Example object if the node is valid, or a ValueSource containing
|
|
54
|
+
the invalid data if the root is not a MappingNode (preserving the invalid data
|
|
55
|
+
and its source location for validation).
|
|
56
|
+
|
|
57
|
+
Example:
|
|
58
|
+
from ruamel.yaml import YAML
|
|
59
|
+
yaml = YAML()
|
|
60
|
+
root = yaml.compose("summary: A user example\\nvalue:\\n id: 1\\n name: John")
|
|
61
|
+
example = build(root)
|
|
62
|
+
assert example.summary.value == 'A user example'
|
|
63
|
+
"""
|
|
64
|
+
return build_model(root, Example, context=context)
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def build_example_or_reference(
|
|
68
|
+
node: yaml.Node, context: Context
|
|
69
|
+
) -> Example | Reference | ValueSource[YAMLInvalidValue]:
|
|
70
|
+
"""
|
|
71
|
+
Build either an Example or Reference from a YAML node.
|
|
72
|
+
|
|
73
|
+
This helper handles the polymorphic nature of OpenAPI where many fields
|
|
74
|
+
can contain either an Example object or a Reference object ($ref).
|
|
75
|
+
|
|
76
|
+
Args:
|
|
77
|
+
node: The YAML node to parse
|
|
78
|
+
context: Parsing context
|
|
79
|
+
|
|
80
|
+
Returns:
|
|
81
|
+
An Example, Reference, or ValueSource if the node is invalid
|
|
82
|
+
"""
|
|
83
|
+
# Check if it's a reference (has $ref key)
|
|
84
|
+
if isinstance(node, yaml.MappingNode):
|
|
85
|
+
for key_node, _ in node.value:
|
|
86
|
+
key = context.yaml_constructor.construct_yaml_str(key_node)
|
|
87
|
+
if key == "$ref":
|
|
88
|
+
return build_reference(node, context)
|
|
89
|
+
|
|
90
|
+
# Otherwise, try to build as Example
|
|
91
|
+
return build(node, context)
|
|
@@ -2,16 +2,10 @@ from dataclasses import dataclass, field
|
|
|
2
2
|
|
|
3
3
|
from ruamel import yaml
|
|
4
4
|
|
|
5
|
-
from
|
|
6
|
-
from
|
|
7
|
-
from
|
|
8
|
-
from
|
|
9
|
-
FieldSource,
|
|
10
|
-
KeySource,
|
|
11
|
-
ValueSource,
|
|
12
|
-
YAMLInvalidValue,
|
|
13
|
-
YAMLValue,
|
|
14
|
-
)
|
|
5
|
+
from ..context import Context
|
|
6
|
+
from ..fields import fixed_field
|
|
7
|
+
from ..sources import FieldSource, KeySource, ValueSource, YAMLInvalidValue, YAMLValue
|
|
8
|
+
from .builders import build_model
|
|
15
9
|
|
|
16
10
|
|
|
17
11
|
__all__ = ["ExternalDocumentation", "build"]
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
from dataclasses import dataclass, field
|
|
2
|
+
from typing import TYPE_CHECKING
|
|
3
|
+
|
|
4
|
+
from ruamel import yaml
|
|
5
|
+
|
|
6
|
+
from ..context import Context
|
|
7
|
+
from ..fields import fixed_field
|
|
8
|
+
from ..sources import FieldSource, KeySource, ValueSource, YAMLInvalidValue, YAMLValue
|
|
9
|
+
from .builders import build_model
|
|
10
|
+
from .example import Example
|
|
11
|
+
from .reference import Reference
|
|
12
|
+
from .reference import build as build_reference
|
|
13
|
+
from .schema import Schema
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
if TYPE_CHECKING:
|
|
17
|
+
from .media_type import MediaType
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
__all__ = ["Header", "build", "build_header_or_reference"]
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
@dataclass(frozen=True, slots=True)
|
|
24
|
+
class Header:
|
|
25
|
+
"""
|
|
26
|
+
Header Object representation for OpenAPI 3.0.
|
|
27
|
+
|
|
28
|
+
The Header Object follows the structure of the Parameter Object, including determining its
|
|
29
|
+
serialization strategy based on whether schema or content is present, with the following changes:
|
|
30
|
+
- name MUST NOT be specified, it is given in the corresponding headers map.
|
|
31
|
+
- in MUST NOT be specified, it is implicitly in header.
|
|
32
|
+
- All traits that are affected by the location MUST be applicable to a location of header
|
|
33
|
+
(for example, style). This means that allowEmptyValue and allowReserved MUST NOT be used,
|
|
34
|
+
and style, if used, MUST be limited to "simple".
|
|
35
|
+
|
|
36
|
+
Attributes:
|
|
37
|
+
root_node: The top-level node representing the entire Header object in the original source file
|
|
38
|
+
description: A brief description of the header. CommonMark syntax MAY be used for rich text representation.
|
|
39
|
+
required: Determines whether this header is mandatory. Default value is false.
|
|
40
|
+
deprecated: Specifies that a header is deprecated and SHOULD be transitioned out of usage. Default value is false.
|
|
41
|
+
style: Describes how the header value will be serialized depending on the type of the header value.
|
|
42
|
+
If used, MUST be limited to "simple".
|
|
43
|
+
explode: When this is true, header values of type array or object generate separate parameters for each value of the array or key-value pair of the map. Default value is false.
|
|
44
|
+
schema: The schema defining the type used for the header.
|
|
45
|
+
example: Example of the header's potential value. The example SHOULD match the specified schema and encoding properties if present.
|
|
46
|
+
examples: Examples of the header's potential value. Each example SHOULD contain a value in the correct format as specified in the header encoding.
|
|
47
|
+
content: A map containing the representations for the header. The key is the media type and the value describes it.
|
|
48
|
+
extensions: Specification extensions (x-* fields)
|
|
49
|
+
"""
|
|
50
|
+
|
|
51
|
+
root_node: yaml.Node
|
|
52
|
+
description: FieldSource[str] | None = fixed_field()
|
|
53
|
+
required: FieldSource[bool] | None = fixed_field()
|
|
54
|
+
deprecated: FieldSource[bool] | None = fixed_field()
|
|
55
|
+
style: FieldSource[str] | None = fixed_field()
|
|
56
|
+
explode: FieldSource[bool] | None = fixed_field()
|
|
57
|
+
schema: FieldSource["Schema | Reference"] | None = fixed_field()
|
|
58
|
+
example: FieldSource[YAMLValue] | None = fixed_field()
|
|
59
|
+
examples: FieldSource[dict[KeySource[str], "Example | Reference"]] | None = fixed_field()
|
|
60
|
+
content: FieldSource[dict[KeySource[str], "MediaType"]] | None = fixed_field()
|
|
61
|
+
extensions: dict[KeySource[str], ValueSource[YAMLValue]] = field(default_factory=dict)
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def build(
|
|
65
|
+
root: yaml.Node, context: Context | None = None
|
|
66
|
+
) -> Header | ValueSource[YAMLInvalidValue]:
|
|
67
|
+
"""
|
|
68
|
+
Build a Header object from a YAML node.
|
|
69
|
+
|
|
70
|
+
Preserves all source data as-is, regardless of type. This is a low-level/plumbing
|
|
71
|
+
model that provides complete source fidelity for inspection and validation.
|
|
72
|
+
|
|
73
|
+
Args:
|
|
74
|
+
root: The YAML node to parse (should be a MappingNode)
|
|
75
|
+
context: Optional parsing context. If None, a default context will be created.
|
|
76
|
+
|
|
77
|
+
Returns:
|
|
78
|
+
A Header object if the node is valid, or a ValueSource containing
|
|
79
|
+
the invalid data if the root is not a MappingNode (preserving the invalid data
|
|
80
|
+
and its source location for validation).
|
|
81
|
+
|
|
82
|
+
Example:
|
|
83
|
+
from ruamel.yaml import YAML
|
|
84
|
+
yaml = YAML()
|
|
85
|
+
root = yaml.compose('''
|
|
86
|
+
description: The number of allowed requests in the current period
|
|
87
|
+
schema:
|
|
88
|
+
type: integer
|
|
89
|
+
''')
|
|
90
|
+
header = build(root)
|
|
91
|
+
assert header.description.value == 'The number of allowed requests in the current period'
|
|
92
|
+
"""
|
|
93
|
+
return build_model(root, Header, context=context)
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
def build_header_or_reference(
|
|
97
|
+
node: yaml.Node, context: Context
|
|
98
|
+
) -> Header | Reference | ValueSource[YAMLInvalidValue]:
|
|
99
|
+
"""
|
|
100
|
+
Build either a Header or Reference from a YAML node.
|
|
101
|
+
|
|
102
|
+
This helper handles the polymorphic nature of OpenAPI where many fields
|
|
103
|
+
can contain either a Header object or a Reference object ($ref).
|
|
104
|
+
|
|
105
|
+
Args:
|
|
106
|
+
node: The YAML node to parse
|
|
107
|
+
context: Parsing context
|
|
108
|
+
|
|
109
|
+
Returns:
|
|
110
|
+
A Header, Reference, or ValueSource if the node is invalid
|
|
111
|
+
"""
|
|
112
|
+
# Check if it's a reference (has $ref key)
|
|
113
|
+
if isinstance(node, yaml.MappingNode):
|
|
114
|
+
for key_node, _ in node.value:
|
|
115
|
+
key = context.yaml_constructor.construct_yaml_str(key_node)
|
|
116
|
+
if key == "$ref":
|
|
117
|
+
return build_reference(node, context)
|
|
118
|
+
|
|
119
|
+
# Otherwise, try to build as Header
|
|
120
|
+
return build(node, context)
|
|
@@ -2,20 +2,14 @@ from dataclasses import dataclass, field, replace
|
|
|
2
2
|
|
|
3
3
|
from ruamel import yaml
|
|
4
4
|
|
|
5
|
-
from
|
|
6
|
-
from
|
|
7
|
-
from
|
|
8
|
-
from
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
YAMLValue,
|
|
14
|
-
)
|
|
15
|
-
from jentic.apitools.openapi.datamodels.low.v30.contact import Contact
|
|
16
|
-
from jentic.apitools.openapi.datamodels.low.v30.contact import build as build_contact
|
|
17
|
-
from jentic.apitools.openapi.datamodels.low.v30.license import License
|
|
18
|
-
from jentic.apitools.openapi.datamodels.low.v30.license import build as build_license
|
|
5
|
+
from ..context import Context
|
|
6
|
+
from ..fields import fixed_field
|
|
7
|
+
from ..sources import FieldSource, KeySource, ValueSource, YAMLInvalidValue, YAMLValue
|
|
8
|
+
from .builders import build_model
|
|
9
|
+
from .contact import Contact
|
|
10
|
+
from .contact import build as build_contact
|
|
11
|
+
from .license import License
|
|
12
|
+
from .license import build as build_license
|
|
19
13
|
|
|
20
14
|
|
|
21
15
|
__all__ = ["Info", "build"]
|
|
@@ -85,18 +79,15 @@ def build(root: yaml.Node, context: Context | None = None) -> Info | ValueSource
|
|
|
85
79
|
assert info.version.value == '1.0.1'
|
|
86
80
|
assert info.contact.value.name.value == 'API Support'
|
|
87
81
|
"""
|
|
88
|
-
|
|
89
|
-
if context is None:
|
|
90
|
-
context = Context()
|
|
82
|
+
context = context or Context()
|
|
91
83
|
|
|
92
|
-
|
|
93
|
-
# Preserve invalid root data instead of returning None
|
|
94
|
-
value = context.yaml_constructor.construct_object(root, deep=True)
|
|
95
|
-
return ValueSource(value=value, value_node=root)
|
|
96
|
-
|
|
97
|
-
# Use build_model to handle most fields
|
|
84
|
+
# Use build_model for initial construction
|
|
98
85
|
info = build_model(root, Info, context=context)
|
|
99
86
|
|
|
87
|
+
# If build_model returned ValueSource (invalid node), return it immediately
|
|
88
|
+
if not isinstance(info, Info):
|
|
89
|
+
return info
|
|
90
|
+
|
|
100
91
|
# Manually handle nested objects (contact, license)
|
|
101
92
|
for key_node, value_node in root.value:
|
|
102
93
|
key = context.yaml_constructor.construct_yaml_str(key_node)
|
|
@@ -2,16 +2,10 @@ from dataclasses import dataclass, field
|
|
|
2
2
|
|
|
3
3
|
from ruamel import yaml
|
|
4
4
|
|
|
5
|
-
from
|
|
6
|
-
from
|
|
7
|
-
from
|
|
8
|
-
from
|
|
9
|
-
FieldSource,
|
|
10
|
-
KeySource,
|
|
11
|
-
ValueSource,
|
|
12
|
-
YAMLInvalidValue,
|
|
13
|
-
YAMLValue,
|
|
14
|
-
)
|
|
5
|
+
from ..context import Context
|
|
6
|
+
from ..fields import fixed_field
|
|
7
|
+
from ..sources import FieldSource, KeySource, ValueSource, YAMLInvalidValue, YAMLValue
|
|
8
|
+
from .builders import build_model
|
|
15
9
|
|
|
16
10
|
|
|
17
11
|
__all__ = ["License", "build"]
|