mirror of
https://github.com/correl/openapi-core.git
synced 2024-11-22 03:00:10 +00:00
Exceptions restructure
This commit is contained in:
parent
9b05d7b271
commit
4e1a61aace
27 changed files with 287 additions and 209 deletions
|
@ -1,77 +0,0 @@
|
|||
"""OpenAPI core exceptions module"""
|
||||
|
||||
|
||||
class OpenAPIError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class OpenAPIMappingError(OpenAPIError):
|
||||
pass
|
||||
|
||||
|
||||
class OpenAPIServerError(OpenAPIMappingError):
|
||||
pass
|
||||
|
||||
|
||||
class OpenAPIOperationError(OpenAPIMappingError):
|
||||
pass
|
||||
|
||||
|
||||
class InvalidValueType(OpenAPIMappingError):
|
||||
pass
|
||||
|
||||
|
||||
class OpenAPIParameterError(OpenAPIMappingError):
|
||||
pass
|
||||
|
||||
|
||||
class OpenAPIBodyError(OpenAPIMappingError):
|
||||
pass
|
||||
|
||||
|
||||
class InvalidServer(OpenAPIServerError):
|
||||
pass
|
||||
|
||||
|
||||
class InvalidOperation(OpenAPIOperationError):
|
||||
pass
|
||||
|
||||
|
||||
class EmptyValue(OpenAPIParameterError):
|
||||
pass
|
||||
|
||||
|
||||
class MissingParameter(OpenAPIParameterError):
|
||||
pass
|
||||
|
||||
|
||||
class InvalidParameterValue(OpenAPIParameterError):
|
||||
pass
|
||||
|
||||
|
||||
class MissingBody(OpenAPIBodyError):
|
||||
pass
|
||||
|
||||
|
||||
class InvalidMediaTypeValue(OpenAPIBodyError):
|
||||
pass
|
||||
|
||||
|
||||
class UndefinedSchemaProperty(OpenAPIBodyError):
|
||||
pass
|
||||
|
||||
|
||||
class MissingProperty(OpenAPIBodyError):
|
||||
pass
|
||||
|
||||
|
||||
class InvalidContentType(OpenAPIBodyError):
|
||||
pass
|
||||
|
||||
|
||||
class InvalidResponse(OpenAPIMappingError):
|
||||
pass
|
||||
|
||||
|
||||
class InvalidValue(OpenAPIMappingError):
|
||||
pass
|
9
openapi_core/schema/exceptions.py
Normal file
9
openapi_core/schema/exceptions.py
Normal file
|
@ -0,0 +1,9 @@
|
|||
"""OpenAPI core schema exceptions module"""
|
||||
|
||||
|
||||
class OpenAPIError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class OpenAPIMappingError(OpenAPIError):
|
||||
pass
|
13
openapi_core/schema/media_types/exceptions.py
Normal file
13
openapi_core/schema/media_types/exceptions.py
Normal file
|
@ -0,0 +1,13 @@
|
|||
from openapi_core.schema.exceptions import OpenAPIMappingError
|
||||
|
||||
|
||||
class OpenAPIMediaTypeError(OpenAPIMappingError):
|
||||
pass
|
||||
|
||||
|
||||
class InvalidMediaTypeValue(OpenAPIMediaTypeError):
|
||||
pass
|
||||
|
||||
|
||||
class InvalidContentType(OpenAPIMediaTypeError):
|
||||
pass
|
|
@ -2,9 +2,9 @@
|
|||
from collections import defaultdict
|
||||
|
||||
from json import loads
|
||||
from six import iteritems
|
||||
|
||||
from openapi_core.exceptions import InvalidValueType, InvalidMediaTypeValue
|
||||
from openapi_core.schema.media_types.exceptions import InvalidMediaTypeValue
|
||||
from openapi_core.schema.schemas.exceptions import InvalidSchemaValue
|
||||
|
||||
|
||||
MEDIA_TYPE_DESERIALIZERS = {
|
||||
|
@ -42,5 +42,5 @@ class MediaType(object):
|
|||
|
||||
try:
|
||||
return self.schema.unmarshal(deserialized)
|
||||
except InvalidValueType as exc:
|
||||
except InvalidSchemaValue as exc:
|
||||
raise InvalidMediaTypeValue(str(exc))
|
||||
|
|
9
openapi_core/schema/operations/exceptions.py
Normal file
9
openapi_core/schema/operations/exceptions.py
Normal file
|
@ -0,0 +1,9 @@
|
|||
from openapi_core.schema.exceptions import OpenAPIMappingError
|
||||
|
||||
|
||||
class OpenAPIOperationError(OpenAPIMappingError):
|
||||
pass
|
||||
|
||||
|
||||
class InvalidOperation(OpenAPIOperationError):
|
||||
pass
|
|
@ -1,6 +1,6 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
"""OpenAPI core operations models module"""
|
||||
from openapi_core.exceptions import InvalidResponse
|
||||
from openapi_core.schema.responses.exceptions import InvalidResponse
|
||||
|
||||
|
||||
class Operation(object):
|
||||
|
@ -21,6 +21,7 @@ class Operation(object):
|
|||
return self.parameters[name]
|
||||
|
||||
def get_response(self, http_status='default'):
|
||||
# @todo: move to Responses object
|
||||
try:
|
||||
return self.responses[http_status]
|
||||
except KeyError:
|
||||
|
|
21
openapi_core/schema/parameters/exceptions.py
Normal file
21
openapi_core/schema/parameters/exceptions.py
Normal file
|
@ -0,0 +1,21 @@
|
|||
from openapi_core.schema.exceptions import OpenAPIMappingError
|
||||
|
||||
|
||||
class OpenAPIParameterError(OpenAPIMappingError):
|
||||
pass
|
||||
|
||||
|
||||
class MissingParameter(OpenAPIParameterError):
|
||||
pass
|
||||
|
||||
|
||||
class MissingRequiredParameter(OpenAPIParameterError):
|
||||
pass
|
||||
|
||||
|
||||
class EmptyParameterValue(OpenAPIParameterError):
|
||||
pass
|
||||
|
||||
|
||||
class InvalidParameterValue(OpenAPIParameterError):
|
||||
pass
|
|
@ -2,11 +2,13 @@
|
|||
import logging
|
||||
import warnings
|
||||
|
||||
from openapi_core.exceptions import (
|
||||
EmptyValue, InvalidValueType, InvalidParameterValue,
|
||||
)
|
||||
from openapi_core.schema.parameters.enums import ParameterLocation, ParameterStyle
|
||||
from openapi_core.schema.parameters.exceptions import (
|
||||
MissingRequiredParameter, MissingParameter, InvalidParameterValue,
|
||||
EmptyParameterValue,
|
||||
)
|
||||
from openapi_core.schema.schemas.enums import SchemaType
|
||||
from openapi_core.schema.schemas.exceptions import InvalidSchemaValue
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
@ -68,6 +70,27 @@ class Parameter(object):
|
|||
deserializer = self.get_dererializer()
|
||||
return deserializer(value)
|
||||
|
||||
def get_value(self, request):
|
||||
location = request.parameters[self.location.value]
|
||||
|
||||
try:
|
||||
raw = location[self.name]
|
||||
except KeyError:
|
||||
if self.required:
|
||||
raise MissingRequiredParameter(
|
||||
"Missing required `{0}` parameter".format(self.name))
|
||||
|
||||
if not self.schema or self.schema.default is None:
|
||||
raise MissingParameter(
|
||||
"Missing `{0}` parameter".format(self.name))
|
||||
|
||||
raw = self.schema.default
|
||||
|
||||
if self.aslist and self.explode:
|
||||
return location.getlist(self.name)
|
||||
|
||||
return raw
|
||||
|
||||
def unmarshal(self, value):
|
||||
if self.deprecated:
|
||||
warnings.warn(
|
||||
|
@ -77,7 +100,7 @@ class Parameter(object):
|
|||
|
||||
if (self.location == ParameterLocation.QUERY and value == "" and
|
||||
not self.allow_empty_value):
|
||||
raise EmptyValue(
|
||||
raise EmptyParameterValue(
|
||||
"Value of {0} parameter cannot be empty".format(self.name))
|
||||
|
||||
if not self.schema:
|
||||
|
@ -87,5 +110,5 @@ class Parameter(object):
|
|||
|
||||
try:
|
||||
return self.schema.unmarshal(deserialized)
|
||||
except InvalidValueType as exc:
|
||||
except InvalidSchemaValue as exc:
|
||||
raise InvalidParameterValue(str(exc))
|
||||
|
|
9
openapi_core/schema/request_bodies/exceptions.py
Normal file
9
openapi_core/schema/request_bodies/exceptions.py
Normal file
|
@ -0,0 +1,9 @@
|
|||
from openapi_core.schema.exceptions import OpenAPIMappingError
|
||||
|
||||
|
||||
class OpenAPIRequestBodyError(OpenAPIMappingError):
|
||||
pass
|
||||
|
||||
|
||||
class MissingRequestBody(OpenAPIRequestBodyError):
|
||||
pass
|
|
@ -1,5 +1,7 @@
|
|||
"""OpenAPI core request bodies models module"""
|
||||
from openapi_core.exceptions import InvalidContentType
|
||||
|
||||
from openapi_core.schema.media_types.exceptions import InvalidContentType
|
||||
from openapi_core.schema.request_bodies.exceptions import MissingRequestBody
|
||||
|
||||
|
||||
class RequestBody(object):
|
||||
|
@ -15,3 +17,9 @@ class RequestBody(object):
|
|||
except KeyError:
|
||||
raise InvalidContentType(
|
||||
"Invalid mime type `{0}`".format(mimetype))
|
||||
|
||||
def get_value(self, request):
|
||||
if not request.body and self.required:
|
||||
raise MissingRequestBody("Missing required request body")
|
||||
|
||||
return request.body
|
||||
|
|
13
openapi_core/schema/responses/exceptions.py
Normal file
13
openapi_core/schema/responses/exceptions.py
Normal file
|
@ -0,0 +1,13 @@
|
|||
from openapi_core.schema.exceptions import OpenAPIMappingError
|
||||
|
||||
|
||||
class OpenAPIResponseError(OpenAPIMappingError):
|
||||
pass
|
||||
|
||||
|
||||
class InvalidResponse(OpenAPIResponseError):
|
||||
pass
|
||||
|
||||
|
||||
class MissingResponseContent(OpenAPIResponseError):
|
||||
pass
|
|
@ -1,5 +1,6 @@
|
|||
"""OpenAPI core responses models module"""
|
||||
from openapi_core.exceptions import InvalidContentType
|
||||
from openapi_core.schema.media_types.exceptions import InvalidContentType
|
||||
from openapi_core.schema.responses.exceptions import MissingResponseContent
|
||||
|
||||
|
||||
class Response(object):
|
||||
|
@ -19,3 +20,9 @@ class Response(object):
|
|||
except KeyError:
|
||||
raise InvalidContentType(
|
||||
"Invalid mime type `{0}`".format(mimetype))
|
||||
|
||||
def get_value(self, response):
|
||||
if not response.data:
|
||||
raise MissingResponseContent("Missing response content")
|
||||
|
||||
return response.data
|
||||
|
|
17
openapi_core/schema/schemas/exceptions.py
Normal file
17
openapi_core/schema/schemas/exceptions.py
Normal file
|
@ -0,0 +1,17 @@
|
|||
from openapi_core.schema.exceptions import OpenAPIMappingError
|
||||
|
||||
|
||||
class OpenAPISchemaError(OpenAPIMappingError):
|
||||
pass
|
||||
|
||||
|
||||
class InvalidSchemaValue(OpenAPISchemaError):
|
||||
pass
|
||||
|
||||
|
||||
class UndefinedSchemaProperty(OpenAPISchemaError):
|
||||
pass
|
||||
|
||||
|
||||
class MissingSchemaProperty(OpenAPISchemaError):
|
||||
pass
|
|
@ -5,11 +5,11 @@ import warnings
|
|||
|
||||
from six import iteritems
|
||||
|
||||
from openapi_core.exceptions import (
|
||||
InvalidValueType, UndefinedSchemaProperty, MissingProperty, InvalidValue,
|
||||
)
|
||||
from openapi_core.extensions.models.factories import ModelFactory
|
||||
from openapi_core.schema.schemas.enums import SchemaType, SchemaFormat
|
||||
from openapi_core.schema.schemas.exceptions import (
|
||||
InvalidSchemaValue, UndefinedSchemaProperty, MissingSchemaProperty,
|
||||
)
|
||||
from openapi_core.schema.schemas.util import forcebool
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
@ -74,7 +74,7 @@ class Schema(object):
|
|||
"""Cast value to schema type"""
|
||||
if value is None:
|
||||
if not self.nullable:
|
||||
raise InvalidValueType("Null value for non-nullable schema")
|
||||
raise InvalidSchemaValue("Null value for non-nullable schema")
|
||||
return self.default
|
||||
|
||||
if self.type is None:
|
||||
|
@ -89,7 +89,7 @@ class Schema(object):
|
|||
try:
|
||||
return cast_callable(value)
|
||||
except ValueError:
|
||||
raise InvalidValueType(
|
||||
raise InvalidSchemaValue(
|
||||
"Failed to cast value of {0} to {1}".format(value, self.type)
|
||||
)
|
||||
|
||||
|
@ -104,7 +104,7 @@ class Schema(object):
|
|||
return None
|
||||
|
||||
if self.enum and casted not in self.enum:
|
||||
raise InvalidValue(
|
||||
raise InvalidSchemaValue(
|
||||
"Value of {0} not in enum choices: {1}".format(
|
||||
value, self.enum)
|
||||
)
|
||||
|
@ -116,7 +116,8 @@ class Schema(object):
|
|||
|
||||
def _unmarshal_object(self, value):
|
||||
if not isinstance(value, (dict, )):
|
||||
raise InvalidValueType("Value of {0} not an object".format(value))
|
||||
raise InvalidSchemaValue(
|
||||
"Value of {0} not an object".format(value))
|
||||
|
||||
all_properties = self.get_all_properties()
|
||||
all_required_properties = self.get_all_required_properties()
|
||||
|
@ -135,7 +136,7 @@ class Schema(object):
|
|||
prop_value = value[prop_name]
|
||||
except KeyError:
|
||||
if prop_name in all_required_properties:
|
||||
raise MissingProperty(
|
||||
raise MissingSchemaProperty(
|
||||
"Missing schema property {0}".format(prop_name))
|
||||
if not prop.nullable and not prop.default:
|
||||
continue
|
||||
|
|
9
openapi_core/schema/servers/exceptions.py
Normal file
9
openapi_core/schema/servers/exceptions.py
Normal file
|
@ -0,0 +1,9 @@
|
|||
from openapi_core.schema.exceptions import OpenAPIMappingError
|
||||
|
||||
|
||||
class OpenAPIServerError(OpenAPIMappingError):
|
||||
pass
|
||||
|
||||
|
||||
class InvalidServer(OpenAPIServerError):
|
||||
pass
|
|
@ -4,7 +4,8 @@ from functools import lru_cache
|
|||
|
||||
from openapi_spec_validator import openapi_v3_spec_validator
|
||||
|
||||
from openapi_core.exceptions import InvalidOperation, InvalidServer
|
||||
from openapi_core.schema.operations.exceptions import InvalidOperation
|
||||
from openapi_core.schema.servers.exceptions import InvalidServer
|
||||
from openapi_core.schema.components.factories import ComponentsFactory
|
||||
from openapi_core.schema.infos.factories import InfoFactory
|
||||
from openapi_core.schema.paths.generators import PathsGenerator
|
||||
|
|
|
@ -3,7 +3,8 @@
|
|||
import logging
|
||||
from functools import partialmethod
|
||||
|
||||
from openapi_core.exceptions import InvalidOperation, InvalidServer
|
||||
from openapi_core.schema.operations.exceptions import InvalidOperation
|
||||
from openapi_core.schema.servers.exceptions import InvalidServer
|
||||
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
|
|
@ -3,7 +3,12 @@ from jsonschema.validators import RefResolver
|
|||
from openapi_spec_validator.validators import Dereferencer
|
||||
from openapi_spec_validator import default_handlers
|
||||
|
||||
from openapi_core.exceptions import OpenAPIParameterError, OpenAPIBodyError
|
||||
from openapi_core.schema.media_types.exceptions import OpenAPIMediaTypeError
|
||||
from openapi_core.schema.parameters.exceptions import OpenAPIParameterError
|
||||
from openapi_core.schema.request_bodies.exceptions import (
|
||||
OpenAPIRequestBodyError,
|
||||
)
|
||||
from openapi_core.schema.schemas.exceptions import OpenAPISchemaError
|
||||
from openapi_core.schema.specs.factories import SpecFactory
|
||||
from openapi_core.validation.request.validators import RequestValidator
|
||||
from openapi_core.validation.response.validators import ResponseValidator
|
||||
|
@ -26,7 +31,10 @@ def validate_parameters(spec, request, wrapper_class=None):
|
|||
|
||||
try:
|
||||
result.raise_for_errors()
|
||||
except OpenAPIBodyError:
|
||||
except (
|
||||
OpenAPIRequestBodyError, OpenAPIMediaTypeError,
|
||||
OpenAPISchemaError,
|
||||
):
|
||||
return result.parameters
|
||||
else:
|
||||
return result.parameters
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
"""OpenAPI core validation request models module"""
|
||||
from openapi_core.exceptions import OpenAPIMappingError
|
||||
from openapi_core.schema.exceptions import OpenAPIMappingError
|
||||
|
||||
from openapi_core.validation.models import BaseValidationResult
|
||||
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
"""OpenAPI core validation request validators module"""
|
||||
from six import iteritems
|
||||
|
||||
from openapi_core.exceptions import (
|
||||
OpenAPIMappingError, MissingParameter, MissingBody,
|
||||
)
|
||||
from openapi_core.schema.exceptions import OpenAPIMappingError
|
||||
from openapi_core.schema.parameters.exceptions import MissingParameter
|
||||
from openapi_core.validation.request.models import (
|
||||
RequestParameters, RequestValidationResult,
|
||||
)
|
||||
|
@ -16,16 +15,11 @@ class RequestValidator(object):
|
|||
self.spec = spec
|
||||
|
||||
def validate(self, request):
|
||||
errors = []
|
||||
body = None
|
||||
parameters = RequestParameters()
|
||||
|
||||
try:
|
||||
server = self.spec.get_server(request.full_url_pattern)
|
||||
# don't process if server errors
|
||||
except OpenAPIMappingError as exc:
|
||||
errors.append(exc)
|
||||
return RequestValidationResult(errors, body, parameters)
|
||||
return RequestValidationResult([exc, ], None, None)
|
||||
|
||||
operation_pattern = get_operation_pattern(
|
||||
server.default_url, request.full_url_pattern
|
||||
|
@ -36,19 +30,26 @@ class RequestValidator(object):
|
|||
operation_pattern, request.method)
|
||||
# don't process if operation errors
|
||||
except OpenAPIMappingError as exc:
|
||||
errors.append(exc)
|
||||
return RequestValidationResult(errors, body, parameters)
|
||||
return RequestValidationResult([exc, ], None, None)
|
||||
|
||||
params, params_errors = self._get_parameters(request, operation)
|
||||
body, body_errors = self._get_body(request, operation)
|
||||
|
||||
errors = params_errors + body_errors
|
||||
return RequestValidationResult(errors, body, params)
|
||||
|
||||
def _get_parameters(self, request, operation):
|
||||
errors = []
|
||||
|
||||
parameters = RequestParameters()
|
||||
for param_name, param in iteritems(operation.parameters):
|
||||
try:
|
||||
raw_value = self._get_raw_value(request, param)
|
||||
except MissingParameter as exc:
|
||||
if param.required:
|
||||
errors.append(exc)
|
||||
|
||||
if not param.schema or param.schema.default is None:
|
||||
continue
|
||||
raw_value = param.schema.default
|
||||
raw_value = param.get_value(request)
|
||||
except MissingParameter:
|
||||
continue
|
||||
except OpenAPIMappingError as exc:
|
||||
errors.append(exc)
|
||||
continue
|
||||
|
||||
try:
|
||||
value = param.unmarshal(raw_value)
|
||||
|
@ -57,41 +58,28 @@ class RequestValidator(object):
|
|||
else:
|
||||
parameters[param.location.value][param_name] = value
|
||||
|
||||
if operation.request_body is not None:
|
||||
return parameters, errors
|
||||
|
||||
def _get_body(self, request, operation):
|
||||
errors = []
|
||||
|
||||
if operation.request_body is None:
|
||||
return None, errors
|
||||
|
||||
body = None
|
||||
try:
|
||||
media_type = operation.request_body[request.mimetype]
|
||||
except OpenAPIMappingError as exc:
|
||||
errors.append(exc)
|
||||
else:
|
||||
try:
|
||||
media_type = operation.request_body[request.mimetype]
|
||||
raw_body = operation.request_body.get_value(request)
|
||||
except OpenAPIMappingError as exc:
|
||||
errors.append(exc)
|
||||
else:
|
||||
try:
|
||||
raw_body = self._get_raw_body(request)
|
||||
except MissingBody as exc:
|
||||
if operation.request_body.required:
|
||||
errors.append(exc)
|
||||
else:
|
||||
try:
|
||||
body = media_type.unmarshal(raw_body)
|
||||
except OpenAPIMappingError as exc:
|
||||
errors.append(exc)
|
||||
body = media_type.unmarshal(raw_body)
|
||||
except OpenAPIMappingError as exc:
|
||||
errors.append(exc)
|
||||
|
||||
return RequestValidationResult(errors, body, parameters)
|
||||
|
||||
def _get_raw_value(self, request, param):
|
||||
location = request.parameters[param.location.value]
|
||||
|
||||
try:
|
||||
raw = location[param.name]
|
||||
except KeyError:
|
||||
raise MissingParameter(
|
||||
"Missing required `{0}` parameter".format(param.name))
|
||||
|
||||
if param.aslist and param.explode:
|
||||
return location.getlist(param.name)
|
||||
|
||||
return raw
|
||||
|
||||
def _get_raw_body(self, request):
|
||||
if not request.body:
|
||||
raise MissingBody("Missing required request body")
|
||||
|
||||
return request.body
|
||||
return body, errors
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
"""OpenAPI core validation response validators module"""
|
||||
from openapi_core.exceptions import (
|
||||
OpenAPIMappingError, MissingBody, InvalidResponse,
|
||||
)
|
||||
from openapi_core.schema.exceptions import OpenAPIMappingError
|
||||
from openapi_core.validation.response.models import ResponseValidationResult
|
||||
from openapi_core.validation.util import get_operation_pattern
|
||||
|
||||
|
@ -12,16 +10,11 @@ class ResponseValidator(object):
|
|||
self.spec = spec
|
||||
|
||||
def validate(self, request, response):
|
||||
errors = []
|
||||
data = None
|
||||
headers = {}
|
||||
|
||||
try:
|
||||
server = self.spec.get_server(request.full_url_pattern)
|
||||
# don't process if server errors
|
||||
except OpenAPIMappingError as exc:
|
||||
errors.append(exc)
|
||||
return ResponseValidationResult(errors, data, headers)
|
||||
return ResponseValidationResult([exc, ], None, None)
|
||||
|
||||
operation_pattern = get_operation_pattern(
|
||||
server.default_url, request.full_url_pattern
|
||||
|
@ -32,37 +25,51 @@ class ResponseValidator(object):
|
|||
operation_pattern, request.method)
|
||||
# don't process if operation errors
|
||||
except OpenAPIMappingError as exc:
|
||||
errors.append(exc)
|
||||
return ResponseValidationResult(errors, data, headers)
|
||||
return ResponseValidationResult([exc, ], None, None)
|
||||
|
||||
try:
|
||||
operation_response = operation.get_response(
|
||||
str(response.status_code))
|
||||
# don't process if invalid response status code
|
||||
except InvalidResponse as exc:
|
||||
errors.append(exc)
|
||||
return ResponseValidationResult(errors, data, headers)
|
||||
# don't process if operation response errors
|
||||
except OpenAPIMappingError as exc:
|
||||
return ResponseValidationResult([exc, ], None, None)
|
||||
|
||||
if operation_response.content:
|
||||
data, data_errors = self._get_data(response, operation_response)
|
||||
|
||||
headers, headers_errors = self._get_headers(
|
||||
response, operation_response)
|
||||
|
||||
errors = data_errors + headers_errors
|
||||
return ResponseValidationResult(errors, data, headers)
|
||||
|
||||
def _get_data(self, response, operation_response):
|
||||
errors = []
|
||||
|
||||
if not operation_response.content:
|
||||
return None, errors
|
||||
|
||||
data = None
|
||||
try:
|
||||
media_type = operation_response[response.mimetype]
|
||||
except OpenAPIMappingError as exc:
|
||||
errors.append(exc)
|
||||
else:
|
||||
try:
|
||||
media_type = operation_response[response.mimetype]
|
||||
raw_data = operation_response.get_value(response)
|
||||
except OpenAPIMappingError as exc:
|
||||
errors.append(exc)
|
||||
else:
|
||||
try:
|
||||
raw_data = self._get_raw_data(response)
|
||||
except MissingBody as exc:
|
||||
data = media_type.unmarshal(raw_data)
|
||||
except OpenAPIMappingError as exc:
|
||||
errors.append(exc)
|
||||
else:
|
||||
try:
|
||||
data = media_type.unmarshal(raw_data)
|
||||
except OpenAPIMappingError as exc:
|
||||
errors.append(exc)
|
||||
|
||||
return ResponseValidationResult(errors, data, headers)
|
||||
return data, errors
|
||||
|
||||
def _get_raw_data(self, response):
|
||||
if not response.data:
|
||||
raise MissingBody("Missing required response data")
|
||||
def _get_headers(self, response, operation_response):
|
||||
errors = []
|
||||
|
||||
return response.data
|
||||
# @todo: implement
|
||||
headers = {}
|
||||
|
||||
return headers, errors
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import pytest
|
||||
|
||||
from openapi_core.exceptions import InvalidOperation
|
||||
from openapi_core.schema.operations.exceptions import InvalidOperation
|
||||
from openapi_core.shortcuts import create_spec
|
||||
from openapi_core.validation.request.validators import RequestValidator
|
||||
from openapi_core.wrappers.mock import MockRequest
|
||||
|
|
|
@ -2,18 +2,23 @@ import json
|
|||
import pytest
|
||||
from six import iteritems
|
||||
|
||||
from openapi_core.exceptions import (
|
||||
MissingParameter, InvalidContentType, InvalidServer,
|
||||
UndefinedSchemaProperty, MissingProperty,
|
||||
EmptyValue, InvalidMediaTypeValue, InvalidParameterValue,
|
||||
from openapi_core.schema.media_types.exceptions import (
|
||||
InvalidContentType, InvalidMediaTypeValue,
|
||||
)
|
||||
from openapi_core.schema.media_types.models import MediaType
|
||||
from openapi_core.schema.operations.models import Operation
|
||||
from openapi_core.schema.parameters.exceptions import (
|
||||
MissingRequiredParameter, InvalidParameterValue, EmptyParameterValue,
|
||||
)
|
||||
from openapi_core.schema.parameters.models import Parameter
|
||||
from openapi_core.schema.paths.models import Path
|
||||
from openapi_core.schema.request_bodies.models import RequestBody
|
||||
from openapi_core.schema.responses.models import Response
|
||||
from openapi_core.schema.schemas.exceptions import (
|
||||
UndefinedSchemaProperty, MissingSchemaProperty,
|
||||
)
|
||||
from openapi_core.schema.schemas.models import Schema
|
||||
from openapi_core.schema.servers.exceptions import InvalidServer
|
||||
from openapi_core.schema.servers.models import Server, ServerVariable
|
||||
from openapi_core.shortcuts import create_spec
|
||||
from openapi_core.validation.request.validators import RequestValidator
|
||||
|
@ -313,7 +318,7 @@ class TestPetstore(object):
|
|||
path_pattern=path_pattern,
|
||||
)
|
||||
|
||||
with pytest.raises(MissingParameter):
|
||||
with pytest.raises(MissingRequiredParameter):
|
||||
request.get_parameters(spec)
|
||||
|
||||
body = request.get_body(spec)
|
||||
|
@ -332,7 +337,7 @@ class TestPetstore(object):
|
|||
path_pattern=path_pattern, args=query_params,
|
||||
)
|
||||
|
||||
with pytest.raises(EmptyValue):
|
||||
with pytest.raises(EmptyParameterValue):
|
||||
request.get_parameters(spec)
|
||||
body = request.get_body(spec)
|
||||
|
||||
|
@ -465,7 +470,7 @@ class TestPetstore(object):
|
|||
|
||||
assert parameters == {}
|
||||
|
||||
with pytest.raises(MissingProperty):
|
||||
with pytest.raises(MissingSchemaProperty):
|
||||
request.get_body(spec)
|
||||
|
||||
def test_post_pets_extra_body_properties(self, spec, spec_dict):
|
||||
|
|
|
@ -1,11 +1,16 @@
|
|||
import json
|
||||
import pytest
|
||||
|
||||
from openapi_core.exceptions import (
|
||||
InvalidServer, InvalidOperation, MissingParameter,
|
||||
MissingBody, InvalidContentType, InvalidResponse, InvalidMediaTypeValue,
|
||||
InvalidValue,
|
||||
from openapi_core.schema.media_types.exceptions import (
|
||||
InvalidContentType, InvalidMediaTypeValue,
|
||||
)
|
||||
from openapi_core.schema.operations.exceptions import InvalidOperation
|
||||
from openapi_core.schema.parameters.exceptions import MissingRequiredParameter
|
||||
from openapi_core.schema.request_bodies.exceptions import MissingRequestBody
|
||||
from openapi_core.schema.responses.exceptions import (
|
||||
MissingResponseContent, InvalidResponse,
|
||||
)
|
||||
from openapi_core.schema.servers.exceptions import InvalidServer
|
||||
from openapi_core.shortcuts import create_spec
|
||||
from openapi_core.validation.request.validators import RequestValidator
|
||||
from openapi_core.validation.response.validators import ResponseValidator
|
||||
|
@ -53,7 +58,7 @@ class TestRequestValidator(object):
|
|||
|
||||
result = validator.validate(request)
|
||||
|
||||
assert type(result.errors[0]) == MissingParameter
|
||||
assert type(result.errors[0]) == MissingRequiredParameter
|
||||
assert result.body is None
|
||||
assert result.parameters == {
|
||||
'query': {
|
||||
|
@ -89,7 +94,7 @@ class TestRequestValidator(object):
|
|||
result = validator.validate(request)
|
||||
|
||||
assert len(result.errors) == 1
|
||||
assert type(result.errors[0]) == MissingBody
|
||||
assert type(result.errors[0]) == MissingRequestBody
|
||||
assert result.body is None
|
||||
assert result.parameters == {}
|
||||
|
||||
|
@ -184,7 +189,7 @@ class TestResponseValidator(object):
|
|||
assert len(result.errors) == 1
|
||||
assert type(result.errors[0]) == InvalidServer
|
||||
assert result.data is None
|
||||
assert result.headers == {}
|
||||
assert result.headers is None
|
||||
|
||||
def test_invalid_operation(self, validator):
|
||||
request = MockRequest(self.host_url, 'get', '/v1')
|
||||
|
@ -195,7 +200,7 @@ class TestResponseValidator(object):
|
|||
assert len(result.errors) == 1
|
||||
assert type(result.errors[0]) == InvalidOperation
|
||||
assert result.data is None
|
||||
assert result.headers == {}
|
||||
assert result.headers is None
|
||||
|
||||
def test_invalid_response(self, validator):
|
||||
request = MockRequest(self.host_url, 'get', '/v1/pets')
|
||||
|
@ -206,7 +211,7 @@ class TestResponseValidator(object):
|
|||
assert len(result.errors) == 1
|
||||
assert type(result.errors[0]) == InvalidResponse
|
||||
assert result.data is None
|
||||
assert result.headers == {}
|
||||
assert result.headers is None
|
||||
|
||||
def test_invalid_content_type(self, validator):
|
||||
request = MockRequest(self.host_url, 'get', '/v1/pets')
|
||||
|
@ -226,7 +231,7 @@ class TestResponseValidator(object):
|
|||
result = validator.validate(request, response)
|
||||
|
||||
assert len(result.errors) == 1
|
||||
assert type(result.errors[0]) == MissingBody
|
||||
assert type(result.errors[0]) == MissingResponseContent
|
||||
assert result.data is None
|
||||
assert result.headers == {}
|
||||
|
||||
|
@ -257,7 +262,7 @@ class TestResponseValidator(object):
|
|||
result = validator.validate(request, response)
|
||||
|
||||
assert len(result.errors) == 1
|
||||
assert type(result.errors[0]) == InvalidValue
|
||||
assert type(result.errors[0]) == InvalidMediaTypeValue
|
||||
assert result.data is None
|
||||
assert result.headers == {}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import pytest
|
||||
|
||||
from openapi_core.exceptions import EmptyValue
|
||||
from openapi_core.schema.parameters.exceptions import EmptyParameterValue
|
||||
from openapi_core.schema.parameters.enums import ParameterStyle
|
||||
from openapi_core.schema.parameters.models import Parameter
|
||||
|
||||
|
@ -59,7 +59,7 @@ class TestParameterUnmarshal(object):
|
|||
param = Parameter('param', 'query')
|
||||
value = ''
|
||||
|
||||
with pytest.raises(EmptyValue):
|
||||
with pytest.raises(EmptyParameterValue):
|
||||
param.unmarshal(value)
|
||||
|
||||
def test_query_allow_empty_value(self):
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import mock
|
||||
import pytest
|
||||
|
||||
from openapi_core.exceptions import InvalidValueType, InvalidValue
|
||||
from openapi_core.schema.schemas.exceptions import InvalidSchemaValue
|
||||
from openapi_core.schema.schemas.models import Schema
|
||||
|
||||
|
||||
|
@ -44,7 +44,7 @@ class TestSchemaUnmarshal(object):
|
|||
schema = Schema('string')
|
||||
value = None
|
||||
|
||||
with pytest.raises(InvalidValueType):
|
||||
with pytest.raises(InvalidSchemaValue):
|
||||
schema.unmarshal(value)
|
||||
|
||||
def test_string_default(self):
|
||||
|
@ -52,7 +52,7 @@ class TestSchemaUnmarshal(object):
|
|||
schema = Schema('string', default=default_value)
|
||||
value = None
|
||||
|
||||
with pytest.raises(InvalidValueType):
|
||||
with pytest.raises(InvalidSchemaValue):
|
||||
schema.unmarshal(value)
|
||||
|
||||
def test_string_default_nullable(self):
|
||||
|
@ -76,7 +76,7 @@ class TestSchemaUnmarshal(object):
|
|||
schema = Schema('integer', enum=[1, 2, 3])
|
||||
value = '123'
|
||||
|
||||
with pytest.raises(InvalidValue):
|
||||
with pytest.raises(InvalidSchemaValue):
|
||||
schema.unmarshal(value)
|
||||
|
||||
def test_integer_enum(self):
|
||||
|
@ -92,7 +92,7 @@ class TestSchemaUnmarshal(object):
|
|||
schema = Schema('integer', default=default_value)
|
||||
value = None
|
||||
|
||||
with pytest.raises(InvalidValueType):
|
||||
with pytest.raises(InvalidSchemaValue):
|
||||
schema.unmarshal(value)
|
||||
|
||||
def test_integer_default_nullable(self):
|
||||
|
@ -108,5 +108,5 @@ class TestSchemaUnmarshal(object):
|
|||
schema = Schema('integer')
|
||||
value = 'abc'
|
||||
|
||||
with pytest.raises(InvalidValueType):
|
||||
with pytest.raises(InvalidSchemaValue):
|
||||
schema.unmarshal(value)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import mock
|
||||
import pytest
|
||||
|
||||
from openapi_core.exceptions import InvalidOperation
|
||||
from openapi_core.schema.operations.exceptions import InvalidOperation
|
||||
from openapi_core.schema.paths.models import Path
|
||||
from openapi_core.schema.specs.models import Spec
|
||||
|
||||
|
|
Loading…
Reference in a new issue