schemathesis 3.22.1__py3-none-any.whl → 3.23.1__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.
- schemathesis/_hypothesis.py +6 -2
- schemathesis/cli/__init__.py +30 -1
- schemathesis/cli/callbacks.py +10 -0
- schemathesis/cli/cassettes.py +5 -1
- schemathesis/contrib/openapi/__init__.py +3 -1
- schemathesis/contrib/openapi/fill_missing_examples.py +22 -0
- schemathesis/exceptions.py +5 -2
- schemathesis/models.py +3 -8
- schemathesis/runner/__init__.py +3 -0
- schemathesis/runner/impl/core.py +8 -5
- schemathesis/runner/impl/solo.py +2 -0
- schemathesis/runner/impl/threadpool.py +2 -0
- schemathesis/schemas.py +1 -1
- schemathesis/specs/openapi/examples.py +8 -1
- schemathesis/specs/openapi/loaders.py +4 -1
- schemathesis/specs/openapi/serialization.py +1 -1
- schemathesis/transports/responses.py +0 -26
- {schemathesis-3.22.1.dist-info → schemathesis-3.23.1.dist-info}/METADATA +3 -2
- {schemathesis-3.22.1.dist-info → schemathesis-3.23.1.dist-info}/RECORD +22 -21
- {schemathesis-3.22.1.dist-info → schemathesis-3.23.1.dist-info}/WHEEL +0 -0
- {schemathesis-3.22.1.dist-info → schemathesis-3.23.1.dist-info}/entry_points.txt +0 -0
- {schemathesis-3.22.1.dist-info → schemathesis-3.23.1.dist-info}/licenses/LICENSE +0 -0
schemathesis/_hypothesis.py
CHANGED
|
@@ -134,6 +134,12 @@ def add_examples(test: Callable, operation: APIOperation, hook_dispatcher: HookD
|
|
|
134
134
|
|
|
135
135
|
|
|
136
136
|
def get_single_example(strategy: st.SearchStrategy[Case]) -> Case:
|
|
137
|
+
examples: list[Case] = []
|
|
138
|
+
add_single_example(strategy, examples)
|
|
139
|
+
return examples[0]
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
def add_single_example(strategy: st.SearchStrategy[Case], examples: list[Case]) -> None:
|
|
137
143
|
@hypothesis.given(strategy) # type: ignore
|
|
138
144
|
@hypothesis.settings( # type: ignore
|
|
139
145
|
database=None,
|
|
@@ -146,6 +152,4 @@ def get_single_example(strategy: st.SearchStrategy[Case]) -> Case:
|
|
|
146
152
|
def example_generating_inner_function(ex: Case) -> None:
|
|
147
153
|
examples.append(ex)
|
|
148
154
|
|
|
149
|
-
examples: list[Case] = []
|
|
150
155
|
example_generating_inner_function()
|
|
151
|
-
return examples[0]
|
schemathesis/cli/__init__.py
CHANGED
|
@@ -165,6 +165,11 @@ class GroupedOption(click.Option):
|
|
|
165
165
|
self.group = group
|
|
166
166
|
|
|
167
167
|
|
|
168
|
+
with_request_proxy = click.option(
|
|
169
|
+
"--request-proxy",
|
|
170
|
+
help="Set the proxy for all network requests.",
|
|
171
|
+
type=str,
|
|
172
|
+
)
|
|
168
173
|
with_request_tls_verify = click.option(
|
|
169
174
|
"--request-tls-verify",
|
|
170
175
|
help="Configures TLS certificate verification for server requests. Can specify path to CA_BUNDLE for custom certs.",
|
|
@@ -398,6 +403,7 @@ REPORT_TO_SERVICE = ReportToService()
|
|
|
398
403
|
type=click.IntRange(1),
|
|
399
404
|
default=DEFAULT_RESPONSE_TIMEOUT,
|
|
400
405
|
)
|
|
406
|
+
@with_request_proxy
|
|
401
407
|
@with_request_tls_verify
|
|
402
408
|
@with_request_cert
|
|
403
409
|
@with_request_cert_key
|
|
@@ -542,6 +548,14 @@ The report data, consisting of a tar gz file with multiple JSON files, is subjec
|
|
|
542
548
|
default=False,
|
|
543
549
|
show_default=True,
|
|
544
550
|
)
|
|
551
|
+
@click.option(
|
|
552
|
+
"--contrib-openapi-fill-missing-examples",
|
|
553
|
+
"contrib_openapi_fill_missing_examples",
|
|
554
|
+
help="Enables generation of random examples for API operations that do not have explicit examples defined.",
|
|
555
|
+
is_flag=True,
|
|
556
|
+
default=False,
|
|
557
|
+
show_default=True,
|
|
558
|
+
)
|
|
545
559
|
@click.option(
|
|
546
560
|
"--hypothesis-database",
|
|
547
561
|
help="Configures storage for examples discovered by Hypothesis. "
|
|
@@ -637,6 +651,7 @@ The report data, consisting of a tar gz file with multiple JSON files, is subjec
|
|
|
637
651
|
help="Specifies the codec used for generating strings.",
|
|
638
652
|
type=str,
|
|
639
653
|
default="utf-8",
|
|
654
|
+
callback=callbacks.validate_generation_codec,
|
|
640
655
|
)
|
|
641
656
|
@click.option(
|
|
642
657
|
"--schemathesis-io-token",
|
|
@@ -690,6 +705,7 @@ def run(
|
|
|
690
705
|
request_tls_verify: bool = True,
|
|
691
706
|
request_cert: str | None = None,
|
|
692
707
|
request_cert_key: str | None = None,
|
|
708
|
+
request_proxy: str | None = None,
|
|
693
709
|
validate_schema: bool = True,
|
|
694
710
|
skip_deprecated_operations: bool = False,
|
|
695
711
|
junit_xml: click.utils.LazyFile | None = None,
|
|
@@ -709,6 +725,7 @@ def run(
|
|
|
709
725
|
sanitize_output: bool = True,
|
|
710
726
|
contrib_unique_data: bool = False,
|
|
711
727
|
contrib_openapi_formats_uuid: bool = False,
|
|
728
|
+
contrib_openapi_fill_missing_examples: bool = False,
|
|
712
729
|
hypothesis_database: str | None = None,
|
|
713
730
|
hypothesis_deadline: int | NotSet | None = None,
|
|
714
731
|
hypothesis_derandomize: bool | None = None,
|
|
@@ -842,6 +859,8 @@ def run(
|
|
|
842
859
|
contrib.unique_data.install()
|
|
843
860
|
if contrib_openapi_formats_uuid:
|
|
844
861
|
contrib.openapi.formats.uuid.install()
|
|
862
|
+
if contrib_openapi_fill_missing_examples:
|
|
863
|
+
contrib.openapi.fill_missing_examples.install()
|
|
845
864
|
|
|
846
865
|
hypothesis_settings = prepare_hypothesis_settings(
|
|
847
866
|
database=hypothesis_database,
|
|
@@ -863,6 +882,7 @@ def run(
|
|
|
863
882
|
data_generation_methods=data_generation_methods,
|
|
864
883
|
force_schema_version=force_schema_version,
|
|
865
884
|
request_tls_verify=request_tls_verify,
|
|
885
|
+
request_proxy=request_proxy,
|
|
866
886
|
request_cert=prepare_request_cert(request_cert, request_cert_key),
|
|
867
887
|
wait_for_schema=wait_for_schema,
|
|
868
888
|
auth=auth,
|
|
@@ -936,6 +956,7 @@ class LoaderConfig:
|
|
|
936
956
|
data_generation_methods: tuple[DataGenerationMethod, ...]
|
|
937
957
|
force_schema_version: str | None
|
|
938
958
|
request_tls_verify: bool | str
|
|
959
|
+
request_proxy: str | None
|
|
939
960
|
request_cert: RequestCert | None
|
|
940
961
|
wait_for_schema: float | None
|
|
941
962
|
rate_limit: str | None
|
|
@@ -961,6 +982,7 @@ def into_event_stream(
|
|
|
961
982
|
data_generation_methods: tuple[DataGenerationMethod, ...],
|
|
962
983
|
force_schema_version: str | None,
|
|
963
984
|
request_tls_verify: bool | str,
|
|
985
|
+
request_proxy: str | None,
|
|
964
986
|
request_cert: RequestCert | None,
|
|
965
987
|
# Network request parameters
|
|
966
988
|
auth: tuple[str, str] | None,
|
|
@@ -1000,6 +1022,7 @@ def into_event_stream(
|
|
|
1000
1022
|
skip_deprecated_operations=skip_deprecated_operations,
|
|
1001
1023
|
data_generation_methods=data_generation_methods,
|
|
1002
1024
|
force_schema_version=force_schema_version,
|
|
1025
|
+
request_proxy=request_proxy,
|
|
1003
1026
|
request_tls_verify=request_tls_verify,
|
|
1004
1027
|
request_cert=request_cert,
|
|
1005
1028
|
wait_for_schema=wait_for_schema,
|
|
@@ -1020,6 +1043,7 @@ def into_event_stream(
|
|
|
1020
1043
|
headers=headers,
|
|
1021
1044
|
request_timeout=request_timeout,
|
|
1022
1045
|
request_tls_verify=request_tls_verify,
|
|
1046
|
+
request_proxy=request_proxy,
|
|
1023
1047
|
request_cert=request_cert,
|
|
1024
1048
|
seed=seed,
|
|
1025
1049
|
exit_first=exit_first,
|
|
@@ -1073,7 +1097,7 @@ def _try_load_schema(config: LoaderConfig, first: Loader, second: Loader) -> Bas
|
|
|
1073
1097
|
try:
|
|
1074
1098
|
return first(config)
|
|
1075
1099
|
except SchemaError as exc:
|
|
1076
|
-
if should_try_more(exc):
|
|
1100
|
+
if config.force_schema_version is None and should_try_more(exc):
|
|
1077
1101
|
try:
|
|
1078
1102
|
return second(config)
|
|
1079
1103
|
except Exception as second_exc:
|
|
@@ -1088,6 +1112,8 @@ def is_specific_exception(loader: Loader, exc: Exception) -> bool:
|
|
|
1088
1112
|
loader is _load_graphql_schema
|
|
1089
1113
|
and isinstance(exc, SchemaError)
|
|
1090
1114
|
and exc.type == SchemaErrorType.GRAPHQL_INVALID_SCHEMA
|
|
1115
|
+
# In some cases it is not clear that the schema is even supposed to be GraphQL, e.g. an empty input
|
|
1116
|
+
and "Syntax Error: Unexpected <EOF>." not in exc.extras
|
|
1091
1117
|
)
|
|
1092
1118
|
|
|
1093
1119
|
|
|
@@ -1417,6 +1443,7 @@ def get_exit_code(event: events.ExecutionEvent) -> int:
|
|
|
1417
1443
|
@click.option("--force-color", help="Explicitly tells to enable ANSI color escape codes.", type=bool, is_flag=True)
|
|
1418
1444
|
@click.option("--verbosity", "-v", help="Increase verbosity of the output.", count=True)
|
|
1419
1445
|
@with_request_tls_verify
|
|
1446
|
+
@with_request_proxy
|
|
1420
1447
|
@with_request_cert
|
|
1421
1448
|
@with_request_cert_key
|
|
1422
1449
|
@click.pass_context
|
|
@@ -1432,6 +1459,7 @@ def replay(
|
|
|
1432
1459
|
request_tls_verify: bool = True,
|
|
1433
1460
|
request_cert: str | None = None,
|
|
1434
1461
|
request_cert_key: str | None = None,
|
|
1462
|
+
request_proxy: str | None = None,
|
|
1435
1463
|
force_color: bool = False,
|
|
1436
1464
|
) -> None:
|
|
1437
1465
|
"""Replay a cassette.
|
|
@@ -1455,6 +1483,7 @@ def replay(
|
|
|
1455
1483
|
method=method,
|
|
1456
1484
|
request_tls_verify=request_tls_verify,
|
|
1457
1485
|
request_cert=prepare_request_cert(request_cert, request_cert_key),
|
|
1486
|
+
request_proxy=request_proxy,
|
|
1458
1487
|
):
|
|
1459
1488
|
click.secho(f" {bold('ID')} : {replayed.interaction['id']}")
|
|
1460
1489
|
click.secho(f" {bold('URI')} : {replayed.interaction['request']['uri']}")
|
schemathesis/cli/callbacks.py
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import codecs
|
|
2
4
|
import enum
|
|
3
5
|
import os
|
|
4
6
|
import re
|
|
@@ -137,6 +139,14 @@ def validate_base_url(ctx: click.core.Context, param: click.core.Parameter, raw_
|
|
|
137
139
|
return raw_value
|
|
138
140
|
|
|
139
141
|
|
|
142
|
+
def validate_generation_codec(ctx: click.core.Context, param: click.core.Parameter, raw_value: str) -> str:
|
|
143
|
+
try:
|
|
144
|
+
codecs.getencoder(raw_value)
|
|
145
|
+
except LookupError as exc:
|
|
146
|
+
raise click.UsageError(f"Codec `{raw_value}` is unknown") from exc
|
|
147
|
+
return raw_value
|
|
148
|
+
|
|
149
|
+
|
|
140
150
|
def validate_rate_limit(ctx: click.core.Context, param: click.core.Parameter, raw_value: str | None) -> str | None:
|
|
141
151
|
if raw_value is None:
|
|
142
152
|
return raw_value
|
schemathesis/cli/cassettes.py
CHANGED
|
@@ -290,6 +290,7 @@ def replay(
|
|
|
290
290
|
method: str | None = None,
|
|
291
291
|
request_tls_verify: bool = True,
|
|
292
292
|
request_cert: RequestCert | None = None,
|
|
293
|
+
request_proxy: str | None = None,
|
|
293
294
|
) -> Generator[Replayed, None, None]:
|
|
294
295
|
"""Replay saved interactions."""
|
|
295
296
|
import requests
|
|
@@ -297,9 +298,12 @@ def replay(
|
|
|
297
298
|
session = requests.Session()
|
|
298
299
|
session.verify = request_tls_verify
|
|
299
300
|
session.cert = request_cert
|
|
301
|
+
kwargs = {}
|
|
302
|
+
if request_proxy is not None:
|
|
303
|
+
kwargs["proxies"] = {"all": request_proxy}
|
|
300
304
|
for interaction in filter_cassette(cassette["http_interactions"], id_, status, uri, method):
|
|
301
305
|
request = get_prepared_request(interaction["request"])
|
|
302
|
-
response = session.send(request) # type: ignore
|
|
306
|
+
response = session.send(request, **kwargs) # type: ignore
|
|
303
307
|
yield Replayed(interaction, response)
|
|
304
308
|
|
|
305
309
|
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
from typing import TYPE_CHECKING
|
|
3
|
+
from ...hooks import HookContext, register, unregister
|
|
4
|
+
|
|
5
|
+
if TYPE_CHECKING:
|
|
6
|
+
from ...models import Case
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def install() -> None:
|
|
10
|
+
register(before_add_examples)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def uninstall() -> None:
|
|
14
|
+
unregister(before_add_examples)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def before_add_examples(context: HookContext, examples: list[Case]) -> None:
|
|
18
|
+
if not examples and context.operation is not None:
|
|
19
|
+
from ..._hypothesis import add_single_example
|
|
20
|
+
|
|
21
|
+
strategy = context.operation.as_strategy()
|
|
22
|
+
add_single_example(strategy, examples)
|
schemathesis/exceptions.py
CHANGED
|
@@ -51,7 +51,7 @@ def make_unique_by_key(
|
|
|
51
51
|
|
|
52
52
|
|
|
53
53
|
def deduplicate_failed_checks(
|
|
54
|
-
checks: list[CheckFailed | AssertionError]
|
|
54
|
+
checks: list[CheckFailed | AssertionError],
|
|
55
55
|
) -> Generator[CheckFailed | AssertionError, None, None]:
|
|
56
56
|
"""Keep only unique failed checks."""
|
|
57
57
|
seen = set()
|
|
@@ -462,7 +462,10 @@ def extract_requests_exception_details(exc: RequestException) -> tuple[str, list
|
|
|
462
462
|
message = "Connection failed"
|
|
463
463
|
inner = exc.args[0]
|
|
464
464
|
if isinstance(inner, MaxRetryError) and inner.reason is not None:
|
|
465
|
-
|
|
465
|
+
if ":" not in inner.reason.args[0]:
|
|
466
|
+
reason = inner.reason.args[0]
|
|
467
|
+
else:
|
|
468
|
+
_, reason = inner.reason.args[0].split(":", maxsplit=1)
|
|
466
469
|
extra = [reason.strip()]
|
|
467
470
|
else:
|
|
468
471
|
extra = [" ".join(map(str, inner.args))]
|
schemathesis/models.py
CHANGED
|
@@ -79,11 +79,7 @@ class CaseSource:
|
|
|
79
79
|
elapsed: float
|
|
80
80
|
|
|
81
81
|
def partial_deepcopy(self) -> CaseSource:
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
return self.__class__(
|
|
85
|
-
case=self.case.partial_deepcopy(), response=copy_response(self.response), elapsed=self.elapsed
|
|
86
|
-
)
|
|
82
|
+
return self.__class__(case=self.case.partial_deepcopy(), response=self.response, elapsed=self.elapsed)
|
|
87
83
|
|
|
88
84
|
|
|
89
85
|
def cant_serialize(media_type: str) -> NoReturn: # type: ignore
|
|
@@ -461,7 +457,7 @@ class Case:
|
|
|
461
457
|
"""
|
|
462
458
|
__tracebackhide__ = True
|
|
463
459
|
from .checks import ALL_CHECKS
|
|
464
|
-
from .transports.responses import get_payload,
|
|
460
|
+
from .transports.responses import get_payload, get_reason
|
|
465
461
|
|
|
466
462
|
checks = checks or ALL_CHECKS
|
|
467
463
|
checks = tuple(check for check in checks if check not in excluded_checks)
|
|
@@ -469,9 +465,8 @@ class Case:
|
|
|
469
465
|
failed_checks = []
|
|
470
466
|
for check in chain(checks, additional_checks):
|
|
471
467
|
copied_case = self.partial_deepcopy()
|
|
472
|
-
copied_response = copy_response(response)
|
|
473
468
|
try:
|
|
474
|
-
check(
|
|
469
|
+
check(response, copied_case)
|
|
475
470
|
except AssertionError as exc:
|
|
476
471
|
maybe_set_assertion_message(exc, check.__name__)
|
|
477
472
|
failed_checks.append(exc)
|
schemathesis/runner/__init__.py
CHANGED
|
@@ -323,6 +323,7 @@ def from_schema(
|
|
|
323
323
|
headers: dict[str, Any] | None = None,
|
|
324
324
|
request_timeout: int | None = None,
|
|
325
325
|
request_tls_verify: bool | str = True,
|
|
326
|
+
request_proxy: str | None = None,
|
|
326
327
|
request_cert: RequestCert | None = None,
|
|
327
328
|
seed: int | None = None,
|
|
328
329
|
exit_first: bool = False,
|
|
@@ -373,6 +374,7 @@ def from_schema(
|
|
|
373
374
|
workers_num=workers_num,
|
|
374
375
|
request_timeout=request_timeout,
|
|
375
376
|
request_tls_verify=request_tls_verify,
|
|
377
|
+
request_proxy=request_proxy,
|
|
376
378
|
request_cert=request_cert,
|
|
377
379
|
exit_first=exit_first,
|
|
378
380
|
max_failures=max_failures,
|
|
@@ -442,6 +444,7 @@ def from_schema(
|
|
|
442
444
|
seed=seed,
|
|
443
445
|
request_timeout=request_timeout,
|
|
444
446
|
request_tls_verify=request_tls_verify,
|
|
447
|
+
request_proxy=request_proxy,
|
|
445
448
|
request_cert=request_cert,
|
|
446
449
|
exit_first=exit_first,
|
|
447
450
|
max_failures=max_failures,
|
schemathesis/runner/impl/core.py
CHANGED
|
@@ -40,7 +40,6 @@ from ...internal.result import Ok
|
|
|
40
40
|
from ...models import APIOperation, Case, Check, CheckFunction, Status, TestResult, TestResultSet
|
|
41
41
|
from ...runner import events
|
|
42
42
|
from ...internal.datetime import current_datetime
|
|
43
|
-
from ...transports.responses import copy_response
|
|
44
43
|
from ...schemas import BaseSchema
|
|
45
44
|
from ...stateful import Feedback, Stateful
|
|
46
45
|
from ...targets import Target, TargetContext
|
|
@@ -520,16 +519,15 @@ def run_checks(
|
|
|
520
519
|
context = error.context
|
|
521
520
|
else:
|
|
522
521
|
context = None
|
|
523
|
-
check_results.append(result.add_failure(check_name, copied_case,
|
|
522
|
+
check_results.append(result.add_failure(check_name, copied_case, response, elapsed_time, msg, context))
|
|
524
523
|
|
|
525
524
|
for check in checks:
|
|
526
525
|
check_name = check.__name__
|
|
527
526
|
copied_case = case.partial_deepcopy()
|
|
528
|
-
copied_response = copy_response(response)
|
|
529
527
|
try:
|
|
530
|
-
skip_check = check(
|
|
528
|
+
skip_check = check(response, copied_case)
|
|
531
529
|
if not skip_check:
|
|
532
|
-
check_result = result.add_success(check_name, copied_case,
|
|
530
|
+
check_result = result.add_success(check_name, copied_case, response, elapsed_time)
|
|
533
531
|
check_results.append(check_result)
|
|
534
532
|
except AssertionError as exc:
|
|
535
533
|
add_single_failure(exc)
|
|
@@ -621,6 +619,7 @@ def network_test(
|
|
|
621
619
|
session: requests.Session,
|
|
622
620
|
request_timeout: int | None,
|
|
623
621
|
request_tls_verify: bool,
|
|
622
|
+
request_proxy: str | None,
|
|
624
623
|
request_cert: RequestCert | None,
|
|
625
624
|
store_interactions: bool,
|
|
626
625
|
headers: dict[str, Any] | None,
|
|
@@ -649,6 +648,7 @@ def network_test(
|
|
|
649
648
|
headers,
|
|
650
649
|
feedback,
|
|
651
650
|
request_tls_verify,
|
|
651
|
+
request_proxy,
|
|
652
652
|
request_cert,
|
|
653
653
|
max_response_time,
|
|
654
654
|
)
|
|
@@ -667,6 +667,7 @@ def _network_test(
|
|
|
667
667
|
headers: dict[str, Any] | None,
|
|
668
668
|
feedback: Feedback,
|
|
669
669
|
request_tls_verify: bool,
|
|
670
|
+
request_proxy: str | None,
|
|
670
671
|
request_cert: RequestCert | None,
|
|
671
672
|
max_response_time: int | None,
|
|
672
673
|
) -> requests.Response:
|
|
@@ -680,6 +681,8 @@ def _network_test(
|
|
|
680
681
|
"verify": request_tls_verify,
|
|
681
682
|
"cert": request_cert,
|
|
682
683
|
}
|
|
684
|
+
if request_proxy is not None:
|
|
685
|
+
kwargs["proxies"] = {"all": request_proxy}
|
|
683
686
|
hooks.dispatch("process_call_kwargs", hook_context, case, kwargs)
|
|
684
687
|
response = case.call(**kwargs)
|
|
685
688
|
except CheckFailed as exc:
|
schemathesis/runner/impl/solo.py
CHANGED
|
@@ -15,6 +15,7 @@ class SingleThreadRunner(BaseRunner):
|
|
|
15
15
|
"""Fast runner that runs tests sequentially in the main thread."""
|
|
16
16
|
|
|
17
17
|
request_tls_verify: bool | str = True
|
|
18
|
+
request_proxy: str | None = None
|
|
18
19
|
request_cert: RequestCert | None = None
|
|
19
20
|
|
|
20
21
|
def _execute(
|
|
@@ -42,6 +43,7 @@ class SingleThreadRunner(BaseRunner):
|
|
|
42
43
|
headers=self.headers,
|
|
43
44
|
request_timeout=self.request_timeout,
|
|
44
45
|
request_tls_verify=self.request_tls_verify,
|
|
46
|
+
request_proxy=self.request_proxy,
|
|
45
47
|
request_cert=self.request_cert,
|
|
46
48
|
store_interactions=self.store_interactions,
|
|
47
49
|
dry_run=self.dry_run,
|
|
@@ -224,6 +224,7 @@ class ThreadPoolRunner(BaseRunner):
|
|
|
224
224
|
|
|
225
225
|
workers_num: int = 2
|
|
226
226
|
request_tls_verify: bool | str = True
|
|
227
|
+
request_proxy: str | None = None
|
|
227
228
|
request_cert: RequestCert | None = None
|
|
228
229
|
|
|
229
230
|
def _execute(
|
|
@@ -330,6 +331,7 @@ class ThreadPoolRunner(BaseRunner):
|
|
|
330
331
|
"kwargs": {
|
|
331
332
|
"request_timeout": self.request_timeout,
|
|
332
333
|
"request_tls_verify": self.request_tls_verify,
|
|
334
|
+
"request_proxy": self.request_proxy,
|
|
333
335
|
"request_cert": self.request_cert,
|
|
334
336
|
"store_interactions": self.store_interactions,
|
|
335
337
|
"max_response_time": self.max_response_time,
|
schemathesis/schemas.py
CHANGED
|
@@ -434,7 +434,7 @@ class BaseSchema(Mapping):
|
|
|
434
434
|
|
|
435
435
|
|
|
436
436
|
def operations_to_dict(
|
|
437
|
-
operations: Generator[Result[APIOperation, OperationSchemaError], None, None]
|
|
437
|
+
operations: Generator[Result[APIOperation, OperationSchemaError], None, None],
|
|
438
438
|
) -> dict[str, MethodsDict]:
|
|
439
439
|
output: dict[str, MethodsDict] = {}
|
|
440
440
|
for result in operations:
|
|
@@ -7,6 +7,7 @@ import requests
|
|
|
7
7
|
from hypothesis.strategies import SearchStrategy
|
|
8
8
|
|
|
9
9
|
from ...constants import DEFAULT_RESPONSE_TIMEOUT
|
|
10
|
+
from ...internal.copy import fast_deepcopy
|
|
10
11
|
from ...models import APIOperation, Case
|
|
11
12
|
from ._hypothesis import PARAMETERS, get_case_strategy
|
|
12
13
|
from .constants import LOCATION_TO_CONTAINER
|
|
@@ -109,7 +110,13 @@ def get_static_parameters_from_example(operation: APIOperation) -> dict[str, Any
|
|
|
109
110
|
|
|
110
111
|
def get_static_parameters_from_examples(operation: APIOperation, examples_field: str) -> list[dict[str, Any]]:
|
|
111
112
|
"""Get static parameters from OpenAPI examples keyword."""
|
|
112
|
-
operation_definition = operation.definition.resolved
|
|
113
|
+
operation_definition = fast_deepcopy(operation.definition.resolved)
|
|
114
|
+
# Add shared parameters excluding body
|
|
115
|
+
for parameter in operation.definition.parameters:
|
|
116
|
+
parameters = operation_definition.setdefault("parameters", [])
|
|
117
|
+
if parameter.location == "body" or parameter.name in {parameter["name"] for parameter in parameters}:
|
|
118
|
+
continue
|
|
119
|
+
parameters.append(parameter.definition)
|
|
113
120
|
return merge_examples(
|
|
114
121
|
get_parameter_examples(operation_definition, examples_field),
|
|
115
122
|
get_request_body_examples(operation_definition, examples_field),
|
|
@@ -184,6 +184,7 @@ def from_uri(
|
|
|
184
184
|
)
|
|
185
185
|
|
|
186
186
|
|
|
187
|
+
SCHEMA_INVALID_ERROR = "The provided API schema does not appear to be a valid OpenAPI schema"
|
|
187
188
|
SCHEMA_LOADING_ERROR = "Received unsupported content while expecting a JSON or YAML payload for Open API"
|
|
188
189
|
SCHEMA_SYNTAX_ERROR = "API schema does not appear syntactically valid"
|
|
189
190
|
|
|
@@ -304,6 +305,8 @@ def from_dict(
|
|
|
304
305
|
"""
|
|
305
306
|
from .schemas import OpenApi30, SwaggerV20
|
|
306
307
|
|
|
308
|
+
if not isinstance(raw_schema, dict):
|
|
309
|
+
raise SchemaError(SchemaErrorType.OPEN_API_INVALID_SCHEMA, SCHEMA_INVALID_ERROR)
|
|
307
310
|
_code_sample_style = CodeSampleStyle.from_str(code_sample_style)
|
|
308
311
|
hook_context = HookContext()
|
|
309
312
|
is_openapi_31 = raw_schema.get("openapi", "").startswith("3.1")
|
|
@@ -435,7 +438,7 @@ def _maybe_validate_schema(
|
|
|
435
438
|
except ValidationError as exc:
|
|
436
439
|
raise SchemaError(
|
|
437
440
|
SchemaErrorType.OPEN_API_INVALID_SCHEMA,
|
|
438
|
-
|
|
441
|
+
SCHEMA_INVALID_ERROR,
|
|
439
442
|
extras=[entry for entry in str(exc).splitlines() if entry],
|
|
440
443
|
) from exc
|
|
441
444
|
|
|
@@ -11,7 +11,7 @@ MapFunction = Callable[[Generated], Generated]
|
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
def make_serializer(
|
|
14
|
-
func: Callable[[DefinitionList], Generator[Callable | None, None, None]]
|
|
14
|
+
func: Callable[[DefinitionList], Generator[Callable | None, None, None]],
|
|
15
15
|
) -> Callable[[DefinitionList], Callable | None]:
|
|
16
16
|
"""A maker function to avoid code duplication."""
|
|
17
17
|
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import sys
|
|
4
|
-
from copy import deepcopy, copy
|
|
5
4
|
from json import JSONDecodeError
|
|
6
5
|
from typing import Union, TYPE_CHECKING, NoReturn
|
|
7
6
|
from .._compat import JSONMixin
|
|
@@ -31,31 +30,6 @@ def get_payload(response: GenericResponse) -> str:
|
|
|
31
30
|
return response.get_data(as_text=True)
|
|
32
31
|
|
|
33
32
|
|
|
34
|
-
def copy_response(response: GenericResponse) -> GenericResponse:
|
|
35
|
-
"""Create a copy of the given response as far as it makes sense."""
|
|
36
|
-
from requests import Response
|
|
37
|
-
|
|
38
|
-
if isinstance(response, Response):
|
|
39
|
-
# Hooks are not copyable. Keep them out and copy the rest
|
|
40
|
-
hooks = None
|
|
41
|
-
if response.request is not None:
|
|
42
|
-
hooks = response.request.hooks["response"]
|
|
43
|
-
response.request.hooks["response"] = []
|
|
44
|
-
copied_response = deepcopy(response)
|
|
45
|
-
if hooks is not None:
|
|
46
|
-
copied_response.request.hooks["response"] = hooks
|
|
47
|
-
copied_response.raw = response.raw
|
|
48
|
-
copied_response.verify = getattr(response, "verify", True) # type: ignore[union-attr]
|
|
49
|
-
return copied_response
|
|
50
|
-
|
|
51
|
-
# Can't deepcopy WSGI response due to generators inside (`response.freeze` doesn't completely help)
|
|
52
|
-
if isinstance(response, WSGIResponse):
|
|
53
|
-
response.freeze()
|
|
54
|
-
copied_response = copy(response)
|
|
55
|
-
copied_response.request = deepcopy(response.request)
|
|
56
|
-
return copied_response
|
|
57
|
-
|
|
58
|
-
|
|
59
33
|
def get_reason(status_code: int) -> str:
|
|
60
34
|
if sys.version_info < (3, 9) and status_code == 418:
|
|
61
35
|
# Python 3.8 does not have 418 status in the `HTTPStatus` enum
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: schemathesis
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.23.1
|
|
4
4
|
Summary: Property-based testing framework for Open API and GraphQL based apps
|
|
5
5
|
Project-URL: Documentation, https://schemathesis.readthedocs.io/en/stable/
|
|
6
6
|
Project-URL: Changelog, https://schemathesis.readthedocs.io/en/stable/changelog.html
|
|
@@ -28,6 +28,7 @@ Classifier: Programming Language :: Python :: 3.12
|
|
|
28
28
|
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
29
29
|
Classifier: Topic :: Software Development :: Testing
|
|
30
30
|
Requires-Python: >=3.8
|
|
31
|
+
Requires-Dist: anyio<4
|
|
31
32
|
Requires-Dist: backoff<3.0,>=2.1.2
|
|
32
33
|
Requires-Dist: click<9.0,>=7.0
|
|
33
34
|
Requires-Dist: colorama<1.0,>=0.4
|
|
@@ -42,7 +43,7 @@ Requires-Dist: pytest-subtests<0.8.0,>=0.2.1
|
|
|
42
43
|
Requires-Dist: pytest<8,>=4.6.4
|
|
43
44
|
Requires-Dist: pyyaml<7.0,>=5.1
|
|
44
45
|
Requires-Dist: requests<3,>=2.22
|
|
45
|
-
Requires-Dist: starlette-testclient
|
|
46
|
+
Requires-Dist: starlette-testclient<1
|
|
46
47
|
Requires-Dist: starlette<1,>=0.13
|
|
47
48
|
Requires-Dist: tomli-w<2.0,>=1.0.0
|
|
48
49
|
Requires-Dist: tomli<3.0,>=2.0.1
|
|
@@ -1,33 +1,33 @@
|
|
|
1
1
|
schemathesis/__init__.py,sha256=WW1NBZxmc5jRR0c24xz-ZtTkJMUQG5MOw1MGVRRGc1s,1970
|
|
2
2
|
schemathesis/_compat.py,sha256=VizWR0QAVj4l7WZautNe_zmo3AJ7WBl2zrJQOfJAQtk,1837
|
|
3
3
|
schemathesis/_dependency_versions.py,sha256=P8f-zHGGUb1RRBIwg_QqMLzVTuey8dKKHSeVVmZi6TM,505
|
|
4
|
-
schemathesis/_hypothesis.py,sha256=
|
|
4
|
+
schemathesis/_hypothesis.py,sha256=e0H4Z8qeLbL6H638ubxvGUntWnCoVBlubvZmWEuqjWQ,6810
|
|
5
5
|
schemathesis/_lazy_import.py,sha256=LTki2tM168fCcXet1e6qDoQq8SLgInUA3xjXgi7cXJk,469
|
|
6
6
|
schemathesis/_xml.py,sha256=1ILe404GO6sfUjFqzy44EvYMYvbBirjTH7-b4QiAEik,6781
|
|
7
7
|
schemathesis/auths.py,sha256=09tlGuNGpl3rrsU3ua3UI3rIefqUIpaVtG89U5P6rJo,14731
|
|
8
8
|
schemathesis/checks.py,sha256=jB7E6PfdeLSwMhjLVGmC3WoGCw4DXug_TYP7o0ETrGQ,1572
|
|
9
9
|
schemathesis/code_samples.py,sha256=QFwyA7dmc_ij2FRwfbe0uMRm6j2yeofQ8zXynZV3SZI,4122
|
|
10
10
|
schemathesis/constants.py,sha256=sDvVBhNW1TIvNXFMxicHyNgNTxlng877KZsaS7K_L2Y,2085
|
|
11
|
-
schemathesis/exceptions.py,sha256=
|
|
11
|
+
schemathesis/exceptions.py,sha256=MySsK-H8ZpxJK251avsQlaLsjZCrmLI19tzcU1AQWm8,16715
|
|
12
12
|
schemathesis/failures.py,sha256=cWPaIzou8nv8ioUXImvgT_JyCaj9MOJJS_Nbc6fvhxU,5191
|
|
13
13
|
schemathesis/filters.py,sha256=oaNrVA6VWCSy85k9CkB9JdaVpHFFTcJ831gPnfW3-PU,9334
|
|
14
14
|
schemathesis/graphql.py,sha256=YkoKWY5K8lxp7H3ikAs-IsoDbiPwJvChG7O8p3DgwtI,229
|
|
15
15
|
schemathesis/hooks.py,sha256=cNJgCh7SyLWT1sYDKF5ncDC80ld08CinvKo2IqLMV4g,12396
|
|
16
16
|
schemathesis/lazy.py,sha256=JTXoL5QMFc-_h4OsilVV20jTkXEp8pcW5KmJU1UL-QQ,13302
|
|
17
17
|
schemathesis/loaders.py,sha256=RJnrbf-3vZ7KXmRBkmr3uqWyg0eHzOnONABuudWcTIg,4586
|
|
18
|
-
schemathesis/models.py,sha256=
|
|
18
|
+
schemathesis/models.py,sha256=OgisrUHFg4x79nDJ5A54QYNp0kf9AwqR-fUEKqOv1ew,45705
|
|
19
19
|
schemathesis/parameters.py,sha256=oSsXRpujndiv5_1lWUnBZQEJajqd9AQ8sMxVcxtr7rY,2685
|
|
20
20
|
schemathesis/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
21
21
|
schemathesis/sanitization.py,sha256=WSV_MB5YRrYkp1pQRPHrzsidqsKcqYZiq64N9grKobo,8956
|
|
22
|
-
schemathesis/schemas.py,sha256=
|
|
22
|
+
schemathesis/schemas.py,sha256=VaO3Mb9bx8n1Ia57Epyr1Ah-8loOs6HNXAnmHe_H9ig,16366
|
|
23
23
|
schemathesis/serializers.py,sha256=c-LkIJuuc4D5owoJREm7KQQd3AgcsENPIXEEyiNcevY,11109
|
|
24
24
|
schemathesis/targets.py,sha256=tzp7VZ2-7g2nZHCooRgFzTMtOVcbl0rvtNR421hQthA,1162
|
|
25
25
|
schemathesis/throttling.py,sha256=QQcS7TFpXHavUjm0kdFaCcCRhAGlgQ4y3XIbkdRoW20,1079
|
|
26
26
|
schemathesis/types.py,sha256=AglR5M0bce-YXeDRkweToXTP0GjNOWVjS_mIsxLobwc,919
|
|
27
27
|
schemathesis/utils.py,sha256=tjH1jkMseEXV6vYg8ylJpYd7sRprnpbmXqdWg20ZaGE,4939
|
|
28
|
-
schemathesis/cli/__init__.py,sha256=
|
|
29
|
-
schemathesis/cli/callbacks.py,sha256=
|
|
30
|
-
schemathesis/cli/cassettes.py,sha256
|
|
28
|
+
schemathesis/cli/__init__.py,sha256=mLAjbvhkrRwooGJ74BihfLcO241pbRnx3u12GRkjUZY,60312
|
|
29
|
+
schemathesis/cli/callbacks.py,sha256=UAlHDW_zYUzuVlpA01GarsApOtij4PaKJpPp4lboqJk,12770
|
|
30
|
+
schemathesis/cli/cassettes.py,sha256=gPPvcuIj1WnoP-yqqvGCJNe49SWlDFu8OdQkOmY453A,12988
|
|
31
31
|
schemathesis/cli/constants.py,sha256=x9zrVVFBTOO1HogPeqRO5Mvdgs3y1kiah9R5nPRTIyw,1347
|
|
32
32
|
schemathesis/cli/context.py,sha256=QrNr-5-7Z8TWGNzlD87hJZau6wU--ZboYHN92cyg82k,1652
|
|
33
33
|
schemathesis/cli/debug.py,sha256=PDEa-oHyz5bZ8aYjRYARwQaCv_AC6HM_L43LJfe4vUM,657
|
|
@@ -40,7 +40,8 @@ schemathesis/cli/output/default.py,sha256=g2SBeZWRspBRlSqYkDrQvkFVVVosfthbaGa2wM
|
|
|
40
40
|
schemathesis/cli/output/short.py,sha256=Ui21Ko7eY5igs4CyNFb88-KRXKmMjz776l9aCHpYq8o,1628
|
|
41
41
|
schemathesis/contrib/__init__.py,sha256=FH8NL8NXgSKBFOF8Jy_EB6T4CJEaiM-tmDhz16B2o4k,187
|
|
42
42
|
schemathesis/contrib/unique_data.py,sha256=XttUSDVzD7-231jC7kqMi-9Xmu2aP8ljjDYINMOoHJk,736
|
|
43
|
-
schemathesis/contrib/openapi/__init__.py,sha256=
|
|
43
|
+
schemathesis/contrib/openapi/__init__.py,sha256=YMj_b2f3ohGwEt8QQXlxBT60wqvdCFS6516I4EHWVNM,217
|
|
44
|
+
schemathesis/contrib/openapi/fill_missing_examples.py,sha256=dY1ygG41PWmITOegdv2uwpDm-UiBcyDSOuGCZMGxYAg,582
|
|
44
45
|
schemathesis/contrib/openapi/formats/__init__.py,sha256=OpHWPW8MkTLVv83QXPYY1HVLflhmSH49hSVefm1oVV0,111
|
|
45
46
|
schemathesis/contrib/openapi/formats/uuid.py,sha256=SsTH_bInSXnlGLNyYLmwUfvafVnVOTHdmhmKytQVoUQ,390
|
|
46
47
|
schemathesis/experimental/__init__.py,sha256=vWj64BquX0mbCSd9iDBlwMb1dfm3zHJjAWBQiozRnxw,2474
|
|
@@ -61,13 +62,13 @@ schemathesis/internal/jsonschema.py,sha256=eQEkBLTdJ__U7Z0XYXB_RVBQJ4texfFO0AaOo
|
|
|
61
62
|
schemathesis/internal/result.py,sha256=Og_ZfwwQ6JFmW79ExC1ndjVMIOHJB7o9XtrfhYIjOOs,461
|
|
62
63
|
schemathesis/internal/transformation.py,sha256=ZNEtL8ezryLdP9-of4eSRBMSjjV_lBQ5DZZfoPGZFEU,449
|
|
63
64
|
schemathesis/internal/validation.py,sha256=ZCUrjB_QFriyMKo4V2HgZknMnywOtpwlcEADQiWRJFs,591
|
|
64
|
-
schemathesis/runner/__init__.py,sha256=
|
|
65
|
+
schemathesis/runner/__init__.py,sha256=hbdrQojyIWMZo0e2VgJzJjvjWMPM-qwRLamFXofaQ94,19947
|
|
65
66
|
schemathesis/runner/events.py,sha256=whpHGXcT7esnJ2bNsFirUrrELI3GtDAAoJ7VVTty2mc,9416
|
|
66
67
|
schemathesis/runner/serialization.py,sha256=MHgSlsqIWAHqzXtpZABEEr3ARfd7sdE-GRaNP-r7L8Y,15495
|
|
67
68
|
schemathesis/runner/impl/__init__.py,sha256=1E2iME8uthYPBh9MjwVBCTFV-P3fi7AdphCCoBBspjs,199
|
|
68
|
-
schemathesis/runner/impl/core.py,sha256=
|
|
69
|
-
schemathesis/runner/impl/solo.py,sha256
|
|
70
|
-
schemathesis/runner/impl/threadpool.py,sha256=
|
|
69
|
+
schemathesis/runner/impl/core.py,sha256=34n0qaV1ktfesO5ljLNrs3U14q7RVCaY_pSKNNQ8Ogg,33051
|
|
70
|
+
schemathesis/runner/impl/solo.py,sha256=Y_tNhVBVxcuxv65hN0FjxLlVSC41ebHMOM1xSzVrNk8,3358
|
|
71
|
+
schemathesis/runner/impl/threadpool.py,sha256=2-2Wvw7msezZtenZY5vU_x3FGLLVlH-ywvhU9hTwAAo,15073
|
|
71
72
|
schemathesis/service/__init__.py,sha256=cDVTCFD1G-vvhxZkJUwiToTAEQ-0ByIoqwXvJBCf_V8,472
|
|
72
73
|
schemathesis/service/auth.py,sha256=AiZXvSNwz1Hi3fn-OCp6XD-E4GAMDlfcX8fORJ8_dLo,445
|
|
73
74
|
schemathesis/service/ci.py,sha256=Nke_GHtUlbJtZA-7JmjD1Nu4aKBCtkUo8AwFwm38qpk,6781
|
|
@@ -92,16 +93,16 @@ schemathesis/specs/openapi/checks.py,sha256=1WB_UGNqptfJThWLUNbds1Q-IzOGbbHCOYPI
|
|
|
92
93
|
schemathesis/specs/openapi/constants.py,sha256=JqM_FHOenqS_MuUE9sxVQ8Hnw0DNM8cnKDwCwPLhID4,783
|
|
93
94
|
schemathesis/specs/openapi/converter.py,sha256=rhzGRJNW6o9CeKLanVm_VIlXJQEWCpQ60XZobSpnplY,2677
|
|
94
95
|
schemathesis/specs/openapi/definitions.py,sha256=t5xffHLBnSgptBdDkSqYN1OfT-DaXoeUw2tIgNEe2q8,94057
|
|
95
|
-
schemathesis/specs/openapi/examples.py,sha256=
|
|
96
|
+
schemathesis/specs/openapi/examples.py,sha256=QIwFrciKUFz-cxbrXqBdsKCLt01XZo8p3z8m3JK28XI,9475
|
|
96
97
|
schemathesis/specs/openapi/filters.py,sha256=Ei-QTFcGCvGSIunT-GYQrtqzB-kqvUePOcUuC7B7mT8,1436
|
|
97
98
|
schemathesis/specs/openapi/formats.py,sha256=ZT-10kOWE4Xcc_OXchjhPxpjA2iq4SXG2a75Lnib03w,1146
|
|
98
99
|
schemathesis/specs/openapi/links.py,sha256=YryI35djHOhTikRV3FLafy_jhYFypF7E8Yb6dg9ksWc,14575
|
|
99
|
-
schemathesis/specs/openapi/loaders.py,sha256=
|
|
100
|
+
schemathesis/specs/openapi/loaders.py,sha256=2s9pF8HdIRcz4GwSLy3XJli_FZaeo9zontbat-SFOws,23613
|
|
100
101
|
schemathesis/specs/openapi/parameters.py,sha256=GbvxMQ0vg2-HvLrKr1dBtOwSNEXkAF6Hj-hqX9qdTNs,15014
|
|
101
102
|
schemathesis/specs/openapi/references.py,sha256=pnn0aQbP2Kz0xwZE0gVa9nYGyJkXA2jRYoNMFcRf3TQ,8656
|
|
102
103
|
schemathesis/specs/openapi/schemas.py,sha256=s81MBsGVoc3WILCYR8DjNvmN6OotSsg27YFK5iqtdt8,46220
|
|
103
104
|
schemathesis/specs/openapi/security.py,sha256=lNRD4RSYe341f_ayhl_bQuYlFbGzx4luhXi6qJwzrOY,6495
|
|
104
|
-
schemathesis/specs/openapi/serialization.py,sha256=
|
|
105
|
+
schemathesis/specs/openapi/serialization.py,sha256=jajqowTIiyEVWEx-Gy4ZinXZewNg0n_ipsGzz7JXP7c,11383
|
|
105
106
|
schemathesis/specs/openapi/utils.py,sha256=gmW4v6o6sZQifajfPquhFeWmZWGQM89mOOBYZvjnE7g,741
|
|
106
107
|
schemathesis/specs/openapi/validation.py,sha256=UJWtW7VTRyMbbBHMRhMwNSUn92k1Hnp4p7IIVqCvqiI,998
|
|
107
108
|
schemathesis/specs/openapi/expressions/__init__.py,sha256=7TZeRPpCPt0Bjzs5L--AkQnnIbDgTRnpkgYeJKma5Bc,660
|
|
@@ -122,9 +123,9 @@ schemathesis/transports/__init__.py,sha256=Wix_WnOxZlDFD_XFqPMIqz_3TAc7Xda6UGicO
|
|
|
122
123
|
schemathesis/transports/auth.py,sha256=ZKFku9gjhIG6445qNC2p_64Yt9Iz_4azbvja8AMptBk,404
|
|
123
124
|
schemathesis/transports/content_types.py,sha256=bgep10TeCT9e0GfOxVFBOFmrmdZ3t4tG8MLE0SJN5D0,1297
|
|
124
125
|
schemathesis/transports/headers.py,sha256=EDxpm8su0AuhyqZUkMex-OFZMAJN_5NHah7fDT2HDZE,989
|
|
125
|
-
schemathesis/transports/responses.py,sha256=
|
|
126
|
-
schemathesis-3.
|
|
127
|
-
schemathesis-3.
|
|
128
|
-
schemathesis-3.
|
|
129
|
-
schemathesis-3.
|
|
130
|
-
schemathesis-3.
|
|
126
|
+
schemathesis/transports/responses.py,sha256=w-l0bQrPuAXKURtDazm9ptuGVcJgEW-QYWYpYblFEyM,1347
|
|
127
|
+
schemathesis-3.23.1.dist-info/METADATA,sha256=HJD__7N6XCehhfzauNlzscwE42RpyoyPC3l4Tpzue24,15611
|
|
128
|
+
schemathesis-3.23.1.dist-info/WHEEL,sha256=hKi7AIIx6qfnsRbr087vpeJnrVUuDokDHZacPPMW7-Y,87
|
|
129
|
+
schemathesis-3.23.1.dist-info/entry_points.txt,sha256=VHyLcOG7co0nOeuk8WjgpRETk5P1E2iCLrn26Zkn5uk,158
|
|
130
|
+
schemathesis-3.23.1.dist-info/licenses/LICENSE,sha256=PsPYgrDhZ7g9uwihJXNG-XVb55wj2uYhkl2DD8oAzY0,1103
|
|
131
|
+
schemathesis-3.23.1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|