Skip to content

Commit 0f5ac8e

Browse files
authored
Merge pull request #686 from python-openapi/feature/openapi-spec-validator-remove-deprecations
Specification validation as part of shortcuts
2 parents 0abae09 + 1752d35 commit 0f5ac8e

File tree

15 files changed

+137
-32
lines changed

15 files changed

+137
-32
lines changed

docs/customizations.rst

+6-7
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,17 @@ Customizations
44
Specification validation
55
------------------------
66

7-
By default, the provided specification is validated on ``Spec`` object creation time.
7+
By default, the specified specification is also validated.
88

99
If you know you have a valid specification already, disabling the validator can improve the performance.
1010

1111
.. code-block:: python
12-
:emphasize-lines: 5
12+
:emphasize-lines: 4
1313
14-
from openapi_core import Spec
15-
16-
spec = Spec.from_dict(
17-
spec_dict,
18-
validator=None,
14+
validate_request(
15+
request,
16+
spec=spec,
17+
spec_validator_cls=None,
1918
)
2019
2120
Media type deserializers

openapi_core/shortcuts.py

+8
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ def unmarshal_apicall_request(
108108
if not issubclass(cls, RequestUnmarshaller):
109109
raise TypeError("'cls' argument is not type of RequestUnmarshaller")
110110
v = cls(spec, base_url=base_url, **unmarshaller_kwargs)
111+
v.check_spec(spec)
111112
result = v.unmarshal(request)
112113
result.raise_for_errors()
113114
return result
@@ -134,6 +135,7 @@ def unmarshal_webhook_request(
134135
"'cls' argument is not type of WebhookRequestUnmarshaller"
135136
)
136137
v = cls(spec, base_url=base_url, **unmarshaller_kwargs)
138+
v.check_spec(spec)
137139
result = v.unmarshal(request)
138140
result.raise_for_errors()
139141
return result
@@ -198,6 +200,7 @@ def unmarshal_apicall_response(
198200
if not issubclass(cls, ResponseUnmarshaller):
199201
raise TypeError("'cls' argument is not type of ResponseUnmarshaller")
200202
v = cls(spec, base_url=base_url, **unmarshaller_kwargs)
203+
v.check_spec(spec)
201204
result = v.unmarshal(request, response)
202205
result.raise_for_errors()
203206
return result
@@ -227,6 +230,7 @@ def unmarshal_webhook_response(
227230
"'cls' argument is not type of WebhookResponseUnmarshaller"
228231
)
229232
v = cls(spec, base_url=base_url, **unmarshaller_kwargs)
233+
v.check_spec(spec)
230234
result = v.unmarshal(request, response)
231235
result.raise_for_errors()
232236
return result
@@ -378,6 +382,7 @@ def validate_apicall_request(
378382
if not issubclass(cls, RequestValidator):
379383
raise TypeError("'cls' argument is not type of RequestValidator")
380384
v = cls(spec, base_url=base_url, **validator_kwargs)
385+
v.check_spec(spec)
381386
return v.validate(request)
382387

383388

@@ -402,6 +407,7 @@ def validate_webhook_request(
402407
"'cls' argument is not type of WebhookRequestValidator"
403408
)
404409
v = cls(spec, base_url=base_url, **validator_kwargs)
410+
v.check_spec(spec)
405411
return v.validate(request)
406412

407413

@@ -425,6 +431,7 @@ def validate_apicall_response(
425431
if not issubclass(cls, ResponseValidator):
426432
raise TypeError("'cls' argument is not type of ResponseValidator")
427433
v = cls(spec, base_url=base_url, **validator_kwargs)
434+
v.check_spec(spec)
428435
return v.validate(request, response)
429436

430437

@@ -452,4 +459,5 @@ def validate_webhook_response(
452459
"'cls' argument is not type of WebhookResponseValidator"
453460
)
454461
v = cls(spec, base_url=base_url, **validator_kwargs)
462+
v.check_spec(spec)
455463
return v.validate(request, response)

openapi_core/unmarshalling/request/protocols.py

+6
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ class RequestUnmarshaller(Protocol):
1515
def __init__(self, spec: SchemaPath, base_url: Optional[str] = None):
1616
...
1717

18+
def check_spec(self, spec: SchemaPath) -> None:
19+
...
20+
1821
def unmarshal(
1922
self,
2023
request: Request,
@@ -27,6 +30,9 @@ class WebhookRequestUnmarshaller(Protocol):
2730
def __init__(self, spec: SchemaPath, base_url: Optional[str] = None):
2831
...
2932

33+
def check_spec(self, spec: SchemaPath) -> None:
34+
...
35+
3036
def unmarshal(
3137
self,
3238
request: WebhookRequest,

openapi_core/unmarshalling/request/unmarshallers.py

+4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from typing import Optional
22

33
from jsonschema_path import SchemaPath
4+
from openapi_spec_validator.validation.types import SpecValidatorType
45

56
from openapi_core.casting.schemas import schema_casters_factory
67
from openapi_core.casting.schemas.factories import SchemaCastersFactory
@@ -88,6 +89,7 @@ def __init__(
8889
style_deserializers_factory: StyleDeserializersFactory = style_deserializers_factory,
8990
media_type_deserializers_factory: MediaTypeDeserializersFactory = media_type_deserializers_factory,
9091
schema_validators_factory: Optional[SchemaValidatorsFactory] = None,
92+
spec_validator_cls: Optional[SpecValidatorType] = None,
9193
format_validators: Optional[FormatValidatorsDict] = None,
9294
extra_format_validators: Optional[FormatValidatorsDict] = None,
9395
extra_media_type_deserializers: Optional[
@@ -108,6 +110,7 @@ def __init__(
108110
style_deserializers_factory=style_deserializers_factory,
109111
media_type_deserializers_factory=media_type_deserializers_factory,
110112
schema_validators_factory=schema_validators_factory,
113+
spec_validator_cls=spec_validator_cls,
111114
format_validators=format_validators,
112115
extra_format_validators=extra_format_validators,
113116
extra_media_type_deserializers=extra_media_type_deserializers,
@@ -123,6 +126,7 @@ def __init__(
123126
style_deserializers_factory=style_deserializers_factory,
124127
media_type_deserializers_factory=media_type_deserializers_factory,
125128
schema_validators_factory=schema_validators_factory,
129+
spec_validator_cls=spec_validator_cls,
126130
format_validators=format_validators,
127131
extra_format_validators=extra_format_validators,
128132
extra_media_type_deserializers=extra_media_type_deserializers,

openapi_core/unmarshalling/response/protocols.py

+6
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ class ResponseUnmarshaller(Protocol):
2020
def __init__(self, spec: SchemaPath, base_url: Optional[str] = None):
2121
...
2222

23+
def check_spec(self, spec: SchemaPath) -> None:
24+
...
25+
2326
def unmarshal(
2427
self,
2528
request: Request,
@@ -33,6 +36,9 @@ class WebhookResponseUnmarshaller(Protocol):
3336
def __init__(self, spec: SchemaPath, base_url: Optional[str] = None):
3437
...
3538

39+
def check_spec(self, spec: SchemaPath) -> None:
40+
...
41+
3642
def unmarshal(
3743
self,
3844
request: WebhookRequest,

openapi_core/unmarshalling/unmarshallers.py

+3
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from typing import Tuple
55

66
from jsonschema_path import SchemaPath
7+
from openapi_spec_validator.validation.types import SpecValidatorType
78

89
from openapi_core.casting.schemas import schema_casters_factory
910
from openapi_core.casting.schemas.factories import SchemaCastersFactory
@@ -42,6 +43,7 @@ def __init__(
4243
style_deserializers_factory: StyleDeserializersFactory = style_deserializers_factory,
4344
media_type_deserializers_factory: MediaTypeDeserializersFactory = media_type_deserializers_factory,
4445
schema_validators_factory: Optional[SchemaValidatorsFactory] = None,
46+
spec_validator_cls: Optional[SpecValidatorType] = None,
4547
format_validators: Optional[FormatValidatorsDict] = None,
4648
extra_format_validators: Optional[FormatValidatorsDict] = None,
4749
extra_media_type_deserializers: Optional[
@@ -64,6 +66,7 @@ def __init__(
6466
style_deserializers_factory=style_deserializers_factory,
6567
media_type_deserializers_factory=media_type_deserializers_factory,
6668
schema_validators_factory=schema_validators_factory,
69+
spec_validator_cls=spec_validator_cls,
6770
format_validators=format_validators,
6871
extra_format_validators=extra_format_validators,
6972
extra_media_type_deserializers=extra_media_type_deserializers,

openapi_core/validation/request/protocols.py

+6
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ class RequestValidator(Protocol):
1515
def __init__(self, spec: SchemaPath, base_url: Optional[str] = None):
1616
...
1717

18+
def check_spec(self, spec: SchemaPath) -> None:
19+
...
20+
1821
def iter_errors(
1922
self,
2023
request: Request,
@@ -33,6 +36,9 @@ class WebhookRequestValidator(Protocol):
3336
def __init__(self, spec: SchemaPath, base_url: Optional[str] = None):
3437
...
3538

39+
def check_spec(self, spec: SchemaPath) -> None:
40+
...
41+
3642
def iter_errors(
3743
self,
3844
request: WebhookRequest,

openapi_core/validation/request/validators.py

+17
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66
from typing import Optional
77

88
from jsonschema_path import SchemaPath
9+
from openapi_spec_validator import OpenAPIV30SpecValidator
10+
from openapi_spec_validator import OpenAPIV31SpecValidator
11+
from openapi_spec_validator.validation.types import SpecValidatorType
912

1013
from openapi_core.casting.schemas import schema_casters_factory
1114
from openapi_core.casting.schemas.factories import SchemaCastersFactory
@@ -70,6 +73,7 @@ def __init__(
7073
style_deserializers_factory: StyleDeserializersFactory = style_deserializers_factory,
7174
media_type_deserializers_factory: MediaTypeDeserializersFactory = media_type_deserializers_factory,
7275
schema_validators_factory: Optional[SchemaValidatorsFactory] = None,
76+
spec_validator_cls: Optional[SpecValidatorType] = None,
7377
format_validators: Optional[FormatValidatorsDict] = None,
7478
extra_format_validators: Optional[FormatValidatorsDict] = None,
7579
extra_media_type_deserializers: Optional[
@@ -84,6 +88,7 @@ def __init__(
8488
style_deserializers_factory=style_deserializers_factory,
8589
media_type_deserializers_factory=media_type_deserializers_factory,
8690
schema_validators_factory=schema_validators_factory,
91+
spec_validator_cls=spec_validator_cls,
8792
format_validators=format_validators,
8893
extra_format_validators=extra_format_validators,
8994
extra_media_type_deserializers=extra_media_type_deserializers,
@@ -387,53 +392,65 @@ def iter_errors(self, request: WebhookRequest) -> Iterator[Exception]:
387392

388393

389394
class V30RequestBodyValidator(APICallRequestBodyValidator):
395+
spec_validator_cls = OpenAPIV30SpecValidator
390396
schema_validators_factory = oas30_write_schema_validators_factory
391397

392398

393399
class V30RequestParametersValidator(APICallRequestParametersValidator):
400+
spec_validator_cls = OpenAPIV30SpecValidator
394401
schema_validators_factory = oas30_write_schema_validators_factory
395402

396403

397404
class V30RequestSecurityValidator(APICallRequestSecurityValidator):
405+
spec_validator_cls = OpenAPIV30SpecValidator
398406
schema_validators_factory = oas30_write_schema_validators_factory
399407

400408

401409
class V30RequestValidator(APICallRequestValidator):
410+
spec_validator_cls = OpenAPIV30SpecValidator
402411
schema_validators_factory = oas30_write_schema_validators_factory
403412

404413

405414
class V31RequestBodyValidator(APICallRequestBodyValidator):
415+
spec_validator_cls = OpenAPIV31SpecValidator
406416
schema_validators_factory = oas31_schema_validators_factory
407417

408418

409419
class V31RequestParametersValidator(APICallRequestParametersValidator):
420+
spec_validator_cls = OpenAPIV31SpecValidator
410421
schema_validators_factory = oas31_schema_validators_factory
411422

412423

413424
class V31RequestSecurityValidator(APICallRequestSecurityValidator):
425+
spec_validator_cls = OpenAPIV31SpecValidator
414426
schema_validators_factory = oas31_schema_validators_factory
415427

416428

417429
class V31RequestValidator(APICallRequestValidator):
430+
spec_validator_cls = OpenAPIV31SpecValidator
418431
schema_validators_factory = oas31_schema_validators_factory
419432
path_finder_cls = WebhookPathFinder
420433

421434

422435
class V31WebhookRequestBodyValidator(WebhookRequestBodyValidator):
436+
spec_validator_cls = OpenAPIV31SpecValidator
423437
schema_validators_factory = oas31_schema_validators_factory
424438
path_finder_cls = WebhookPathFinder
425439

426440

427441
class V31WebhookRequestParametersValidator(WebhookRequestParametersValidator):
442+
spec_validator_cls = OpenAPIV31SpecValidator
428443
schema_validators_factory = oas31_schema_validators_factory
429444
path_finder_cls = WebhookPathFinder
430445

431446

432447
class V31WebhookRequestSecurityValidator(WebhookRequestSecurityValidator):
448+
spec_validator_cls = OpenAPIV31SpecValidator
433449
schema_validators_factory = oas31_schema_validators_factory
434450
path_finder_cls = WebhookPathFinder
435451

436452

437453
class V31WebhookRequestValidator(WebhookRequestValidator):
454+
spec_validator_cls = OpenAPIV31SpecValidator
438455
schema_validators_factory = oas31_schema_validators_factory
439456
path_finder_cls = WebhookPathFinder

openapi_core/validation/response/protocols.py

+6
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ class ResponseValidator(Protocol):
1616
def __init__(self, spec: SchemaPath, base_url: Optional[str] = None):
1717
...
1818

19+
def check_spec(self, spec: SchemaPath) -> None:
20+
...
21+
1922
def iter_errors(
2023
self,
2124
request: Request,
@@ -36,6 +39,9 @@ class WebhookResponseValidator(Protocol):
3639
def __init__(self, spec: SchemaPath, base_url: Optional[str] = None):
3740
...
3841

42+
def check_spec(self, spec: SchemaPath) -> None:
43+
...
44+
3945
def iter_errors(
4046
self,
4147
request: WebhookRequest,

openapi_core/validation/response/validators.py

+11
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
from typing import Mapping
88

99
from jsonschema_path import SchemaPath
10+
from openapi_spec_validator import OpenAPIV30SpecValidator
11+
from openapi_spec_validator import OpenAPIV31SpecValidator
1012

1113
from openapi_core.exceptions import OpenAPIError
1214
from openapi_core.protocols import Request
@@ -330,36 +332,45 @@ def iter_errors(
330332

331333

332334
class V30ResponseDataValidator(APICallResponseDataValidator):
335+
spec_validator_cls = OpenAPIV30SpecValidator
333336
schema_validators_factory = oas30_read_schema_validators_factory
334337

335338

336339
class V30ResponseHeadersValidator(APICallResponseHeadersValidator):
340+
spec_validator_cls = OpenAPIV30SpecValidator
337341
schema_validators_factory = oas30_read_schema_validators_factory
338342

339343

340344
class V30ResponseValidator(APICallResponseValidator):
345+
spec_validator_cls = OpenAPIV30SpecValidator
341346
schema_validators_factory = oas30_read_schema_validators_factory
342347

343348

344349
class V31ResponseDataValidator(APICallResponseDataValidator):
350+
spec_validator_cls = OpenAPIV31SpecValidator
345351
schema_validators_factory = oas31_schema_validators_factory
346352

347353

348354
class V31ResponseHeadersValidator(APICallResponseHeadersValidator):
355+
spec_validator_cls = OpenAPIV31SpecValidator
349356
schema_validators_factory = oas31_schema_validators_factory
350357

351358

352359
class V31ResponseValidator(APICallResponseValidator):
360+
spec_validator_cls = OpenAPIV31SpecValidator
353361
schema_validators_factory = oas31_schema_validators_factory
354362

355363

356364
class V31WebhookResponseDataValidator(WebhookResponseDataValidator):
365+
spec_validator_cls = OpenAPIV31SpecValidator
357366
schema_validators_factory = oas31_schema_validators_factory
358367

359368

360369
class V31WebhookResponseHeadersValidator(WebhookResponseHeadersValidator):
370+
spec_validator_cls = OpenAPIV31SpecValidator
361371
schema_validators_factory = oas31_schema_validators_factory
362372

363373

364374
class V31WebhookResponseValidator(WebhookResponseValidator):
375+
spec_validator_cls = OpenAPIV31SpecValidator
365376
schema_validators_factory = oas31_schema_validators_factory

0 commit comments

Comments
 (0)