Skip to content

Commit 300266e

Browse files
committed
Predefined openapi validators
1 parent 0dbcfcd commit 300266e

33 files changed

+635
-611
lines changed

openapi_core/__init__.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
"""OpenAPI core module"""
22
from openapi_core.spec import OpenAPIv30Spec
3-
from openapi_core.validation.request.shortcuts import validate_request
43
from openapi_core.validation.request.validators import RequestBodyValidator
54
from openapi_core.validation.request.validators import (
65
RequestParametersValidator,
76
)
87
from openapi_core.validation.request.validators import RequestSecurityValidator
98
from openapi_core.validation.request.validators import RequestValidator
10-
from openapi_core.validation.response.shortcuts import validate_response
119
from openapi_core.validation.response.validators import ResponseDataValidator
1210
from openapi_core.validation.response.validators import (
1311
ResponseHeadersValidator,
1412
)
1513
from openapi_core.validation.response.validators import ResponseValidator
14+
from openapi_core.validation.shortcuts import validate_request
15+
from openapi_core.validation.shortcuts import validate_response
1616

1717
__author__ = "Artur Maciag"
1818
__email__ = "[email protected]"

openapi_core/contrib/django/handlers.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
"""OpenAPI core contrib django handlers module"""
22
from django.http import JsonResponse
33

4-
from openapi_core.exceptions import MissingRequiredParameter
54
from openapi_core.templating.media_types.exceptions import MediaTypeNotFound
65
from openapi_core.templating.paths.exceptions import OperationNotFound
76
from openapi_core.templating.paths.exceptions import PathNotFound
87
from openapi_core.templating.paths.exceptions import ServerNotFound
98
from openapi_core.validation.exceptions import InvalidSecurity
9+
from openapi_core.validation.exceptions import MissingRequiredParameter
1010

1111

1212
class DjangoOpenAPIErrorsHandler:

openapi_core/contrib/django/middlewares.py

+5-7
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
from openapi_core.contrib.django.requests import DjangoOpenAPIRequest
77
from openapi_core.contrib.django.responses import DjangoOpenAPIResponse
88
from openapi_core.validation.processors import OpenAPIProcessor
9-
from openapi_core.validation.request.validators import RequestValidator
10-
from openapi_core.validation.response.validators import ResponseValidator
9+
from openapi_core.validation.request import openapi_request_validator
10+
from openapi_core.validation.response import openapi_response_validator
1111

1212

1313
class DjangoOpenAPIMiddleware:
@@ -22,15 +22,13 @@ def __init__(self, get_response):
2222
if not hasattr(settings, "OPENAPI_SPEC"):
2323
raise ImproperlyConfigured("OPENAPI_SPEC not defined in settings")
2424

25-
request_validator = RequestValidator(settings.OPENAPI_SPEC)
26-
response_validator = ResponseValidator(settings.OPENAPI_SPEC)
2725
self.validation_processor = OpenAPIProcessor(
28-
request_validator, response_validator
26+
openapi_request_validator, openapi_response_validator
2927
)
3028

3129
def __call__(self, request):
3230
openapi_request = self._get_openapi_request(request)
33-
req_result = self.validation_processor.process_request(openapi_request)
31+
req_result = self.validation_processor.process_request(settings.OPENAPI_SPEC, openapi_request)
3432
if req_result.errors:
3533
response = self._handle_request_errors(req_result, request)
3634
else:
@@ -39,7 +37,7 @@ def __call__(self, request):
3937

4038
openapi_response = self._get_openapi_response(response)
4139
resp_result = self.validation_processor.process_response(
42-
openapi_request, openapi_response
40+
settings.OPENAPI_SPEC, openapi_request, openapi_response
4341
)
4442
if resp_result.errors:
4543
return self._handle_response_errors(resp_result, request, response)

openapi_core/contrib/falcon/handlers.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,12 @@
44
from falcon import status_codes
55
from falcon.constants import MEDIA_JSON
66

7-
from openapi_core.exceptions import MissingRequiredParameter
87
from openapi_core.templating.media_types.exceptions import MediaTypeNotFound
98
from openapi_core.templating.paths.exceptions import OperationNotFound
109
from openapi_core.templating.paths.exceptions import PathNotFound
1110
from openapi_core.templating.paths.exceptions import ServerNotFound
1211
from openapi_core.validation.exceptions import InvalidSecurity
12+
from openapi_core.validation.exceptions import MissingRequiredParameter
1313

1414

1515
class FalconOpenAPIErrorsHandler:

openapi_core/contrib/falcon/middlewares.py

