robotframework-openapitools 1.0.0b4__py3-none-any.whl → 1.0.0b5__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.
- OpenApiDriver/openapi_executors.py +7 -3
- OpenApiDriver/openapidriver.libspec +3 -3
- OpenApiLibCore/__init__.py +0 -0
- OpenApiLibCore/data_generation/__init__.py +0 -0
- OpenApiLibCore/data_generation/body_data_generation.py +4 -4
- OpenApiLibCore/data_generation/data_generation_core.py +18 -45
- OpenApiLibCore/data_invalidation.py +1 -5
- OpenApiLibCore/dto_base.py +31 -22
- OpenApiLibCore/dto_utils.py +31 -3
- OpenApiLibCore/localized_faker.py +0 -0
- OpenApiLibCore/models.py +26 -18
- OpenApiLibCore/openapi_libcore.libspec +26 -26
- OpenApiLibCore/openapi_libcore.py +35 -26
- OpenApiLibCore/parameter_utils.py +3 -3
- OpenApiLibCore/path_functions.py +5 -6
- OpenApiLibCore/path_invalidation.py +5 -7
- OpenApiLibCore/protocols.py +6 -0
- OpenApiLibCore/request_data.py +0 -0
- OpenApiLibCore/resource_relations.py +4 -2
- OpenApiLibCore/validation.py +4 -9
- OpenApiLibCore/value_utils.py +1 -1
- openapi_libgen/generator.py +2 -2
- openapi_libgen/parsing_utils.py +9 -5
- openapi_libgen/spec_parser.py +4 -4
- {robotframework_openapitools-1.0.0b4.dist-info → robotframework_openapitools-1.0.0b5.dist-info}/METADATA +1 -1
- robotframework_openapitools-1.0.0b5.dist-info/RECORD +40 -0
- robotframework_openapitools-1.0.0b4.dist-info/RECORD +0 -40
- {robotframework_openapitools-1.0.0b4.dist-info → robotframework_openapitools-1.0.0b5.dist-info}/LICENSE +0 -0
- {robotframework_openapitools-1.0.0b4.dist-info → robotframework_openapitools-1.0.0b5.dist-info}/WHEEL +0 -0
- {robotframework_openapitools-1.0.0b4.dist-info → robotframework_openapitools-1.0.0b5.dist-info}/entry_points.txt +0 -0
@@ -133,11 +133,15 @@ class OpenApiExecutors(OpenApiLibCore):
|
|
133
133
|
"""
|
134
134
|
valid_url: str = run_keyword("get_valid_url", path)
|
135
135
|
|
136
|
-
|
137
|
-
url
|
136
|
+
try:
|
137
|
+
url = run_keyword(
|
138
138
|
"get_invalidated_url", valid_url, path, expected_status_code
|
139
139
|
)
|
140
|
-
|
140
|
+
except Exception as exception:
|
141
|
+
message = getattr(exception, "message", "")
|
142
|
+
if not message.startswith("ValueError"):
|
143
|
+
raise exception # pragma: no cover
|
144
|
+
|
141
145
|
raise SkipExecution(
|
142
146
|
f"Path {path} does not contain resource references that "
|
143
147
|
f"can be invalidated."
|
@@ -1,6 +1,6 @@
|
|
1
1
|
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
-
<keywordspec name="OpenApiDriver" type="LIBRARY" format="HTML" scope="SUITE" generated="2025-
|
3
|
-
<version>1.0.
|
2
|
+
<keywordspec name="OpenApiDriver" type="LIBRARY" format="HTML" scope="SUITE" generated="2025-06-09T18:38:35+00:00" specversion="6" source="/workspaces/robotframework-openapitools/src/OpenApiDriver/openapidriver.py" lineno="358">
|
3
|
+
<version>1.0.0b5</version>
|
4
4
|
<doc><p>Visit the <a href="https://github.com/MarketSquare/robotframework-openapidriver">library page</a> for an introduction and examples.</p></doc>
|
5
5
|
<tags>
|
6
6
|
</tags>
|
@@ -247,7 +247,7 @@
|
|
247
247
|
</init>
|
248
248
|
</inits>
|
249
249
|
<keywords>
|
250
|
-
<kw name="Test Endpoint" source="/workspaces/robotframework-openapitools/src/OpenApiDriver/openapi_executors.py" lineno="
|
250
|
+
<kw name="Test Endpoint" source="/workspaces/robotframework-openapitools/src/OpenApiDriver/openapi_executors.py" lineno="166">
|
251
251
|
<arguments repr="path: str, method: str, status_code: int">
|
252
252
|
<arg kind="POSITIONAL_OR_NAMED" required="true" repr="path: str">
|
253
253
|
<name>path</name>
|
OpenApiLibCore/__init__.py
CHANGED
File without changes
|
File without changes
|
@@ -8,7 +8,7 @@ from typing import Any
|
|
8
8
|
|
9
9
|
from robot.api import logger
|
10
10
|
|
11
|
-
import OpenApiLibCore.path_functions as
|
11
|
+
import OpenApiLibCore.path_functions as _path_functions
|
12
12
|
from OpenApiLibCore.annotations import JSON
|
13
13
|
from OpenApiLibCore.dto_base import (
|
14
14
|
Dto,
|
@@ -72,7 +72,7 @@ def get_dict_data_for_dto_class(
|
|
72
72
|
property_names = get_property_names_to_process(schema=schema, dto_class=dto_class)
|
73
73
|
|
74
74
|
for property_name in property_names:
|
75
|
-
property_schema = schema.properties.root[property_name]
|
75
|
+
property_schema = schema.properties.root[property_name] # type: ignore[union-attr]
|
76
76
|
if property_schema.readOnly:
|
77
77
|
continue
|
78
78
|
|
@@ -178,7 +178,7 @@ def get_property_names_to_process(
|
|
178
178
|
) -> list[str]:
|
179
179
|
property_names = []
|
180
180
|
|
181
|
-
for property_name in schema.properties.root:
|
181
|
+
for property_name in schema.properties.root: # type: ignore[union-attr]
|
182
182
|
# register the oas_name
|
183
183
|
_ = get_safe_name_for_oas_name(property_name)
|
184
184
|
if constrained_values := get_constrained_values(
|
@@ -243,7 +243,7 @@ def get_dependent_id(
|
|
243
243
|
except ValueError:
|
244
244
|
return None
|
245
245
|
|
246
|
-
valid_id =
|
246
|
+
valid_id = _path_functions.get_valid_id_for_path(
|
247
247
|
path=id_get_path, get_id_property_name=get_id_property_name
|
248
248
|
)
|
249
249
|
logger.debug(f"get_dependent_id for {id_get_path} returned {valid_id}")
|
@@ -3,14 +3,13 @@ Module holding the main functions related to data generation
|
|
3
3
|
for the requests made as part of keyword exection.
|
4
4
|
"""
|
5
5
|
|
6
|
-
import re
|
7
6
|
from dataclasses import Field, field, make_dataclass
|
8
7
|
from random import choice
|
9
8
|
from typing import Any, cast
|
10
9
|
|
11
10
|
from robot.api import logger
|
12
11
|
|
13
|
-
import OpenApiLibCore.path_functions as
|
12
|
+
import OpenApiLibCore.path_functions as _path_functions
|
14
13
|
from OpenApiLibCore.annotations import JSON
|
15
14
|
from OpenApiLibCore.dto_base import (
|
16
15
|
Dto,
|
@@ -23,7 +22,6 @@ from OpenApiLibCore.models import (
|
|
23
22
|
OpenApiObject,
|
24
23
|
OperationObject,
|
25
24
|
ParameterObject,
|
26
|
-
RequestBodyObject,
|
27
25
|
UnionTypeSchema,
|
28
26
|
)
|
29
27
|
from OpenApiLibCore.parameter_utils import get_safe_name_for_oas_name
|
@@ -47,11 +45,13 @@ def get_request_data(
|
|
47
45
|
dto_cls_name = get_dto_cls_name(path=path, method=method)
|
48
46
|
# The path can contain already resolved Ids that have to be matched
|
49
47
|
# against the parametrized paths in the paths section.
|
50
|
-
spec_path =
|
48
|
+
spec_path = _path_functions.get_parametrized_path(
|
49
|
+
path=path, openapi_spec=openapi_spec
|
50
|
+
)
|
51
51
|
dto_class = get_dto_class(path=spec_path, method=method)
|
52
52
|
try:
|
53
53
|
path_item = openapi_spec.paths[spec_path]
|
54
|
-
operation_spec = getattr(path_item, method)
|
54
|
+
operation_spec: OperationObject | None = getattr(path_item, method)
|
55
55
|
if operation_spec is None:
|
56
56
|
raise AttributeError
|
57
57
|
except AttributeError:
|
@@ -77,38 +77,30 @@ def get_request_data(
|
|
77
77
|
has_body=False,
|
78
78
|
)
|
79
79
|
|
80
|
-
|
81
|
-
|
82
|
-
body_schema = operation_spec.requestBody
|
83
|
-
media_type_dict = body_schema.content
|
84
|
-
supported_types = [v for k, v in media_type_dict.items() if "json" in k]
|
85
|
-
supported_schemas = [t.schema_ for t in supported_types if t.schema_ is not None]
|
80
|
+
body_schema = operation_spec.requestBody.schema_
|
86
81
|
|
87
|
-
if not
|
88
|
-
raise ValueError(
|
89
|
-
|
90
|
-
if len(supported_schemas) > 1:
|
91
|
-
logger.warn(
|
92
|
-
f"Multiple JSON media types defined for requestBody, using the first candidate {media_type_dict}"
|
82
|
+
if not body_schema:
|
83
|
+
raise ValueError(
|
84
|
+
f"No supported content schema found: {operation_spec.requestBody.content}"
|
93
85
|
)
|
94
86
|
|
95
|
-
|
87
|
+
headers.update({"content-type": operation_spec.requestBody.mime_type})
|
96
88
|
|
97
|
-
if isinstance(
|
98
|
-
resolved_schemas =
|
99
|
-
|
89
|
+
if isinstance(body_schema, UnionTypeSchema):
|
90
|
+
resolved_schemas = body_schema.resolved_schemas
|
91
|
+
body_schema = choice(resolved_schemas)
|
100
92
|
|
101
|
-
if not isinstance(
|
102
|
-
raise ValueError(f"Selected schema is not an object schema: {
|
93
|
+
if not isinstance(body_schema, ObjectSchema):
|
94
|
+
raise ValueError(f"Selected schema is not an object schema: {body_schema}")
|
103
95
|
|
104
96
|
dto_data = _get_json_data_for_dto_class(
|
105
|
-
schema=
|
97
|
+
schema=body_schema,
|
106
98
|
dto_class=dto_class,
|
107
99
|
get_id_property_name=get_id_property_name,
|
108
100
|
operation_id=operation_spec.operationId,
|
109
101
|
)
|
110
102
|
dto_instance = _get_dto_instance_from_dto_data(
|
111
|
-
object_schema=
|
103
|
+
object_schema=body_schema,
|
112
104
|
dto_class=dto_class,
|
113
105
|
dto_data=dto_data,
|
114
106
|
method_spec=operation_spec,
|
@@ -116,7 +108,7 @@ def get_request_data(
|
|
116
108
|
)
|
117
109
|
return RequestData(
|
118
110
|
dto=dto_instance,
|
119
|
-
body_schema=
|
111
|
+
body_schema=body_schema,
|
120
112
|
parameters=parameters,
|
121
113
|
params=params,
|
122
114
|
headers=headers,
|
@@ -198,25 +190,6 @@ def get_dto_cls_name(path: str, method: str) -> str:
|
|
198
190
|
return result
|
199
191
|
|
200
192
|
|
201
|
-
def get_content_type(body_spec: RequestBodyObject) -> str:
|
202
|
-
"""Get and validate the first supported content type from the requested body spec
|
203
|
-
|
204
|
-
Should be application/json like content type,
|
205
|
-
e.g "application/json;charset=utf-8" or "application/merge-patch+json"
|
206
|
-
"""
|
207
|
-
content_types: list[str] = list(body_spec.content.keys())
|
208
|
-
json_regex = r"application/([a-z\-]+\+)?json(;\s?charset=(.+))?"
|
209
|
-
for content_type in content_types:
|
210
|
-
if re.search(json_regex, content_type):
|
211
|
-
return content_type
|
212
|
-
|
213
|
-
# At present no supported for other types.
|
214
|
-
raise NotImplementedError(
|
215
|
-
f"Only content types like 'application/json' are supported. "
|
216
|
-
f"Content types definded in the spec are '{content_types}'."
|
217
|
-
)
|
218
|
-
|
219
|
-
|
220
193
|
def get_request_parameters(
|
221
194
|
dto_class: Dto | type[Dto], method_spec: OperationObject
|
222
195
|
) -> tuple[list[ParameterObject], dict[str, Any], dict[str, str]]:
|
@@ -16,7 +16,6 @@ from OpenApiLibCore.dto_base import (
|
|
16
16
|
NOT_SET,
|
17
17
|
Dto,
|
18
18
|
IdReference,
|
19
|
-
PathPropertiesConstraint,
|
20
19
|
PropertyValueConstraint,
|
21
20
|
UniquePropertyValueConstraint,
|
22
21
|
)
|
@@ -35,10 +34,7 @@ def get_invalid_body_data(
|
|
35
34
|
invalid_property_default_response: int,
|
36
35
|
) -> dict[str, Any]:
|
37
36
|
method = method.lower()
|
38
|
-
data_relations = request_data.dto.
|
39
|
-
data_relations = [
|
40
|
-
r for r in data_relations if not isinstance(r, PathPropertiesConstraint)
|
41
|
-
]
|
37
|
+
data_relations = request_data.dto.get_body_relations_for_error_code(status_code)
|
42
38
|
if not data_relations:
|
43
39
|
if request_data.body_schema is None:
|
44
40
|
raise ValueError(
|
OpenApiLibCore/dto_base.py
CHANGED
@@ -83,17 +83,17 @@ class Dto(ABC):
|
|
83
83
|
"""Base class for the Dto class."""
|
84
84
|
|
85
85
|
@staticmethod
|
86
|
-
def
|
86
|
+
def get_path_relations() -> list[PathPropertiesConstraint]:
|
87
87
|
"""Return the list of Relations for the header and query parameters."""
|
88
88
|
return []
|
89
89
|
|
90
|
-
def
|
90
|
+
def get_path_relations_for_error_code(
|
91
91
|
self, error_code: int
|
92
|
-
) -> list[
|
92
|
+
) -> list[PathPropertiesConstraint]:
|
93
93
|
"""Return the list of Relations associated with the given error_code."""
|
94
|
-
relations: list[
|
94
|
+
relations: list[PathPropertiesConstraint] = [
|
95
95
|
r
|
96
|
-
for r in self.
|
96
|
+
for r in self.get_path_relations()
|
97
97
|
if r.error_code == error_code
|
98
98
|
or (
|
99
99
|
getattr(r, "invalid_value_error_code", None) == error_code
|
@@ -103,15 +103,17 @@ class Dto(ABC):
|
|
103
103
|
return relations
|
104
104
|
|
105
105
|
@staticmethod
|
106
|
-
def
|
107
|
-
"""Return the list of Relations for the
|
106
|
+
def get_parameter_relations() -> list[ResourceRelation]:
|
107
|
+
"""Return the list of Relations for the header and query parameters."""
|
108
108
|
return []
|
109
109
|
|
110
|
-
def
|
110
|
+
def get_parameter_relations_for_error_code(
|
111
|
+
self, error_code: int
|
112
|
+
) -> list[ResourceRelation]:
|
111
113
|
"""Return the list of Relations associated with the given error_code."""
|
112
114
|
relations: list[ResourceRelation] = [
|
113
115
|
r
|
114
|
-
for r in self.
|
116
|
+
for r in self.get_parameter_relations()
|
115
117
|
if r.error_code == error_code
|
116
118
|
or (
|
117
119
|
getattr(r, "invalid_value_error_code", None) == error_code
|
@@ -120,6 +122,11 @@ class Dto(ABC):
|
|
120
122
|
]
|
121
123
|
return relations
|
122
124
|
|
125
|
+
@staticmethod
|
126
|
+
def get_relations() -> list[ResourceRelation]:
|
127
|
+
"""Return the list of Relations for the (json) body."""
|
128
|
+
return []
|
129
|
+
|
123
130
|
def get_body_relations_for_error_code(
|
124
131
|
self, error_code: int
|
125
132
|
) -> list[ResourceRelation]:
|
@@ -127,8 +134,16 @@ class Dto(ABC):
|
|
127
134
|
Return the list of Relations associated with the given error_code that are
|
128
135
|
applicable to the body / payload of the request.
|
129
136
|
"""
|
130
|
-
|
131
|
-
|
137
|
+
relations: list[ResourceRelation] = [
|
138
|
+
r
|
139
|
+
for r in self.get_relations()
|
140
|
+
if r.error_code == error_code
|
141
|
+
or (
|
142
|
+
getattr(r, "invalid_value_error_code", None) == error_code
|
143
|
+
and getattr(r, "invalid_value", None) != NOT_SET
|
144
|
+
)
|
145
|
+
]
|
146
|
+
return relations
|
132
147
|
|
133
148
|
def get_invalidated_data(
|
134
149
|
self,
|
@@ -139,17 +154,11 @@ class Dto(ABC):
|
|
139
154
|
"""Return a data set with one of the properties set to an invalid value or type."""
|
140
155
|
properties: dict[str, Any] = self.as_dict()
|
141
156
|
|
142
|
-
|
143
|
-
|
144
|
-
relations = self.get_relations_for_error_code(error_code=status_code)
|
145
|
-
# filter PathProperyConstraints since in that case no data can be invalidated
|
146
|
-
relations = [
|
147
|
-
r for r in relations if not isinstance(r, PathPropertiesConstraint)
|
148
|
-
]
|
157
|
+
relations = self.get_body_relations_for_error_code(error_code=status_code)
|
149
158
|
property_names = [r.property_name for r in relations]
|
150
159
|
if status_code == invalid_property_default_code:
|
151
160
|
# add all properties defined in the schema, including optional properties
|
152
|
-
property_names.extend((schema.properties.root.keys()))
|
161
|
+
property_names.extend((schema.properties.root.keys())) # type: ignore[union-attr]
|
153
162
|
if not property_names:
|
154
163
|
raise ValueError(
|
155
164
|
f"No property can be invalidated to cause status_code {status_code}"
|
@@ -167,8 +176,8 @@ class Dto(ABC):
|
|
167
176
|
if id_dependencies:
|
168
177
|
invalid_id = uuid4().hex
|
169
178
|
logger.debug(
|
170
|
-
f"Breaking IdDependency for status_code {status_code}:
|
171
|
-
f"{
|
179
|
+
f"Breaking IdDependency for status_code {status_code}: setting "
|
180
|
+
f"{property_name} to {invalid_id}"
|
172
181
|
)
|
173
182
|
properties[property_name] = invalid_id
|
174
183
|
return properties
|
@@ -191,7 +200,7 @@ class Dto(ABC):
|
|
191
200
|
)
|
192
201
|
return properties
|
193
202
|
|
194
|
-
value_schema = schema.properties.root[property_name]
|
203
|
+
value_schema = schema.properties.root[property_name] # type: ignore[union-attr]
|
195
204
|
if isinstance(value_schema, UnionTypeSchema):
|
196
205
|
# Filter "type": "null" from the possible types since this indicates an
|
197
206
|
# optional / nullable property that can only be invalidated by sending
|
OpenApiLibCore/dto_utils.py
CHANGED
@@ -7,7 +7,11 @@ from typing import Any, Callable, Type, overload
|
|
7
7
|
from robot.api import logger
|
8
8
|
|
9
9
|
from OpenApiLibCore.dto_base import Dto
|
10
|
-
from OpenApiLibCore.protocols import
|
10
|
+
from OpenApiLibCore.protocols import (
|
11
|
+
GetDtoClassType,
|
12
|
+
GetIdPropertyNameType,
|
13
|
+
GetPathDtoClassType,
|
14
|
+
)
|
11
15
|
|
12
16
|
|
13
17
|
@dataclass
|
@@ -49,6 +53,30 @@ class GetDtoClass:
|
|
49
53
|
return DefaultDto
|
50
54
|
|
51
55
|
|
56
|
+
def get_path_dto_class(mappings_module_name: str) -> GetPathDtoClassType:
|
57
|
+
return GetPathDtoClass(mappings_module_name=mappings_module_name)
|
58
|
+
|
59
|
+
|
60
|
+
class GetPathDtoClass:
|
61
|
+
"""Callable class to return Dtos from user-implemented mappings file."""
|
62
|
+
|
63
|
+
def __init__(self, mappings_module_name: str) -> None:
|
64
|
+
try:
|
65
|
+
mappings_module = import_module(mappings_module_name)
|
66
|
+
self.dto_mapping: dict[str, Type[Dto]] = mappings_module.PATH_MAPPING
|
67
|
+
except (ImportError, AttributeError, ValueError) as exception:
|
68
|
+
if mappings_module_name != "no mapping":
|
69
|
+
logger.error(f"PATH_MAPPING was not imported: {exception}")
|
70
|
+
self.dto_mapping = {}
|
71
|
+
|
72
|
+
def __call__(self, path: str) -> Type[Dto]:
|
73
|
+
try:
|
74
|
+
return self.dto_mapping[path]
|
75
|
+
except KeyError:
|
76
|
+
logger.debug(f"No Dto mapping for {path}.")
|
77
|
+
return DefaultDto
|
78
|
+
|
79
|
+
|
52
80
|
def get_id_property_name(mappings_module_name: str) -> GetIdPropertyNameType:
|
53
81
|
return GetIdPropertyName(mappings_module_name=mappings_module_name)
|
54
82
|
|
@@ -86,11 +114,11 @@ class GetIdPropertyName:
|
|
86
114
|
|
87
115
|
|
88
116
|
@overload
|
89
|
-
def dummy_transformer(valid_id: str) -> str: ...
|
117
|
+
def dummy_transformer(valid_id: str) -> str: ... # pragma: no cover
|
90
118
|
|
91
119
|
|
92
120
|
@overload
|
93
|
-
def dummy_transformer(valid_id: int) -> int: ...
|
121
|
+
def dummy_transformer(valid_id: int) -> int: ... # pragma: no cover
|
94
122
|
|
95
123
|
|
96
124
|
def dummy_transformer(valid_id: Any) -> Any:
|
File without changes
|
OpenApiLibCore/models.py
CHANGED
@@ -234,7 +234,7 @@ class IntegerSchema(SchemaBase[int], frozen=True):
|
|
234
234
|
|
235
235
|
return randint(self._min_value, self._max_value)
|
236
236
|
|
237
|
-
def get_values_out_of_bounds(self, current_value: int) -> list[int]:
|
237
|
+
def get_values_out_of_bounds(self, current_value: int) -> list[int]: # pylint: disable=unused-argument
|
238
238
|
invalid_values: list[int] = []
|
239
239
|
|
240
240
|
if self._min_value > self._min_int:
|
@@ -333,7 +333,7 @@ class NumberSchema(SchemaBase[float], frozen=True):
|
|
333
333
|
|
334
334
|
return uniform(self._min_value, self._max_value)
|
335
335
|
|
336
|
-
def get_values_out_of_bounds(self, current_value: float) -> list[float]:
|
336
|
+
def get_values_out_of_bounds(self, current_value: float) -> list[float]: # pylint: disable=unused-argument
|
337
337
|
invalid_values: list[float] = []
|
338
338
|
|
339
339
|
if self._min_value > self._min_float:
|
@@ -643,21 +643,33 @@ class RequestBodyObject(BaseModel):
|
|
643
643
|
required: bool = False
|
644
644
|
description: str = ""
|
645
645
|
|
646
|
-
@
|
646
|
+
@cached_property
|
647
647
|
def schema_(self) -> SchemaObjectTypes | None:
|
648
|
-
|
649
|
-
|
650
|
-
|
651
|
-
|
652
|
-
|
653
|
-
|
654
|
-
|
655
|
-
|
648
|
+
if not self.mime_type:
|
649
|
+
return None
|
650
|
+
|
651
|
+
if len(self._json_schemas) > 1:
|
652
|
+
logger.info(
|
653
|
+
f"Multiple JSON media types defined for requestBody, "
|
654
|
+
f"using the first candidate from {self.content}"
|
655
|
+
)
|
656
|
+
return self._json_schemas[self.mime_type]
|
657
|
+
|
658
|
+
@cached_property
|
659
|
+
def mime_type(self) -> str | None:
|
660
|
+
if not self._json_schemas:
|
656
661
|
return None
|
657
662
|
|
658
|
-
|
659
|
-
|
660
|
-
|
663
|
+
return next(iter(self._json_schemas))
|
664
|
+
|
665
|
+
@cached_property
|
666
|
+
def _json_schemas(self) -> dict[str, SchemaObjectTypes]:
|
667
|
+
json_schemas = {
|
668
|
+
mime_type: media_type.schema_
|
669
|
+
for mime_type, media_type in self.content.items()
|
670
|
+
if "json" in mime_type and media_type.schema_ is not None
|
671
|
+
}
|
672
|
+
return json_schemas
|
661
673
|
|
662
674
|
|
663
675
|
class HeaderObject(BaseModel): ...
|
@@ -673,10 +685,6 @@ class ResponseObject(BaseModel):
|
|
673
685
|
links: dict[str, LinkObject] = {}
|
674
686
|
|
675
687
|
|
676
|
-
# class ComponentsObject(BaseModel):
|
677
|
-
# schemas: dict[str, SchemaObjectTypes]
|
678
|
-
|
679
|
-
|
680
688
|
class OperationObject(BaseModel):
|
681
689
|
operationId: str | None = None
|
682
690
|
summary: str = ""
|