schemathesis 3.25.5__py3-none-any.whl → 4.0.0a1__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 (221) hide show
  1. schemathesis/__init__.py +27 -65
  2. schemathesis/auths.py +102 -82
  3. schemathesis/checks.py +126 -46
  4. schemathesis/cli/__init__.py +11 -1766
  5. schemathesis/cli/__main__.py +4 -0
  6. schemathesis/cli/commands/__init__.py +37 -0
  7. schemathesis/cli/commands/run/__init__.py +662 -0
  8. schemathesis/cli/commands/run/checks.py +80 -0
  9. schemathesis/cli/commands/run/context.py +117 -0
  10. schemathesis/cli/commands/run/events.py +35 -0
  11. schemathesis/cli/commands/run/executor.py +138 -0
  12. schemathesis/cli/commands/run/filters.py +194 -0
  13. schemathesis/cli/commands/run/handlers/__init__.py +46 -0
  14. schemathesis/cli/commands/run/handlers/base.py +18 -0
  15. schemathesis/cli/commands/run/handlers/cassettes.py +494 -0
  16. schemathesis/cli/commands/run/handlers/junitxml.py +54 -0
  17. schemathesis/cli/commands/run/handlers/output.py +746 -0
  18. schemathesis/cli/commands/run/hypothesis.py +105 -0
  19. schemathesis/cli/commands/run/loaders.py +129 -0
  20. schemathesis/cli/{callbacks.py → commands/run/validation.py} +103 -174
  21. schemathesis/cli/constants.py +5 -52
  22. schemathesis/cli/core.py +17 -0
  23. schemathesis/cli/ext/fs.py +14 -0
  24. schemathesis/cli/ext/groups.py +55 -0
  25. schemathesis/cli/{options.py → ext/options.py} +39 -10
  26. schemathesis/cli/hooks.py +36 -0
  27. schemathesis/contrib/__init__.py +1 -3
  28. schemathesis/contrib/openapi/__init__.py +1 -3
  29. schemathesis/contrib/openapi/fill_missing_examples.py +3 -5
  30. schemathesis/core/__init__.py +58 -0
  31. schemathesis/core/compat.py +25 -0
  32. schemathesis/core/control.py +2 -0
  33. schemathesis/core/curl.py +58 -0
  34. schemathesis/core/deserialization.py +65 -0
  35. schemathesis/core/errors.py +370 -0
  36. schemathesis/core/failures.py +285 -0
  37. schemathesis/core/fs.py +19 -0
  38. schemathesis/{_lazy_import.py → core/lazy_import.py} +1 -0
  39. schemathesis/core/loaders.py +104 -0
  40. schemathesis/core/marks.py +66 -0
  41. schemathesis/{transports/content_types.py → core/media_types.py} +17 -13
  42. schemathesis/core/output/__init__.py +69 -0
  43. schemathesis/core/output/sanitization.py +197 -0
  44. schemathesis/core/rate_limit.py +60 -0
  45. schemathesis/core/registries.py +31 -0
  46. schemathesis/{internal → core}/result.py +1 -1
  47. schemathesis/core/transforms.py +113 -0
  48. schemathesis/core/transport.py +108 -0
  49. schemathesis/core/validation.py +38 -0
  50. schemathesis/core/version.py +7 -0
  51. schemathesis/engine/__init__.py +30 -0
  52. schemathesis/engine/config.py +59 -0
  53. schemathesis/engine/context.py +119 -0
  54. schemathesis/engine/control.py +36 -0
  55. schemathesis/engine/core.py +157 -0
  56. schemathesis/engine/errors.py +394 -0
  57. schemathesis/engine/events.py +337 -0
  58. schemathesis/engine/phases/__init__.py +66 -0
  59. schemathesis/{cli → engine/phases}/probes.py +63 -70
  60. schemathesis/engine/phases/stateful/__init__.py +65 -0
  61. schemathesis/engine/phases/stateful/_executor.py +326 -0
  62. schemathesis/engine/phases/stateful/context.py +85 -0
  63. schemathesis/engine/phases/unit/__init__.py +174 -0
  64. schemathesis/engine/phases/unit/_executor.py +321 -0
  65. schemathesis/engine/phases/unit/_pool.py +74 -0
  66. schemathesis/engine/recorder.py +241 -0
  67. schemathesis/errors.py +31 -0
  68. schemathesis/experimental/__init__.py +18 -14
  69. schemathesis/filters.py +103 -14
  70. schemathesis/generation/__init__.py +21 -37
  71. schemathesis/generation/case.py +190 -0
  72. schemathesis/generation/coverage.py +931 -0
  73. schemathesis/generation/hypothesis/__init__.py +30 -0
  74. schemathesis/generation/hypothesis/builder.py +585 -0
  75. schemathesis/generation/hypothesis/examples.py +50 -0
  76. schemathesis/generation/hypothesis/given.py +66 -0
  77. schemathesis/generation/hypothesis/reporting.py +14 -0
  78. schemathesis/generation/hypothesis/strategies.py +16 -0
  79. schemathesis/generation/meta.py +115 -0
  80. schemathesis/generation/modes.py +28 -0
  81. schemathesis/generation/overrides.py +96 -0
  82. schemathesis/generation/stateful/__init__.py +20 -0
  83. schemathesis/{stateful → generation/stateful}/state_machine.py +68 -81
  84. schemathesis/generation/targets.py +69 -0
  85. schemathesis/graphql/__init__.py +15 -0
  86. schemathesis/graphql/checks.py +115 -0
  87. schemathesis/graphql/loaders.py +131 -0
  88. schemathesis/hooks.py +99 -67
  89. schemathesis/openapi/__init__.py +13 -0
  90. schemathesis/openapi/checks.py +412 -0
  91. schemathesis/openapi/generation/__init__.py +0 -0
  92. schemathesis/openapi/generation/filters.py +63 -0
  93. schemathesis/openapi/loaders.py +178 -0
  94. schemathesis/pytest/__init__.py +5 -0
  95. schemathesis/pytest/control_flow.py +7 -0
  96. schemathesis/pytest/lazy.py +273 -0
  97. schemathesis/pytest/loaders.py +12 -0
  98. schemathesis/{extra/pytest_plugin.py → pytest/plugin.py} +106 -127
  99. schemathesis/python/__init__.py +0 -0
  100. schemathesis/python/asgi.py +12 -0
  101. schemathesis/python/wsgi.py +12 -0
  102. schemathesis/schemas.py +537 -261
  103. schemathesis/specs/graphql/__init__.py +0 -1
  104. schemathesis/specs/graphql/_cache.py +25 -0
  105. schemathesis/specs/graphql/nodes.py +1 -0
  106. schemathesis/specs/graphql/scalars.py +7 -5
  107. schemathesis/specs/graphql/schemas.py +215 -187
  108. schemathesis/specs/graphql/validation.py +11 -18
  109. schemathesis/specs/openapi/__init__.py +7 -1
  110. schemathesis/specs/openapi/_cache.py +122 -0
  111. schemathesis/specs/openapi/_hypothesis.py +146 -165
  112. schemathesis/specs/openapi/checks.py +565 -67
  113. schemathesis/specs/openapi/converter.py +33 -6
  114. schemathesis/specs/openapi/definitions.py +11 -18
  115. schemathesis/specs/openapi/examples.py +153 -39
  116. schemathesis/specs/openapi/expressions/__init__.py +37 -2
  117. schemathesis/specs/openapi/expressions/context.py +4 -6
  118. schemathesis/specs/openapi/expressions/extractors.py +23 -0
  119. schemathesis/specs/openapi/expressions/lexer.py +20 -18
  120. schemathesis/specs/openapi/expressions/nodes.py +38 -14
  121. schemathesis/specs/openapi/expressions/parser.py +26 -5
  122. schemathesis/specs/openapi/formats.py +45 -0
  123. schemathesis/specs/openapi/links.py +65 -165
  124. schemathesis/specs/openapi/media_types.py +32 -0
  125. schemathesis/specs/openapi/negative/__init__.py +7 -3
  126. schemathesis/specs/openapi/negative/mutations.py +24 -8
  127. schemathesis/specs/openapi/parameters.py +46 -30
  128. schemathesis/specs/openapi/patterns.py +137 -0
  129. schemathesis/specs/openapi/references.py +47 -57
  130. schemathesis/specs/openapi/schemas.py +483 -367
  131. schemathesis/specs/openapi/security.py +25 -7
  132. schemathesis/specs/openapi/serialization.py +11 -6
  133. schemathesis/specs/openapi/stateful/__init__.py +185 -73
  134. schemathesis/specs/openapi/utils.py +6 -1
  135. schemathesis/transport/__init__.py +104 -0
  136. schemathesis/transport/asgi.py +26 -0
  137. schemathesis/transport/prepare.py +99 -0
  138. schemathesis/transport/requests.py +221 -0
  139. schemathesis/{_xml.py → transport/serialization.py} +143 -28
  140. schemathesis/transport/wsgi.py +165 -0
  141. schemathesis-4.0.0a1.dist-info/METADATA +297 -0
  142. schemathesis-4.0.0a1.dist-info/RECORD +152 -0
  143. {schemathesis-3.25.5.dist-info → schemathesis-4.0.0a1.dist-info}/WHEEL +1 -1
  144. {schemathesis-3.25.5.dist-info → schemathesis-4.0.0a1.dist-info}/entry_points.txt +1 -1
  145. schemathesis/_compat.py +0 -74
  146. schemathesis/_dependency_versions.py +0 -17
  147. schemathesis/_hypothesis.py +0 -246
  148. schemathesis/_override.py +0 -49
  149. schemathesis/cli/cassettes.py +0 -375
  150. schemathesis/cli/context.py +0 -55
  151. schemathesis/cli/debug.py +0 -26
  152. schemathesis/cli/handlers.py +0 -16
  153. schemathesis/cli/junitxml.py +0 -43
  154. schemathesis/cli/output/__init__.py +0 -1
  155. schemathesis/cli/output/default.py +0 -765
  156. schemathesis/cli/output/short.py +0 -40
  157. schemathesis/cli/sanitization.py +0 -20
  158. schemathesis/code_samples.py +0 -149
  159. schemathesis/constants.py +0 -55
  160. schemathesis/contrib/openapi/formats/__init__.py +0 -9
  161. schemathesis/contrib/openapi/formats/uuid.py +0 -15
  162. schemathesis/contrib/unique_data.py +0 -41
  163. schemathesis/exceptions.py +0 -560
  164. schemathesis/extra/_aiohttp.py +0 -27
  165. schemathesis/extra/_flask.py +0 -10
  166. schemathesis/extra/_server.py +0 -17
  167. schemathesis/failures.py +0 -209
  168. schemathesis/fixups/__init__.py +0 -36
  169. schemathesis/fixups/fast_api.py +0 -41
  170. schemathesis/fixups/utf8_bom.py +0 -29
  171. schemathesis/graphql.py +0 -4
  172. schemathesis/internal/__init__.py +0 -7
  173. schemathesis/internal/copy.py +0 -13
  174. schemathesis/internal/datetime.py +0 -5
  175. schemathesis/internal/deprecation.py +0 -34
  176. schemathesis/internal/jsonschema.py +0 -35
  177. schemathesis/internal/transformation.py +0 -15
  178. schemathesis/internal/validation.py +0 -34
  179. schemathesis/lazy.py +0 -361
  180. schemathesis/loaders.py +0 -120
  181. schemathesis/models.py +0 -1231
  182. schemathesis/parameters.py +0 -86
  183. schemathesis/runner/__init__.py +0 -555
  184. schemathesis/runner/events.py +0 -309
  185. schemathesis/runner/impl/__init__.py +0 -3
  186. schemathesis/runner/impl/core.py +0 -986
  187. schemathesis/runner/impl/solo.py +0 -90
  188. schemathesis/runner/impl/threadpool.py +0 -400
  189. schemathesis/runner/serialization.py +0 -411
  190. schemathesis/sanitization.py +0 -248
  191. schemathesis/serializers.py +0 -315
  192. schemathesis/service/__init__.py +0 -18
  193. schemathesis/service/auth.py +0 -11
  194. schemathesis/service/ci.py +0 -201
  195. schemathesis/service/client.py +0 -100
  196. schemathesis/service/constants.py +0 -38
  197. schemathesis/service/events.py +0 -57
  198. schemathesis/service/hosts.py +0 -107
  199. schemathesis/service/metadata.py +0 -46
  200. schemathesis/service/models.py +0 -49
  201. schemathesis/service/report.py +0 -255
  202. schemathesis/service/serialization.py +0 -184
  203. schemathesis/service/usage.py +0 -65
  204. schemathesis/specs/graphql/loaders.py +0 -344
  205. schemathesis/specs/openapi/filters.py +0 -49
  206. schemathesis/specs/openapi/loaders.py +0 -667
  207. schemathesis/specs/openapi/stateful/links.py +0 -92
  208. schemathesis/specs/openapi/validation.py +0 -25
  209. schemathesis/stateful/__init__.py +0 -133
  210. schemathesis/targets.py +0 -45
  211. schemathesis/throttling.py +0 -41
  212. schemathesis/transports/__init__.py +0 -5
  213. schemathesis/transports/auth.py +0 -15
  214. schemathesis/transports/headers.py +0 -35
  215. schemathesis/transports/responses.py +0 -52
  216. schemathesis/types.py +0 -35
  217. schemathesis/utils.py +0 -169
  218. schemathesis-3.25.5.dist-info/METADATA +0 -356
  219. schemathesis-3.25.5.dist-info/RECORD +0 -134
  220. /schemathesis/{extra → cli/ext}/__init__.py +0 -0
  221. {schemathesis-3.25.5.dist-info → schemathesis-4.0.0a1.dist-info}/licenses/LICENSE +0 -0