+8-7
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
from openapi_core.contrib.falcon.requests import FalconOpenAPIRequest
55
from openapi_core.contrib.falcon.responses import FalconOpenAPIResponse
66
from openapi_core.validation.processors import OpenAPIProcessor
7-
from openapi_core.validation.request.validators import RequestValidator
8-
from openapi_core.validation.response.validators import ResponseValidator
7+
from openapi_core.validation.request import openapi_request_validator
8+
from openapi_core.validation.response import openapi_response_validator
99

1010

1111
class FalconOpenAPIMiddleware:
@@ -16,11 +16,13 @@ class FalconOpenAPIMiddleware:
1616

1717
def __init__(
1818
self,
19+
spec,
1920
validation_processor,
2021
request_class=None,
2122
response_class=None,
2223
errors_handler=None,
2324
):
25+
self.spec = spec
2426
self.validation_processor = validation_processor
2527
self.request_class = request_class or self.request_class
2628
self.response_class = response_class or self.response_class
@@ -34,12 +36,11 @@ def from_spec(
3436
response_class=None,
3537
errors_handler=None,
3638
):
37-
request_validator = RequestValidator(spec)
38-
response_validator = ResponseValidator(spec)
3939
validation_processor = OpenAPIProcessor(
40-
request_validator, response_validator
40+
openapi_request_validator, openapi_response_validator
4141
)
4242
return cls(
43+
spec,
4344
validation_processor,
4445
request_class=request_class,
4546
response_class=response_class,
@@ -76,9 +77,9 @@ def _get_openapi_response(self, response):
7677
return self.response_class(response)
7778

7879
def _process_openapi_request(self, openapi_request):
79-
return self.validation_processor.process_request(openapi_request)
80+
return self.validation_processor.process_request(self.spec, openapi_request)
8081

8182
def _process_openapi_response(self, opneapi_request, openapi_response):
8283
return self.validation_processor.process_response(
83-
opneapi_request, openapi_response
84+
self.spec, opneapi_request, openapi_response
8485
)

openapi_core/contrib/flask/decorators.py

+7-6
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,14 @@
44
from openapi_core.contrib.flask.requests import FlaskOpenAPIRequest
55
from openapi_core.contrib.flask.responses import FlaskOpenAPIResponse
66
from openapi_core.validation.decorators import OpenAPIDecorator
7-
from openapi_core.validation.request.validators import RequestValidator
8-
from openapi_core.validation.response.validators import ResponseValidator
7+
from openapi_core.validation.request import openapi_request_validator
8+
from openapi_core.validation.response import openapi_response_validator
99

1010

1111
class FlaskOpenAPIViewDecorator(OpenAPIDecorator):
1212
def __init__(
1313
self,
14+
spec,
1415
request_validator,
1516
response_validator,
1617
request_class=FlaskOpenAPIRequest,
@@ -19,6 +20,7 @@ def __init__(
1920
openapi_errors_handler=FlaskOpenAPIErrorsHandler,
2021
):
2122
super().__init__(
23+
spec,
2224
request_validator,
2325
response_validator,
2426
request_class,
@@ -43,11 +45,10 @@ def from_spec(
4345
request_provider=FlaskRequestProvider,
4446
openapi_errors_handler=FlaskOpenAPIErrorsHandler,
4547
):
46-
request_validator = RequestValidator(spec)
47-
response_validator = ResponseValidator(spec)
4848
return cls(
49-
request_validator=request_validator,
50-
response_validator=response_validator,
49+
spec,
50+
request_validator=openapi_request_validator,
51+
response_validator=openapi_response_validator,
5152
request_class=request_class,
5253
response_class=response_class,
5354
request_provider=request_provider,

openapi_core/contrib/flask/views.py

+6-6
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33

44
from openapi_core.contrib.flask.decorators import FlaskOpenAPIViewDecorator
55
from openapi_core.contrib.flask.handlers import FlaskOpenAPIErrorsHandler
6-
from openapi_core.validation.request.validators import RequestValidator
7-
from openapi_core.validation.response.validators import ResponseValidator
6+
from openapi_core.validation.request import openapi_request_validator
7+
from openapi_core.validation.response import openapi_response_validator
88

99

1010
class FlaskOpenAPIView(MethodView):
@@ -14,13 +14,13 @@ class FlaskOpenAPIView(MethodView):
1414

1515
def __init__(self, spec):
1616
super().__init__()
17-
self.request_validator = RequestValidator(spec)
18-
self.response_validator = ResponseValidator(spec)
17+
self.spec = spec
1918

2019
def dispatch_request(self, *args, **kwargs):
2120
decorator = FlaskOpenAPIViewDecorator(
22-
request_validator=self.request_validator,
23-
response_validator=self.response_validator,
21+
self.spec,
22+
request_validator=openapi_request_validator,
23+
response_validator=openapi_response_validator,
2424
openapi_errors_handler=self.openapi_errors_handler,
2525
)
2626
return decorator(super().dispatch_request)(*args, **kwargs)

openapi_core/exceptions.py

-88
Original file line numberDiff line numberDiff line change
@@ -1,93 +1,5 @@
11
"""OpenAPI core exceptions module"""
2-
from dataclasses import dataclass
3-
4-
from openapi_core.validation.request.protocols import Request
5-
from openapi_core.validation.response.protocols import Response
62

73

84
class OpenAPIError(Exception):
95
pass
10-
11-
12-
class OpenAPIHeaderError(OpenAPIError):
13-
pass
14-
15-
16-
class MissingHeaderError(OpenAPIHeaderError):
17-
"""Missing header error"""
18-
19-
20-
@dataclass
21-
class MissingHeader(MissingHeaderError):
22-
name: str
23-
24-
def __str__(self):
25-
return f"Missing header (without default value): {self.name}"
26-
27-
28-
@dataclass
29-
class MissingRequiredHeader(MissingHeaderError):
30-
name: str
31-
32-
def __str__(self):
33-
return f"Missing required header: {self.name}"
34-
35-
36-
class OpenAPIParameterError(OpenAPIError):
37-
pass
38-
39-
40-
class MissingParameterError(OpenAPIParameterError):
41-
"""Missing parameter error"""
42-
43-
44-
@dataclass
45-
class MissingParameter(MissingParameterError):
46-
name: str
47-
48-
def __str__(self):
49-
return f"Missing parameter (without default value): {self.name}"
50-
51-
52-
@dataclass
53-
class MissingRequiredParameter(MissingParameterError):
54-
name: str
55-
56-
def __str__(self):
57-
return f"Missing required parameter: {self.name}"
58-
59-
60-
class OpenAPIRequestBodyError(OpenAPIError):
61-
pass
62-
63-
64-
class MissingRequestBodyError(OpenAPIRequestBodyError):
65-
"""Missing request body error"""
66-
67-
68-
@dataclass
69-
class MissingRequestBody(MissingRequestBodyError):
70-
request: Request
71-
72-
def __str__(self):
73-
return "Missing request body"
74-
75-
76-
@dataclass
77-
class MissingRequiredRequestBody(MissingRequestBodyError):
78-
request: Request
79-
80-
def __str__(self):
81-
return "Missing required request body"
82-
83-
84-
class OpenAPIResponseError(OpenAPIError):
85-
pass
86-
87-
88-
@dataclass
89-
class MissingResponseContent(OpenAPIResponseError):
90-
response: Response
91-
92-
def __str__(self):
93-
return "Missing response content"

openapi_core/validation/__init__.py

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
"""OpenAPI core validation module"""
2+
from openapi_core.validation.request import openapi_request_body_validator
3+
from openapi_core.validation.request import openapi_request_parameters_validator
4+
from openapi_core.validation.request import openapi_request_security_validator
5+
from openapi_core.validation.request import openapi_request_validator
6+
from openapi_core.validation.response import openapi_response_data_validator
7+
from openapi_core.validation.response import openapi_response_headers_validator
8+
from openapi_core.validation.response import openapi_response_validator
9+
10+
__all__ = [
11+
"openapi_request_body_validator",
12+
"openapi_request_parameters_validator",
13+
"openapi_request_security_validator",
14+
"openapi_request_validator",
15+
"openapi_response_data_validator",
16+
"openapi_response_headers_validator",
17+
"openapi_response_validator",
18+
]

openapi_core/validation/decorators.py

+4-2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
class OpenAPIDecorator(OpenAPIProcessor):
88
def __init__(
99
self,
10+
spec,
1011
request_validator,
1112
response_validator,
1213
request_class,
@@ -15,6 +16,7 @@ def __init__(
1516
openapi_errors_handler,
1617
):
1718
super().__init__(request_validator, response_validator)
19+
self.spec = spec
1820
self.request_class = request_class
1921
self.response_class = response_class
2022
self.request_provider = request_provider
@@ -25,15 +27,15 @@ def __call__(self, view):
2527
def decorated(*args, **kwargs):
2628
request = self._get_request(*args, **kwargs)
2729
openapi_request = self._get_openapi_request(request)
28-
request_result = self.process_request(openapi_request)
30+
request_result = self.process_request(self.spec, openapi_request)
2931
if request_result.errors:
3032
return self._handle_request_errors(request_result)
3133
response = self._handle_request_view(
3234
request_result, view, *args, **kwargs
3335
)
3436
openapi_response = self._get_openapi_response(response)
3537
response_result = self.process_response(
36-
openapi_request, openapi_response
38+
self.spec, openapi_request, openapi_response
3739
)
3840
if response_result.errors:
3941
return self._handle_response_errors(response_result)

0 commit comments

Comments
 (0)