Skip to content

Commit 25bfd59

Browse files
committed
Base validator class
1 parent 0748952 commit 25bfd59

File tree

4 files changed

+107
-119
lines changed

4 files changed

+107
-119
lines changed

openapi_core/validation/request/validators.py

+4-59
Original file line numberDiff line numberDiff line change
@@ -22,17 +22,10 @@
2222
RequestParameters, RequestValidationResult,
2323
)
2424
from openapi_core.validation.util import get_operation_pattern
25+
from openapi_core.validation.validators import BaseValidator
2526

2627

27-
class RequestValidator(object):
28-
29-
def __init__(
30-
self, spec,
31-
custom_formatters=None, custom_media_type_deserializers=None,
32-
):
33-
self.spec = spec
34-
self.custom_formatters = custom_formatters
35-
self.custom_media_type_deserializers = custom_media_type_deserializers
28+
class RequestValidator(BaseValidator):
3629

3730
def validate(self, request):
3831
try:
@@ -81,25 +74,6 @@ def _validate_body(self, request):
8174
body, body_errors = self._get_body(request, operation)
8275
return RequestValidationResult(body_errors, body, None, None)
8376

84-
def _get_operation_pattern(self, request):
85-
server = self.spec.get_server(request.full_url_pattern)
86-
87-
return get_operation_pattern(
88-
server.default_url, request.full_url_pattern
89-
)
90-
91-
def _find_path(self, request):
92-
operation_pattern = self._get_operation_pattern(request)
93-
94-
path = self.spec[operation_pattern]
95-
path_variables = {}
96-
operation = self.spec.get_operation(operation_pattern, request.method)
97-
servers = path.servers or operation.servers or self.spec.servers
98-
server = servers[0]
99-
server_variables = {}
100-
101-
return path, operation, server, path_variables, server_variables
102-
10377
def _get_security(self, request, operation):
10478
security = operation.security or self.spec.security
10579
if not security:
@@ -222,15 +196,6 @@ def _get_body_value(self, request_body, request):
222196
raise MissingRequestBody(request)
223197
return request.body
224198

225-
def _deserialise_media_type(self, media_type, value):
226-
from openapi_core.deserializing.media_types.factories import (
227-
MediaTypeDeserializersFactory,
228-
)
229-
deserializers_factory = MediaTypeDeserializersFactory(
230-
self.custom_media_type_deserializers)
231-
deserializer = deserializers_factory.create(media_type)
232-
return deserializer(value)
233-
234199
def _deserialise_parameter(self, param, value):
235200
from openapi_core.deserializing.parameters.factories import (
236201
ParameterDeserializersFactory,
@@ -239,27 +204,7 @@ def _deserialise_parameter(self, param, value):
239204
deserializer = deserializers_factory.create(param)
240205
return deserializer(value)
241206

242-
def _cast(self, param_or_media_type, value):
243-
# return param_or_media_type.cast(value)
244-
if not param_or_media_type.schema:
245-
return value
246-
247-
from openapi_core.casting.schemas.factories import SchemaCastersFactory
248-
casters_factory = SchemaCastersFactory()
249-
caster = casters_factory.create(param_or_media_type.schema)
250-
return caster(value)
251-
252207
def _unmarshal(self, param_or_media_type, value):
253-
if not param_or_media_type.schema:
254-
return value
255-
256-
from openapi_core.unmarshalling.schemas.factories import (
257-
SchemaUnmarshallersFactory,
258-
)
259-
unmarshallers_factory = SchemaUnmarshallersFactory(
260-
self.spec._resolver, self.custom_formatters,
261-
context=UnmarshalContext.REQUEST,
208+
return super(RequestValidator, self)._unmarshal(
209+
param_or_media_type, value, context=UnmarshalContext.REQUEST,
262210
)
263-
unmarshaller = unmarshallers_factory.create(
264-
param_or_media_type.schema)
265-
return unmarshaller(value)

openapi_core/validation/response/validators.py

+23-59
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
from openapi_core.deserializing.exceptions import DeserializeError
44
from openapi_core.schema.operations.exceptions import InvalidOperation
55
from openapi_core.schema.media_types.exceptions import InvalidContentType
6+
from openapi_core.schema.paths.exceptions import InvalidPath
67
from openapi_core.schema.responses.exceptions import (
78
InvalidResponse, MissingResponseContent,
89
)
@@ -13,24 +14,23 @@
1314
)
1415
from openapi_core.validation.response.datatypes import ResponseValidationResult
1516
from openapi_core.validation.util import get_operation_pattern
17+
from openapi_core.validation.validators import BaseValidator
1618

1719

18-
class ResponseValidator(object):
19-
20-
def __init__(
21-
self, spec,
22-
custom_formatters=None, custom_media_type_deserializers=None,
23-
):
24-
self.spec = spec
25-
self.custom_formatters = custom_formatters
26-
self.custom_media_type_deserializers = custom_media_type_deserializers
20+
class ResponseValidator(BaseValidator):
2721

2822
def validate(self, request, response):
23+
try:
24+
_, operation, _, _, _ = self._find_path(request)
25+
# don't process if operation errors
26+
except (InvalidServer, InvalidPath, InvalidOperation) as exc:
27+
return ResponseValidationResult([exc, ], None, None)
28+
2929
try:
3030
operation_response = self._get_operation_response(
31-
request, response)
31+
operation, response)
3232
# don't process if operation errors
33-
except (InvalidServer, InvalidOperation, InvalidResponse) as exc:
33+
except InvalidResponse as exc:
3434
return ResponseValidationResult([exc, ], None, None)
3535

