schemathesis 3.39.16__py3-none-any.whl → 4.0.0__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 (255) hide show
  1. schemathesis/__init__.py +41 -79
  2. schemathesis/auths.py +111 -122
  3. schemathesis/checks.py +169 -60
  4. schemathesis/cli/__init__.py +15 -2117
  5. schemathesis/cli/commands/__init__.py +85 -0
  6. schemathesis/cli/commands/data.py +10 -0
  7. schemathesis/cli/commands/run/__init__.py +590 -0
  8. schemathesis/cli/commands/run/context.py +204 -0
  9. schemathesis/cli/commands/run/events.py +60 -0
  10. schemathesis/cli/commands/run/executor.py +157 -0
  11. schemathesis/cli/commands/run/filters.py +53 -0
  12. schemathesis/cli/commands/run/handlers/__init__.py +46 -0
  13. schemathesis/cli/commands/run/handlers/base.py +18 -0
  14. schemathesis/cli/commands/run/handlers/cassettes.py +474 -0
  15. schemathesis/cli/commands/run/handlers/junitxml.py +55 -0
  16. schemathesis/cli/commands/run/handlers/output.py +1628 -0
  17. schemathesis/cli/commands/run/loaders.py +114 -0
  18. schemathesis/cli/commands/run/validation.py +246 -0
  19. schemathesis/cli/constants.py +5 -58
  20. schemathesis/cli/core.py +19 -0
  21. schemathesis/cli/ext/fs.py +16 -0
  22. schemathesis/cli/ext/groups.py +84 -0
  23. schemathesis/cli/{options.py → ext/options.py} +36 -34
  24. schemathesis/config/__init__.py +189 -0
  25. schemathesis/config/_auth.py +51 -0
  26. schemathesis/config/_checks.py +268 -0
  27. schemathesis/config/_diff_base.py +99 -0
  28. schemathesis/config/_env.py +21 -0
  29. schemathesis/config/_error.py +156 -0
  30. schemathesis/config/_generation.py +149 -0
  31. schemathesis/config/_health_check.py +24 -0
  32. schemathesis/config/_operations.py +327 -0
  33. schemathesis/config/_output.py +171 -0
  34. schemathesis/config/_parameters.py +19 -0
  35. schemathesis/config/_phases.py +187 -0
  36. schemathesis/config/_projects.py +527 -0
  37. schemathesis/config/_rate_limit.py +17 -0
  38. schemathesis/config/_report.py +120 -0
  39. schemathesis/config/_validator.py +9 -0
  40. schemathesis/config/_warnings.py +25 -0
  41. schemathesis/config/schema.json +885 -0
  42. schemathesis/core/__init__.py +67 -0
  43. schemathesis/core/compat.py +32 -0
  44. schemathesis/core/control.py +2 -0
  45. schemathesis/core/curl.py +58 -0
  46. schemathesis/core/deserialization.py +65 -0
  47. schemathesis/core/errors.py +459 -0
  48. schemathesis/core/failures.py +315 -0
  49. schemathesis/core/fs.py +19 -0
  50. schemathesis/core/hooks.py +20 -0
  51. schemathesis/core/loaders.py +104 -0
  52. schemathesis/core/marks.py +66 -0
  53. schemathesis/{transports/content_types.py → core/media_types.py} +14 -12
  54. schemathesis/core/output/__init__.py +46 -0
  55. schemathesis/core/output/sanitization.py +54 -0
  56. schemathesis/{throttling.py → core/rate_limit.py} +16 -17
  57. schemathesis/core/registries.py +31 -0
  58. schemathesis/core/transforms.py +113 -0
  59. schemathesis/core/transport.py +223 -0
  60. schemathesis/core/validation.py +54 -0
  61. schemathesis/core/version.py +7 -0
  62. schemathesis/engine/__init__.py +28 -0
  63. schemathesis/engine/context.py +118 -0
  64. schemathesis/engine/control.py +36 -0
  65. schemathesis/engine/core.py +169 -0
  66. schemathesis/engine/errors.py +464 -0
  67. schemathesis/engine/events.py +258 -0
  68. schemathesis/engine/phases/__init__.py +88 -0
  69. schemathesis/{runner → engine/phases}/probes.py +52 -68
  70. schemathesis/engine/phases/stateful/__init__.py +68 -0
  71. schemathesis/engine/phases/stateful/_executor.py +356 -0
  72. schemathesis/engine/phases/stateful/context.py +85 -0
  73. schemathesis/engine/phases/unit/__init__.py +212 -0
  74. schemathesis/engine/phases/unit/_executor.py +416 -0
  75. schemathesis/engine/phases/unit/_pool.py +82 -0
  76. schemathesis/engine/recorder.py +247 -0
  77. schemathesis/errors.py +43 -0
  78. schemathesis/filters.py +17 -98
  79. schemathesis/generation/__init__.py +5 -33
  80. schemathesis/generation/case.py +317 -0
  81. schemathesis/generation/coverage.py +282 -175
  82. schemathesis/generation/hypothesis/__init__.py +36 -0
  83. schemathesis/generation/hypothesis/builder.py +800 -0
  84. schemathesis/generation/{_hypothesis.py → hypothesis/examples.py} +2 -11
  85. schemathesis/generation/hypothesis/given.py +66 -0
  86. schemathesis/generation/hypothesis/reporting.py +14 -0
  87. schemathesis/generation/hypothesis/strategies.py +16 -0
  88. schemathesis/generation/meta.py +115 -0
  89. schemathesis/generation/metrics.py +93 -0
  90. schemathesis/generation/modes.py +20 -0
  91. schemathesis/generation/overrides.py +116 -0
  92. schemathesis/generation/stateful/__init__.py +37 -0
  93. schemathesis/generation/stateful/state_machine.py +278 -0
  94. schemathesis/graphql/__init__.py +15 -0
  95. schemathesis/graphql/checks.py +109 -0
  96. schemathesis/graphql/loaders.py +284 -0
  97. schemathesis/hooks.py +80 -101
  98. schemathesis/openapi/__init__.py +13 -0
  99. schemathesis/openapi/checks.py +455 -0
  100. schemathesis/openapi/generation/__init__.py +0 -0
  101. schemathesis/openapi/generation/filters.py +72 -0
  102. schemathesis/openapi/loaders.py +313 -0
  103. schemathesis/pytest/__init__.py +5 -0
  104. schemathesis/pytest/control_flow.py +7 -0
  105. schemathesis/pytest/lazy.py +281 -0
  106. schemathesis/pytest/loaders.py +36 -0
  107. schemathesis/{extra/pytest_plugin.py → pytest/plugin.py} +128 -108
  108. schemathesis/python/__init__.py +0 -0
  109. schemathesis/python/asgi.py +12 -0
  110. schemathesis/python/wsgi.py +12 -0
  111. schemathesis/schemas.py +537 -273
  112. schemathesis/specs/graphql/__init__.py +0 -1
  113. schemathesis/specs/graphql/_cache.py +1 -2
  114. schemathesis/specs/graphql/scalars.py +42 -6
  115. schemathesis/specs/graphql/schemas.py +141 -137
  116. schemathesis/specs/graphql/validation.py +11 -17
  117. schemathesis/specs/openapi/__init__.py +6 -1
  118. schemathesis/specs/openapi/_cache.py +1 -2
  119. schemathesis/specs/openapi/_hypothesis.py +142 -156
  120. schemathesis/specs/openapi/checks.py +368 -257
  121. schemathesis/specs/openapi/converter.py +4 -4
  122. schemathesis/specs/openapi/definitions.py +1 -1
  123. schemathesis/specs/openapi/examples.py +23 -21
  124. schemathesis/specs/openapi/expressions/__init__.py +31 -19
  125. schemathesis/specs/openapi/expressions/extractors.py +1 -4
  126. schemathesis/specs/openapi/expressions/lexer.py +1 -1
  127. schemathesis/specs/openapi/expressions/nodes.py +36 -41
  128. schemathesis/specs/openapi/expressions/parser.py +1 -1
  129. schemathesis/specs/openapi/formats.py +35 -7
  130. schemathesis/specs/openapi/media_types.py +53 -12
  131. schemathesis/specs/openapi/negative/__init__.py +7 -4
  132. schemathesis/specs/openapi/negative/mutations.py +6 -5
  133. schemathesis/specs/openapi/parameters.py +7 -10
  134. schemathesis/specs/openapi/patterns.py +94 -31
  135. schemathesis/specs/openapi/references.py +12 -53
  136. schemathesis/specs/openapi/schemas.py +233 -307
  137. schemathesis/specs/openapi/security.py +1 -1
  138. schemathesis/specs/openapi/serialization.py +12 -6
  139. schemathesis/specs/openapi/stateful/__init__.py +268 -133
  140. schemathesis/specs/openapi/stateful/control.py +87 -0
  141. schemathesis/specs/openapi/stateful/links.py +209 -0
  142. schemathesis/transport/__init__.py +142 -0
  143. schemathesis/transport/asgi.py +26 -0
  144. schemathesis/transport/prepare.py +124 -0
  145. schemathesis/transport/requests.py +244 -0
  146. schemathesis/{_xml.py → transport/serialization.py} +69 -11
  147. schemathesis/transport/wsgi.py +171 -0
  148. schemathesis-4.0.0.dist-info/METADATA +204 -0
  149. schemathesis-4.0.0.dist-info/RECORD +164 -0
  150. {schemathesis-3.39.16.dist-info → schemathesis-4.0.0.dist-info}/entry_points.txt +1 -1
  151. {schemathesis-3.39.16.dist-info → schemathesis-4.0.0.dist-info}/licenses/LICENSE +1 -1
  152. schemathesis/_compat.py +0 -74
  153. schemathesis/_dependency_versions.py +0 -19
  154. schemathesis/_hypothesis.py +0 -717
  155. schemathesis/_override.py +0 -50
  156. schemathesis/_patches.py +0 -21
  157. schemathesis/_rate_limiter.py +0 -7
  158. schemathesis/cli/callbacks.py +0 -466
  159. schemathesis/cli/cassettes.py +0 -561
  160. schemathesis/cli/context.py +0 -75
  161. schemathesis/cli/debug.py +0 -27
  162. schemathesis/cli/handlers.py +0 -19
  163. schemathesis/cli/junitxml.py +0 -124
  164. schemathesis/cli/output/__init__.py +0 -1
  165. schemathesis/cli/output/default.py +0 -920
  166. schemathesis/cli/output/short.py +0 -59
  167. schemathesis/cli/reporting.py +0 -79
  168. schemathesis/cli/sanitization.py +0 -26
  169. schemathesis/code_samples.py +0 -151
  170. schemathesis/constants.py +0 -54
  171. schemathesis/contrib/__init__.py +0 -11
  172. schemathesis/contrib/openapi/__init__.py +0 -11
  173. schemathesis/contrib/openapi/fill_missing_examples.py +0 -24
  174. schemathesis/contrib/openapi/formats/__init__.py +0 -9
  175. schemathesis/contrib/openapi/formats/uuid.py +0 -16
  176. schemathesis/contrib/unique_data.py +0 -41
  177. schemathesis/exceptions.py +0 -571
  178. schemathesis/experimental/__init__.py +0 -109
  179. schemathesis/extra/_aiohttp.py +0 -28
  180. schemathesis/extra/_flask.py +0 -13
  181. schemathesis/extra/_server.py +0 -18
  182. schemathesis/failures.py +0 -284
  183. schemathesis/fixups/__init__.py +0 -37
  184. schemathesis/fixups/fast_api.py +0 -41
  185. schemathesis/fixups/utf8_bom.py +0 -28
  186. schemathesis/generation/_methods.py +0 -44
  187. schemathesis/graphql.py +0 -3
  188. schemathesis/internal/__init__.py +0 -7
  189. schemathesis/internal/checks.py +0 -86
  190. schemathesis/internal/copy.py +0 -32
  191. schemathesis/internal/datetime.py +0 -5
  192. schemathesis/internal/deprecation.py +0 -37
  193. schemathesis/internal/diff.py +0 -15
  194. schemathesis/internal/extensions.py +0 -27
  195. schemathesis/internal/jsonschema.py +0 -36
  196. schemathesis/internal/output.py +0 -68
  197. schemathesis/internal/transformation.py +0 -26
  198. schemathesis/internal/validation.py +0 -34
  199. schemathesis/lazy.py +0 -474
  200. schemathesis/loaders.py +0 -122
  201. schemathesis/models.py +0 -1341
  202. schemathesis/parameters.py +0 -90
  203. schemathesis/runner/__init__.py +0 -605
  204. schemathesis/runner/events.py +0 -389
  205. schemathesis/runner/impl/__init__.py +0 -3
  206. schemathesis/runner/impl/context.py +0 -88
  207. schemathesis/runner/impl/core.py +0 -1280
  208. schemathesis/runner/impl/solo.py +0 -80
  209. schemathesis/runner/impl/threadpool.py +0 -391
  210. schemathesis/runner/serialization.py +0 -544
  211. schemathesis/sanitization.py +0 -252
  212. schemathesis/serializers.py +0 -328
  213. schemathesis/service/__init__.py +0 -18
  214. schemathesis/service/auth.py +0 -11
  215. schemathesis/service/ci.py +0 -202
  216. schemathesis/service/client.py +0 -133
  217. schemathesis/service/constants.py +0 -38
  218. schemathesis/service/events.py +0 -61
  219. schemathesis/service/extensions.py +0 -224
  220. schemathesis/service/hosts.py +0 -111
  221. schemathesis/service/metadata.py +0 -71
  222. schemathesis/service/models.py +0 -258
  223. schemathesis/service/report.py +0 -255
  224. schemathesis/service/serialization.py +0 -173
  225. schemathesis/service/usage.py +0 -66
  226. schemathesis/specs/graphql/loaders.py +0 -364
  227. schemathesis/specs/openapi/expressions/context.py +0 -16
  228. schemathesis/specs/openapi/links.py +0 -389
  229. schemathesis/specs/openapi/loaders.py +0 -707
  230. schemathesis/specs/openapi/stateful/statistic.py +0 -198
  231. schemathesis/specs/openapi/stateful/types.py +0 -14
  232. schemathesis/specs/openapi/validation.py +0 -26
  233. schemathesis/stateful/__init__.py +0 -147
  234. schemathesis/stateful/config.py +0 -97
  235. schemathesis/stateful/context.py +0 -135
  236. schemathesis/stateful/events.py +0 -274
  237. schemathesis/stateful/runner.py +0 -309
  238. schemathesis/stateful/sink.py +0 -68
  239. schemathesis/stateful/state_machine.py +0 -328
  240. schemathesis/stateful/statistic.py +0 -22
  241. schemathesis/stateful/validation.py +0 -100
  242. schemathesis/targets.py +0 -77
  243. schemathesis/transports/__init__.py +0 -369
  244. schemathesis/transports/asgi.py +0 -7
  245. schemathesis/transports/auth.py +0 -38
  246. schemathesis/transports/headers.py +0 -36
  247. schemathesis/transports/responses.py +0 -57
  248. schemathesis/types.py +0 -44
  249. schemathesis/utils.py +0 -164
  250. schemathesis-3.39.16.dist-info/METADATA +0 -293
  251. schemathesis-3.39.16.dist-info/RECORD +0 -160
  252. /schemathesis/{extra → cli/ext}/__init__.py +0 -0
  253. /schemathesis/{_lazy_import.py → core/lazy_import.py} +0 -0
  254. /schemathesis/{internal → core}/result.py +0 -0
  255. {schemathesis-3.39.16.dist-info → schemathesis-4.0.0.dist-info}/WHEEL +0 -0