@@ -1,309 +0,0 @@
1
- from __future__ import annotations
2
- import enum
3
- import threading
4
- import time
5
- from dataclasses import asdict, dataclass, field
6
- from typing import Any, TYPE_CHECKING
7
-
8
- from ..internal.datetime import current_datetime
9
- from ..generation import DataGenerationMethod
10
- from ..exceptions import SchemaError, SchemaErrorType, format_exception, RuntimeErrorType
11
- from .serialization import SerializedError, SerializedTestResult
12
-
13
-
14
- if TYPE_CHECKING:
15
- from ..models import APIOperation, Status, TestResult, TestResultSet
16
- from ..schemas import BaseSchema
17
-
18
-
19
- @dataclass
20
- class ExecutionEvent:
21
- """Generic execution event."""
22
-
23
- # Whether this event is expected to be the last one in the event stream
24
- is_terminal = False
25
-
26
- def asdict(self, **kwargs: Any) -> dict[str, Any]:
27
- data = asdict(self, **kwargs)
28
- # An internal tag for simpler type identification
29
- data["event_type"] = self.__class__.__name__
30
- return data
31
-
32
-
33
- @dataclass
34
- class Initialized(ExecutionEvent):
35
- """Runner is initialized, settings are prepared, requests session is ready."""
36
-
37
- schema: dict[str, Any]
38
- # Total number of operations in the schema
39
- operations_count: int | None
40
- # Total number of links in the schema
41
- links_count: int | None
42
- # The place, where the API schema is located
43
- location: str | None
44
- seed: int | None
45
- # The base URL against which the tests are running
46
- base_url: str
47
- # API schema specification name
48
- specification_name: str
49
- # Monotonic clock value when the test run started. Used to properly calculate run duration, since this clock
50
- # can't go backwards.
51
- start_time: float = field(default_factory=time.monotonic)
52
- # Datetime of the test run start
53
- started_at: str = field(default_factory=current_datetime)
54
- thread_id: int = field(default_factory=threading.get_ident)
55
-
56
- @classmethod
57
- def from_schema(
58
- cls,
59
- *,
60
- schema: BaseSchema,
61
- count_operations: bool = True,
62
- count_links: bool = True,
63
- started_at: str | None = None,
64
- seed: int | None,
65
- ) -> Initialized:
66
- """Computes all needed data from a schema instance."""
67
- return cls(
68
- schema=schema.raw_schema,
69
- operations_count=schema.operations_count if count_operations else None,
70
- links_count=schema.links_count if count_links else None,
71
- location=schema.location,
72
- base_url=schema.get_base_url(),
73
- started_at=started_at or current_datetime(),
74
- specification_name=schema.verbose_name,
75
- seed=seed,
76
- )
77
-
78
-
79
- class CurrentOperationMixin:
80
- method: str
81
- path: str
82
-
83
- @property
84
- def current_operation(self) -> str:
85
- return f"{self.method} {self.path}"
86
-
87
-
88
- @dataclass
89
- class BeforeExecution(CurrentOperationMixin, ExecutionEvent):
90
- """Happens before each tested API operation.
91
-
92
- It happens before a single hypothesis test, that may contain many examples inside.
93
- """
94
-
95
- # HTTP method
96
- method: str
97
- # Full path, including the base path
98
- path: str
99
- # Specification-specific operation name
100
- verbose_name: str
101
- # Path without the base path
102
- relative_path: str
103
- # The current level of recursion during stateful testing
104
- recursion_level: int
105
- # The way data will be generated
106
- data_generation_method: list[DataGenerationMethod]
107
- # A unique ID which connects events that happen during testing of the same API operation
108
- # It may be useful when multiple threads are involved where incoming events are not ordered
109
- correlation_id: str
110
- thread_id: int = field(default_factory=threading.get_ident)
111
-
112
- @classmethod
113
- def from_operation(
114
- cls,
115
- operation: APIOperation,
116
- recursion_level: int,
117
- data_generation_method: list[DataGenerationMethod],
118
- correlation_id: str,
119
- ) -> BeforeExecution:
120
- return cls(
121
- method=operation.method.upper(),
122
- path=operation.full_path,
123
- verbose_name=operation.verbose_name,
124
- relative_path=operation.path,
125
- recursion_level=recursion_level,
126
- data_generation_method=data_generation_method,
127
- correlation_id=correlation_id,
128
- )
129
-
130
-
131
- @dataclass
132
- class AfterExecution(CurrentOperationMixin, ExecutionEvent):
133
- """Happens after each tested API operation."""
134
-
135
- method: str
136
- path: str
137
- relative_path: str
138
- # Specification-specific operation name
139
- verbose_name: str
140
-
141
- # APIOperation test status - success / failure / error
142
- status: Status
143
- # The way data was generated
144
- data_generation_method: list[DataGenerationMethod]
145
- result: SerializedTestResult
146
- # Test running time
147
- elapsed_time: float
148
- correlation_id: str
149
- thread_id: int = field(default_factory=threading.get_ident)
150
- # Captured hypothesis stdout
151
- hypothesis_output: list[str] = field(default_factory=list)
152
-
153
- @classmethod
154
- def from_result(
155
- cls,
156
- result: TestResult,
157
- status: Status,
158
- elapsed_time: float,
159
- hypothesis_output: list[str],
160
- operation: APIOperation,
161
- data_generation_method: list[DataGenerationMethod],
162
- correlation_id: str,
163
- ) -> AfterExecution:
164
- return cls(
165
- method=operation.method.upper(),
166
- path=operation.full_path,
167
- relative_path=operation.path,
168
- verbose_name=operation.verbose_name,
169
- result=SerializedTestResult.from_test_result(result),
170
- status=status,
171
- elapsed_time=elapsed_time,
172
- hypothesis_output=hypothesis_output,
173
- data_generation_method=data_generation_method,
174
- correlation_id=correlation_id,
175
- )
176
-
177
-
178
- @dataclass
179
- class Interrupted(ExecutionEvent):
180
- """If execution was interrupted by Ctrl-C, or a received SIGTERM."""
181
-
182
- thread_id: int = field(default_factory=threading.get_ident)
183
-
184
-
185
- @enum.unique
186
- class InternalErrorType(str, enum.Enum):
187
- SCHEMA = "schema"
188
- OTHER = "other"
189
-
190
-
191
- @dataclass
192
- class InternalError(ExecutionEvent):
193
- """An error that happened inside the runner."""
194
-
195
- is_terminal = True
196
-
197
- # Main error info
198
- type: InternalErrorType
199
- subtype: SchemaErrorType | None
200
- title: str
201
- message: str
202
- extras: list[str]
203
-
204
- # Exception info
205
- exception_type: str
206
- exception: str
207
- exception_with_traceback: str
208
- # Auxiliary data
209
- thread_id: int = field(default_factory=threading.get_ident)
210
-
211
- @classmethod
212
- def from_schema_error(cls, error: SchemaError) -> InternalError:
213
- return cls.with_exception(
214
- error,
215
- type_=InternalErrorType.SCHEMA,
216
- subtype=error.type,
217
- title="Schema Loading Error",
218
- message=error.message,
219
- extras=error.extras,
220
- )
221
-
222
- @classmethod
223
- def from_exc(cls, exc: Exception) -> InternalError:
224
- return cls.with_exception(
225
- exc,
226
- type_=InternalErrorType.OTHER,
227
- subtype=None,
228
- title="Test Execution Error",
229
- message="An internal error occurred during the test run",
230
- extras=[],
231
- )
232
-
233
- @classmethod
234
- def with_exception(
235
- cls,
236
- exc: Exception,
237
- type_: InternalErrorType,
238
- subtype: SchemaErrorType | None,
239
- title: str,
240
- message: str,
241
- extras: list[str],
242
- ) -> InternalError:
243
- exception_type = f"{exc.__class__.__module__}.{exc.__class__.__qualname__}"
244
- exception = format_exception(exc)
245
- exception_with_traceback = format_exception(exc, include_traceback=True)
246
- return cls(
247
- type=type_,
248
- subtype=subtype,
249
- title=title,
250
- message=message,
251
- extras=extras,
252
- exception_type=exception_type,
253
- exception=exception,
254
- exception_with_traceback=exception_with_traceback,
255
- )
256
-
257
-
258
- @dataclass
259
- class Finished(ExecutionEvent):
260
- """The final event of the run.
261
-
262
- No more events after this point.
263
- """
264
-
265
- is_terminal = True
266
-
267
- passed_count: int
268
- skipped_count: int
269
- failed_count: int
270
- errored_count: int
271
-
272
- has_failures: bool
273
- has_errors: bool
274
- has_logs: bool
275
- is_empty: bool
276
- generic_errors: list[SerializedError]
277
- warnings: list[str]
278
-
279
- total: dict[str, dict[str | Status, int]]
280
-
281
- # Total test run execution time
282
- running_time: float
283
- thread_id: int = field(default_factory=threading.get_ident)
284
-
285
- @classmethod
286
- def from_results(cls, results: TestResultSet, running_time: float) -> Finished:
287
- return cls(
288
- passed_count=results.passed_count,
289
- skipped_count=results.skipped_count,
290
- failed_count=results.failed_count,
291
- errored_count=results.errored_count,
292
- has_failures=results.has_failures,
293
- has_errors=results.has_errors,
294
- has_logs=results.has_logs,
295
- is_empty=results.is_empty,
296
- total=results.total,
297
- generic_errors=[
298
- SerializedError.with_exception(
299
- type_=RuntimeErrorType.SCHEMA_GENERIC,
300
- exception=error,
301
- title=error.full_path,
302
- message=error.message,
303
- extras=[],
304
- )
305
- for error in results.generic_errors
306
- ],
307
- warnings=results.warnings,
308
- running_time=running_time,
309
- )
@@ -1,3 +0,0 @@
1
- from .core import BaseRunner
2
- from .solo import SingleThreadASGIRunner, SingleThreadRunner, SingleThreadWSGIRunner
3
- from .threadpool import ThreadPoolASGIRunner, ThreadPoolRunner, ThreadPoolWSGIRunner