3636
data, data_errors = self._get_data(response, operation_response)
@@ -41,28 +41,21 @@ def validate(self, request, response):
4141
errors = data_errors + headers_errors
4242
return ResponseValidationResult(errors, data, headers)
4343

44-
def _get_operation_pattern(self, request):
45-
server = self.spec.get_server(request.full_url_pattern)
46-
47-
return get_operation_pattern(
48-
server.default_url, request.full_url_pattern
49-
)
50-
51-
def _get_operation(self, request):
52-
operation_pattern = self._get_operation_pattern(request)
53-
54-
return self.spec.get_operation(operation_pattern, request.method)
55-
56-
def _get_operation_response(self, request, response):
57-
operation = self._get_operation(request)
58-
44+
def _get_operation_response(self, operation, response):
5945
return operation.get_response(str(response.status_code))
6046

6147
def _validate_data(self, request, response):
48+
try:
49+
_, operation, _, _, _ = self._find_path(request)
50+
# don't process if operation errors
51+
except (InvalidServer, InvalidPath, InvalidOperation) as exc:
52+
return ResponseValidationResult([exc, ], None, None)
53+
6254
try:
6355
operation_response = self._get_operation_response(
64-
request, response)
65-
except (InvalidServer, InvalidOperation, InvalidResponse) as exc:
56+
operation, response)
57+
# don't process if operation errors
58+
except InvalidResponse as exc:
6659
return ResponseValidationResult([exc, ], None, None)
6760

6861
data, data_errors = self._get_data(response, operation_response)
@@ -113,36 +106,7 @@ def _get_data_value(self, response):
113106

114107
return response.data
115108

