mirror of
https://github.com/correl/openapi-core.git
synced 2024-11-22 03:00:10 +00:00
Move casters to separate subpackage
This commit is contained in:
parent
ca63475826
commit
368f6882e5
10 changed files with 98 additions and 43 deletions
0
openapi_core/casting/__init__.py
Normal file
0
openapi_core/casting/__init__.py
Normal file
0
openapi_core/casting/schemas/__init__.py
Normal file
0
openapi_core/casting/schemas/__init__.py
Normal file
34
openapi_core/casting/schemas/casters.py
Normal file
34
openapi_core/casting/schemas/casters.py
Normal file
|
@ -0,0 +1,34 @@
|
|||
from openapi_core.schema.schemas.types import NoValue
|
||||
|
||||
|
||||
class PrimitiveCaster(object):
|
||||
|
||||
def __init__(self, caster_callable):
|
||||
self.caster_callable = caster_callable
|
||||
|
||||
def __call__(self, value):
|
||||
if value in (None, NoValue):
|
||||
return value
|
||||
return self.caster_callable(value)
|
||||
|
||||
|
||||
class DummyCaster(object):
|
||||
|
||||
def __call__(self, value):
|
||||
return value
|
||||
|
||||
|
||||
class ArrayCaster(object):
|
||||
|
||||
def __init__(self, schema, casters_factory):
|
||||
self.schema = schema
|
||||
self.casters_factory = casters_factory
|
||||
|
||||
@property
|
||||
def items_caster(self):
|
||||
return self.casters_factory.create(self.schema.items)
|
||||
|
||||
def __call__(self, value):
|
||||
if value in (None, NoValue):
|
||||
return value
|
||||
return list(map(self.items_caster, value))
|
14
openapi_core/casting/schemas/exceptions.py
Normal file
14
openapi_core/casting/schemas/exceptions.py
Normal file
|
@ -0,0 +1,14 @@
|
|||
import attr
|
||||
|
||||
from openapi_core.exceptions import OpenAPIError
|
||||
|
||||
|
||||
@attr.s(hash=True)
|
||||
class CastError(OpenAPIError):
|
||||
"""Schema cast operation error"""
|
||||
value = attr.ib()
|
||||
type = attr.ib()
|
||||
|
||||
def __str__(self):
|
||||
return "Failed to cast value {value} to type {type}".format(
|
||||
value=self.value, type=self.type)
|
29
openapi_core/casting/schemas/factories.py
Normal file
29
openapi_core/casting/schemas/factories.py
Normal file
|
@ -0,0 +1,29 @@
|
|||
from openapi_core.schema.schemas.enums import SchemaType
|
||||
|
||||
from openapi_core.casting.schemas.casters import (
|
||||
PrimitiveCaster, DummyCaster, ArrayCaster
|
||||
)
|
||||
from openapi_core.casting.schemas.util import forcebool
|
||||
|
||||
|
||||
class SchemaCastersFactory(object):
|
||||
|
||||
DUMMY_CASTER = DummyCaster()
|
||||
PRIMITIVE_CASTERS = {
|
||||
SchemaType.STRING: DUMMY_CASTER,
|
||||
SchemaType.INTEGER: PrimitiveCaster(int),
|
||||
SchemaType.NUMBER: PrimitiveCaster(float),
|
||||
SchemaType.BOOLEAN: PrimitiveCaster(forcebool),
|
||||
SchemaType.OBJECT: DUMMY_CASTER,
|
||||
SchemaType.ANY: DUMMY_CASTER,
|
||||
}
|
||||
COMPLEX_CASTERS = {
|
||||
SchemaType.ARRAY: ArrayCaster,
|
||||
}
|
||||
|
||||
def create(self, schema):
|
||||
if schema.type in self.PRIMITIVE_CASTERS:
|
||||
return self.PRIMITIVE_CASTERS[schema.type]
|
||||
elif schema.type in self.COMPLEX_CASTERS:
|
||||
caster_class = self.COMPLEX_CASTERS[schema.type]
|
||||
return caster_class(schema=schema, casters_factory=self)
|
10
openapi_core/casting/schemas/util.py
Normal file
10
openapi_core/casting/schemas/util.py
Normal file
|
@ -0,0 +1,10 @@
|
|||
"""OpenAPI core casting schemas util module"""
|
||||
from distutils.util import strtobool
|
||||
from six import string_types
|
||||
|
||||
|
||||
def forcebool(val):
|
||||
if isinstance(val, string_types):
|
||||
val = strtobool(val)
|
||||
|
||||
return bool(val)
|
|
@ -5,8 +5,9 @@ from json import loads
|
|||
|
||||
from openapi_core.schema.media_types.exceptions import InvalidMediaTypeValue
|
||||
from openapi_core.schema.schemas.exceptions import (
|
||||
CastError, ValidateError,
|
||||
ValidateError,
|
||||
)
|
||||
from openapi_core.casting.schemas.exceptions import CastError
|
||||
from openapi_core.unmarshalling.schemas.exceptions import UnmarshalError
|
||||
|
||||
|
||||
|
|
|
@ -11,8 +11,9 @@ from openapi_core.schema.parameters.exceptions import (
|
|||
)
|
||||
from openapi_core.schema.schemas.enums import SchemaType
|
||||
from openapi_core.schema.schemas.exceptions import (
|
||||
CastError, ValidateError,
|
||||
ValidateError,
|
||||
)
|
||||
from openapi_core.casting.schemas.exceptions import CastError
|
||||
from openapi_core.unmarshalling.schemas.exceptions import UnmarshalError
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
|
|
@ -7,17 +7,6 @@ class OpenAPISchemaError(OpenAPIMappingError):
|
|||
pass
|
||||
|
||||
|
||||
@attr.s(hash=True)
|
||||
class CastError(OpenAPISchemaError):
|
||||
"""Schema cast operation error"""
|
||||
value = attr.ib()
|
||||
type = attr.ib()
|
||||
|
||||
def __str__(self):
|
||||
return "Failed to cast value {value} to type {type}".format(
|
||||
value=self.value, type=self.type)
|
||||
|
||||
|
||||
class ValidateError(OpenAPISchemaError):
|
||||
"""Schema validate operation error"""
|
||||
pass
|
||||
|
|
|
@ -1,18 +1,14 @@
|
|||
"""OpenAPI core schemas models module"""
|
||||
import attr
|
||||
import logging
|
||||
from collections import defaultdict
|
||||
import re
|
||||
|
||||
from jsonschema.exceptions import ValidationError
|
||||
|
||||
from openapi_core.schema.schemas._format import oas30_format_checker
|
||||
from openapi_core.schema.schemas.enums import SchemaType
|
||||
from openapi_core.schema.schemas.exceptions import (
|
||||
CastError, InvalidSchemaValue,
|
||||
)
|
||||
from openapi_core.schema.schemas.exceptions import InvalidSchemaValue
|
||||
from openapi_core.schema.schemas.types import NoValue
|
||||
from openapi_core.schema.schemas.util import forcebool
|
||||
from openapi_core.schema.schemas.validators import OAS30Validator
|
||||
from openapi_core.unmarshalling.schemas.exceptions import (
|
||||
UnmarshalValueError,
|
||||
|
@ -30,12 +26,6 @@ class Format(object):
|
|||
class Schema(object):
|
||||
"""Represents an OpenAPI Schema."""
|
||||
|
||||
TYPE_CAST_CALLABLE_GETTER = {
|
||||
SchemaType.INTEGER: int,
|
||||
SchemaType.NUMBER: float,
|
||||
SchemaType.BOOLEAN: forcebool,
|
||||
}
|
||||
|
||||
def __init__(
|
||||
self, schema_type=None, properties=None, items=None,
|
||||
schema_format=None, required=None, default=NoValue, nullable=False,
|
||||
|
@ -109,30 +99,17 @@ class Schema(object):
|
|||
all_properties = self.get_all_properties()
|
||||
return set(all_properties.keys())
|
||||
|
||||
def get_cast_mapping(self):
|
||||
mapping = self.TYPE_CAST_CALLABLE_GETTER.copy()
|
||||
mapping.update({
|
||||
SchemaType.ARRAY: self._cast_collection,
|
||||
})
|
||||
|
||||
return defaultdict(lambda: lambda x: x, mapping)
|
||||
|
||||
def cast(self, value):
|
||||
"""Cast value from string to schema type"""
|
||||
if value in (None, NoValue):
|
||||
return value
|
||||
|
||||
cast_mapping = self.get_cast_mapping()
|
||||
|
||||
cast_callable = cast_mapping[self.type]
|
||||
from openapi_core.casting.schemas.exceptions import CastError
|
||||
from openapi_core.casting.schemas.factories import SchemaCastersFactory
|
||||
casters_factory = SchemaCastersFactory()
|
||||
caster = casters_factory.create(self)
|
||||
try:
|
||||
return cast_callable(value)
|
||||
except ValueError:
|
||||
return caster(value)
|
||||
except (ValueError, TypeError):
|
||||
raise CastError(value, self.type)
|
||||
|
||||
def _cast_collection(self, value):
|
||||
return list(map(self.items.cast, value))
|
||||
|
||||
def get_validator(self, resolver=None):
|
||||
return OAS30Validator(
|
||||
self.__dict__,
|
||||
|
|
Loading…
Reference in a new issue