@@ -0,0 +1,317 @@
1
+ from __future__ import annotations
2
+
3
+ from dataclasses import dataclass
4
+ from typing import TYPE_CHECKING, Any, Mapping
5
+
6
+ from schemathesis import transport
7
+ from schemathesis.checks import CHECKS, CheckContext, CheckFunction, run_checks
8
+ from schemathesis.core import NOT_SET, SCHEMATHESIS_TEST_CASE_HEADER, NotSet, curl
9
+ from schemathesis.core.failures import FailureGroup, failure_report_title, format_failures
10
+ from schemathesis.core.transport import Response
11
+ from schemathesis.generation import generate_random_case_id
12
+ from schemathesis.generation.meta import CaseMetadata
13
+ from schemathesis.generation.overrides import Override, store_components
14
+ from schemathesis.hooks import HookContext, dispatch
15
+ from schemathesis.transport.prepare import prepare_path, prepare_request
16
+
17
+ if TYPE_CHECKING:
18
+ import httpx
19
+ import requests
20
+ import requests.auth
21
+ from requests.structures import CaseInsensitiveDict
22
+ from werkzeug.test import TestResponse
23
+
24
+ from schemathesis.schemas import APIOperation
25
+
26
+
27
+ def _default_headers() -> CaseInsensitiveDict:
28
+ from requests.structures import CaseInsensitiveDict
29
+
30
+ return CaseInsensitiveDict()
31
+
32
+
33
+ @dataclass
34
+ class Case:
35
+ """Generated test case data for a single API operation."""
36
+
37
+ operation: APIOperation
38
+ method: str
39
+ """HTTP verb (`GET`, `POST`, etc.)"""
40
+ path: str
41
+ """Path template from schema (e.g., `/users/{user_id}`)"""
42
+ id: str
43
+ """Random ID sent in headers for log correlation"""
44
+ path_parameters: dict[str, Any]
45
+ """Generated path variables (e.g., `{"user_id": "123"}`)"""
46
+ headers: CaseInsensitiveDict
47
+ """Generated HTTP headers"""
48
+ cookies: dict[str, Any]
49
+ """Generated cookies"""
50
+ query: dict[str, Any]
51
+ """Generated query parameters"""
52
+ # By default, there is no body, but we can't use `None` as the default value because it clashes with `null`
53
+ # which is a valid payload.
54
+ body: list | dict[str, Any] | str | int | float | bool | bytes | NotSet
55
+ """Generated request body"""
56
+ media_type: str | None
57
+ """Media type from OpenAPI schema (e.g., "multipart/form-data")"""
58
+
59
+ meta: CaseMetadata | None
60
+
61
+ _auth: requests.auth.AuthBase | None
62
+ _has_explicit_auth: bool
63
+
64
+ __slots__ = (
65
+ "operation",
66
+ "method",
67
+ "path",
68
+ "id",
69
+ "path_parameters",
70
+ "headers",
71
+ "cookies",
72
+ "query",
73
+ "body",
74
+ "media_type",
75
+ "meta",
76
+ "_auth",
77
+ "_has_explicit_auth",
78
+ "_components",
79
+ )
80
+
81
+ def __init__(
82
+ self,
83
+ operation: APIOperation,
84
+ method: str,
85
+ path: str,
86
+ *,
87
+ id: str | None = None,
88
+ path_parameters: dict[str, Any] | None = None,
89
+ headers: CaseInsensitiveDict | None = None,
90
+ cookies: dict[str, Any] | None = None,
91
+ query: dict[str, Any] | None = None,
92
+ body: list | dict[str, Any] | str | int | float | bool | bytes | "NotSet" = NOT_SET,
93
+ media_type: str | None = None,
94
+ meta: CaseMetadata | None = None,
95
+ _auth: requests.auth.AuthBase | None = None,
96
+ _has_explicit_auth: bool = False,
97
+ ) -> None:
98
+ self.operation = operation
99
+ self.method = method
100
+ self.path = path
101
+
102
+ self.id = id if id is not None else generate_random_case_id()
103
+ self.path_parameters = path_parameters if path_parameters is not None else {}
104
+ self.headers = headers if headers is not None else _default_headers()
105
+ self.cookies = cookies if cookies is not None else {}
106
+ self.query = query if query is not None else {}
107
+ self.body = body
108
+ self.media_type = media_type
109
+ self.meta = meta
110
+ self._auth = _auth
111
+ self._has_explicit_auth = _has_explicit_auth
112
+ self._components = store_components(self)
113
+
114
+ def __eq__(self, other: object) -> bool:
115
+ if not isinstance(other, Case):
116
+ return NotImplemented
117
+
118
+ return (
119
+ self.operation == other.operation
120
+ and self.method == other.method
121
+ and self.path == other.path
122
+ and self.path_parameters == other.path_parameters
123
+ and self.headers == other.headers
124
+ and self.cookies == other.cookies
125
+ and self.query == other.query
126
+ and self.body == other.body
127
+ and self.media_type == other.media_type
128
+ )
129
+
130
+ @property
131
+ def _override(self) -> Override:
132
+ return Override.from_components(self._components, self)
133
+
134
+ def __repr__(self) -> str:
135
+ output = f"{self.__class__.__name__}("
136
+ first = True
137
+ for name in ("path_parameters", "headers", "cookies", "query", "body"):
138
+ value = getattr(self, name)
139
+ if name != "body" and not value:
140
+ continue
141
+ if value is not None and not isinstance(value, NotSet):
142
+ if first:
143
+ first = False
144
+ else:
145
+ output += ", "
146
+ output += f"{name}={value!r}"
147
+ return f"{output})"
148
+
149
+ def __hash__(self) -> int:
150
+ return hash(self.as_curl_command({SCHEMATHESIS_TEST_CASE_HEADER: "0"}))
151
+
152
+ def _repr_pretty_(self, *args: Any, **kwargs: Any) -> None: ...
153
+
154
+ @property
155
+ def formatted_path(self) -> str:
156
+ """Path template with variables substituted (e.g., /users/{user_id} → /users/123)."""
157
+ return prepare_path(self.path, self.path_parameters)
158
+
159
+ def as_curl_command(self, headers: Mapping[str, Any] | None = None, verify: bool = True) -> str:
160
+ """Generate a curl command that reproduces this test case.
161
+
162
+ Args:
163
+ headers: Additional headers to include in the command.
164
+ verify: When False, adds `--insecure` flag to curl command.
165
+
166
+ """
167
+ request_data = prepare_request(self, headers, config=self.operation.schema.config.output.sanitization)
168
+ return curl.generate(
169
+ method=str(request_data.method),
170
+ url=str(request_data.url),
171
+ body=request_data.body,
172
+ verify=verify,
173
+ headers=dict(request_data.headers),
174
+ known_generated_headers=dict(self.headers or {}),
175
+ )
176
+
177
+ def as_transport_kwargs(self, base_url: str | None = None, headers: dict[str, str] | None = None) -> dict[str, Any]:
178
+ return self.operation.schema.transport.serialize_case(self, base_url=base_url, headers=headers)
179
+
180
+ def call(
181
+ self,
182
+ base_url: str | None = None,
183
+ session: requests.Session | None = None,
184
+ headers: dict[str, Any] | None = None,
185
+ params: dict[str, Any] | None = None,
186
+ cookies: dict[str, Any] | None = None,
187
+ **kwargs: Any,
188
+ ) -> Response:
189
+ """Make an HTTP request using this test case's data without validation.
190
+
191
+ Use when you need to validate response separately
192
+
193
+ Args:
194
+ base_url: Override the schema's base URL.
195
+ session: Reuse an existing requests session.
196
+ headers: Additional headers.
197
+ params: Additional query parameters.
198
+ cookies: Additional cookies.
199
+ **kwargs: Additional transport-level arguments.
200
+
201
+ """
202
+ hook_context = HookContext(operation=self.operation)
203
+ dispatch("before_call", hook_context, self, **kwargs)
204
+ if self.operation.app is not None:
205
+ kwargs.setdefault("app", self.operation.app)
206
+ if "app" in kwargs:
207
+ transport_ = transport.get(kwargs["app"])
208
+ else:
209
+ transport_ = self.operation.schema.transport
210
+ response = transport_.send(
211
+ self,
212
+ session=session,
213
+ base_url=base_url,
214
+ headers=headers,
215
+ params=params,
216
+ cookies=cookies,
217
+ **kwargs,
218
+ )
219
+ dispatch("after_call", hook_context, self, response)
220
+ return response
221
+
222
+ def validate_response(
223
+ self,
224
+ response: Response | httpx.Response | requests.Response | TestResponse,
225
+ checks: list[CheckFunction] | None = None,
226
+ additional_checks: list[CheckFunction] | None = None,
227
+ excluded_checks: list[CheckFunction] | None = None,
228
+ headers: dict[str, Any] | None = None,
229
+ transport_kwargs: dict[str, Any] | None = None,
230
+ ) -> None:
231
+ """Validate a response against the API schema and built-in checks.
232
+
233
+ Args:
234
+ response: Response to validate.
235
+ checks: Explicit set of checks to run.
236
+ additional_checks: Additional custom checks to run.
237
+ excluded_checks: Built-in checks to skip.
238
+ headers: Headers used in the original request.
239
+ transport_kwargs: Transport arguments used in the original request.
240
+
241
+ """
242
+ __tracebackhide__ = True
243
+ from requests.structures import CaseInsensitiveDict
244
+
245
+ response = Response.from_any(response)
246
+
247
+ checks = [
248
+ check
249
+ for check in list(checks or CHECKS.get_all()) + list(additional_checks or [])
250
+ if check not in set(excluded_checks or [])
251
+ ]
252
+
253
+ ctx = CheckContext(
254
+ override=self._override,
255
+ auth=None,
256
+ headers=CaseInsensitiveDict(headers) if headers else None,
257
+ config=self.operation.schema.config.checks_config_for(
258
+ operation=self.operation, phase=self.meta.phase.name.value if self.meta is not None else None
259
+ ),
260
+ transport_kwargs=transport_kwargs,
261
+ recorder=None,
262
+ )
263
+ failures = run_checks(
264
+ case=self,
265
+ response=response,
266
+ ctx=ctx,
267
+ checks=checks,
268
+ on_failure=lambda _, collected, failure: collected.add(failure),
269
+ )
270
+ if failures:
271
+ _failures = list(failures)
272
+ message = failure_report_title(_failures) + "\n"
273
+ verify = getattr(response, "verify", True)
274
+ curl = self.as_curl_command(headers=dict(response.request.headers), verify=verify)
275
+ message += format_failures(
276
+ case_id=None,
277
+ response=response,
278
+ failures=_failures,
279
+ curl=curl,
280
+ config=self.operation.schema.config.output,
281
+ )
282
+ message += "\n\n"
283
+ raise FailureGroup(_failures, message) from None
284
+
285
+ def call_and_validate(
286
+ self,
287
+ base_url: str | None = None,
288
+ session: requests.Session | None = None,
289
+ headers: dict[str, Any] | None = None,
290
+ checks: list[CheckFunction] | None = None,
291
+ additional_checks: list[CheckFunction] | None = None,
292
+ excluded_checks: list[CheckFunction] | None = None,
293
+ **kwargs: Any,
294
+ ) -> Response:
295
+ """Make an HTTP request and validates the response automatically.
296
+
297
+ Args:
298
+ base_url: Override the schema's base URL.
299
+ session: Reuse an existing requests session.
300
+ headers: Additional headers to send.
301
+ checks: Explicit set of checks to run.
302
+ additional_checks: Additional custom checks to run.
303
+ excluded_checks: Built-in checks to skip.
304
+ **kwargs: Additional transport-level arguments.
305
+
306
+ """
307
+ __tracebackhide__ = True
308
+ response = self.call(base_url, session, headers, **kwargs)
309
+ self.validate_response(
310
+ response,
311
+ checks,
312
+ headers=headers,
313
+ additional_checks=additional_checks,
314
+ excluded_checks=excluded_checks,
315
+ transport_kwargs=kwargs,
316
+ )
317
+ return response