116-
def _deserialise_media_type(self, media_type, value):
117-
from openapi_core.deserializing.media_types.factories import (
118-
MediaTypeDeserializersFactory,
119-
)
120-
deserializers_factory = MediaTypeDeserializersFactory(
121-
self.custom_media_type_deserializers)
122-
deserializer = deserializers_factory.create(media_type)
123-
return deserializer(value)
124-
125-
def _cast(self, param_or_media_type, value):
126-
# return param_or_media_type.cast(value)
127-
if not param_or_media_type.schema:
128-
return value
129-
130-
from openapi_core.casting.schemas.factories import SchemaCastersFactory
131-
casters_factory = SchemaCastersFactory()
132-
caster = casters_factory.create(param_or_media_type.schema)
133-
return caster(value)
134-
135109
def _unmarshal(self, param_or_media_type, value):
136-
if not param_or_media_type.schema:
137-
return value
138-
139-
from openapi_core.unmarshalling.schemas.factories import (
140-
SchemaUnmarshallersFactory,
141-
)
142-
unmarshallers_factory = SchemaUnmarshallersFactory(
143-
self.spec._resolver, self.custom_formatters,
144-
context=UnmarshalContext.RESPONSE,
110+
return super(ResponseValidator, self)._unmarshal(
111+
param_or_media_type, value, context=UnmarshalContext.RESPONSE,
145112
)
146-
unmarshaller = unmarshallers_factory.create(
147-
param_or_media_type.schema)
148-
return unmarshaller(value)

openapi_core/validation/validators.py

+79
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
"""OpenAPI core validation validators module"""
2+
from openapi_core.casting.schemas.exceptions import CastError
3+
from openapi_core.deserializing.exceptions import DeserializeError
4+
from openapi_core.schema.operations.exceptions import InvalidOperation
5+
from openapi_core.schema.media_types.exceptions import InvalidContentType
6+
from openapi_core.schema.responses.exceptions import (
7+
InvalidResponse, MissingResponseContent,
8+
)
9+
from openapi_core.schema.servers.exceptions import InvalidServer
10+
from openapi_core.unmarshalling.schemas.enums import UnmarshalContext
11+
from openapi_core.unmarshalling.schemas.exceptions import (
12+
UnmarshalError, ValidateError,
13+
)
14+
from openapi_core.validation.response.datatypes import ResponseValidationResult
15+
from openapi_core.validation.util import get_operation_pattern
16+
17+
18+
class BaseValidator(object):
19+
20+
def __init__(
21+
self, spec,
22+
custom_formatters=None, custom_media_type_deserializers=None,
23+
):
24+
self.spec = spec
25+
self.custom_formatters = custom_formatters
26+
self.custom_media_type_deserializers = custom_media_type_deserializers
27+
28+
def _find_path(self, request):
29+
operation_pattern = self._get_operation_pattern(request)
30+
31+
path = self.spec[operation_pattern]
32+
path_variables = {}
33+
operation = self.spec.get_operation(operation_pattern, request.method)
34+
servers = path.servers or operation.servers or self.spec.servers
35+
server = servers[0]
36+
server_variables = {}
37+
38+
return path, operation, server, path_variables, server_variables
39+
40+
def _get_operation_pattern(self, request):
41+
server = self.spec.get_server(request.full_url_pattern)
42+
43+
return get_operation_pattern(
44+
server.default_url, request.full_url_pattern
45+
)
46+
47+
def _deserialise_media_type(self, media_type, value):
48+
from openapi_core.deserializing.media_types.factories import (
49+
MediaTypeDeserializersFactory,
50+
)
51+
deserializers_factory = MediaTypeDeserializersFactory(
52+
self.custom_media_type_deserializers)
53+
deserializer = deserializers_factory.create(media_type)
54+
return deserializer(value)
55+
56+
def _cast(self, param_or_media_type, value):
57+
# return param_or_media_type.cast(value)
58+
if not param_or_media_type.schema:
59+
return value
60+
61+
from openapi_core.casting.schemas.factories import SchemaCastersFactory
62+
casters_factory = SchemaCastersFactory()
63+
caster = casters_factory.create(param_or_media_type.schema)
64+
return caster(value)
65+
66+
def _unmarshal(self, param_or_media_type, value, context):
67+
if not param_or_media_type.schema:
68+
return value
69+
70+
from openapi_core.unmarshalling.schemas.factories import (
71+
SchemaUnmarshallersFactory,
72+
)
73+
unmarshallers_factory = SchemaUnmarshallersFactory(
74+
self.spec._resolver, self.custom_formatters,
75+
context=context,
76+
)
77+
unmarshaller = unmarshallers_factory.create(
78+
param_or_media_type.schema)
79+
return unmarshaller(value)

tests/integration/validation/test_validators.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -439,7 +439,7 @@ def test_invalid_operation(self, validator):
439439
result = validator.validate(request, response)
440440

441441
assert len(result.errors) == 1
442-
assert type(result.errors[0]) == InvalidOperation
442+
assert type(result.errors[0]) == InvalidPath
443443
assert result.data is None
444444
assert result.headers is None
445445

0 commit comments

Comments
 (0)