Пример #1
0
class IntegerUnmarshaller(PrimitiveTypeUnmarshaller):

    FORMATTERS = {
        SchemaFormat.NONE: Formatter.from_callables(
            partial(is_integer, None), int),
        SchemaFormat.INT32: Formatter.from_callables(
            partial(oas30_format_checker.check, format='int32'), int),
        SchemaFormat.INT64: Formatter.from_callables(
            partial(oas30_format_checker.check, format='int64'), int),
    }
Пример #2
0
class NumberUnmarshaller(PrimitiveTypeUnmarshaller):

    FORMATTERS = {
        SchemaFormat.NONE: Formatter.from_callables(
            partial(is_number, None), format_number),
        SchemaFormat.FLOAT: Formatter.from_callables(
            partial(oas30_format_checker.check, format='float'), float),
        SchemaFormat.DOUBLE: Formatter.from_callables(
            partial(oas30_format_checker.check, format='double'), float),
    }
Пример #3
0
class NumberUnmarshaller(PrimitiveTypeUnmarshaller):

    FORMATTERS = {
        None:
        Formatter.from_callables(partial(is_number, None), format_number),
        "float":
        Formatter.from_callables(
            partial(oas30_format_checker.check, format="float"), float),
        "double":
        Formatter.from_callables(
            partial(oas30_format_checker.check, format="double"), float),
    }
Пример #4
0
class IntegerUnmarshaller(PrimitiveTypeUnmarshaller):

    FORMATTERS = {
        None:
        Formatter.from_callables(partial(is_integer, None), int),
        "int32":
        Formatter.from_callables(
            partial(oas30_format_checker.check, format="int32"), int),
        "int64":
        Formatter.from_callables(
            partial(oas30_format_checker.check, format="int64"), int),
    }
Пример #5
0
class StringUnmarshaller(PrimitiveTypeUnmarshaller):

    FORMATTERS = {
        None:
        Formatter.from_callables(partial(is_string, None), str),
        "password":
        Formatter.from_callables(
            partial(oas30_format_checker.check, format="password"), str),
        "date":
        Formatter.from_callables(
            partial(oas30_format_checker.check, format="date"), format_date),
        "date-time":
        Formatter.from_callables(
            partial(oas30_format_checker.check, format="date-time"),
            parse_datetime,
        ),
        "binary":
        Formatter.from_callables(
            partial(oas30_format_checker.check, format="binary"), bytes),
        "uuid":
        Formatter.from_callables(
            partial(oas30_format_checker.check, format="uuid"), format_uuid),
        "byte":
        Formatter.from_callables(
            partial(oas30_format_checker.check, format="byte"), format_byte),
    }
Пример #6
0
class StringUnmarshaller(PrimitiveTypeUnmarshaller):

    FORMATTERS = {
        SchemaFormat.NONE:
        Formatter.from_callables(partial(is_string, None), text_type),
        SchemaFormat.PASSWORD:
        Formatter.from_callables(
            partial(oas30_format_checker.check, format='password'), text_type),
        SchemaFormat.DATE:
        Formatter.from_callables(
            partial(oas30_format_checker.check, format='date'), format_date),
        SchemaFormat.DATETIME:
        Formatter.from_callables(
            partial(oas30_format_checker.check, format='date-time'),
            parse_datetime),
        SchemaFormat.BINARY:
        Formatter.from_callables(
            partial(oas30_format_checker.check, format='binary'), binary_type),
        SchemaFormat.UUID:
        Formatter.from_callables(
            partial(oas30_format_checker.check, format='uuid'), format_uuid),
        SchemaFormat.BYTE:
        Formatter.from_callables(
            partial(oas30_format_checker.check, format='byte'), format_byte),
    }
Пример #7
0
class StringUnmarshaller(PrimitiveTypeUnmarshaller):

    FORMATTERS = {
        None:
        Formatter.from_callables(partial(is_string, None), text_type),
        'password':
        Formatter.from_callables(
            partial(oas30_format_checker.check, format='password'), text_type),
        'date':
        Formatter.from_callables(
            partial(oas30_format_checker.check, format='date'), format_date),
        'date-time':
        Formatter.from_callables(
            partial(oas30_format_checker.check, format='date-time'),
            parse_datetime),
        'binary':
        Formatter.from_callables(
            partial(oas30_format_checker.check, format='binary'), binary_type),
        'uuid':
        Formatter.from_callables(
            partial(oas30_format_checker.check, format='uuid'), format_uuid),
        'byte':
        Formatter.from_callables(
            partial(oas30_format_checker.check, format='byte'), format_byte),
    }
Пример #8
0
class ArrayUnmarshaller(ComplexUnmarshaller):

    FORMATTERS = {
        None: Formatter.from_callables(partial(is_array, None), list),
    }

    @property
    def items_unmarshaller(self):
        return self.unmarshallers_factory.create(self.schema / "items")

    def __call__(self, value):
        value = super().__call__(value)
        if value is None and self.schema.getkey("nullable", False):
            return None
        return list(map(self.items_unmarshaller, value))
Пример #9
0
class ArrayUnmarshaller(ComplexUnmarshaller):

    FORMATTERS = {
        SchemaFormat.NONE: Formatter.from_callables(partial(is_array, None),
                                                    list),
    }

    @property
    def items_unmarshaller(self):
        return self.unmarshallers_factory.create(self.schema.items)

    def __call__(self, value=NoValue):
        value = super(ArrayUnmarshaller, self).__call__(value)

        return list(map(self.items_unmarshaller, value))
Пример #10
0
class AnyUnmarshaller(ComplexUnmarshaller):

    FORMATTERS = {
        SchemaFormat.NONE: Formatter(),
    }

    SCHEMA_TYPES_ORDER = [
        SchemaType.OBJECT,
        SchemaType.ARRAY,
        SchemaType.BOOLEAN,
        SchemaType.INTEGER,
        SchemaType.NUMBER,
        SchemaType.STRING,
    ]

    def __call__(self, value=NoValue):
        one_of_schema = self._get_one_of_schema(value)
        if one_of_schema:
            return self.unmarshallers_factory.create(one_of_schema)(value)

        for schema_type in self.SCHEMA_TYPES_ORDER:
            unmarshaller = self.unmarshallers_factory.create(
                self.schema, type_override=schema_type)
            # validate with validator of formatter (usualy type validator)
            try:
                unmarshaller._formatter_validate(value)
            except ValidateError:
                continue
            else:
                return unmarshaller(value)

        log.warning("failed to unmarshal any type")
        return value

    def _get_one_of_schema(self, value):
        if not self.schema.one_of:
            return
        for subschema in self.schema.one_of:
            unmarshaller = self.unmarshallers_factory.create(subschema)
            try:
                unmarshaller.validate(value)
            except ValidateError:
                continue
            else:
                return subschema
Пример #11
0
class BaseSchemaUnmarshaller:

    FORMATTERS = {
        None: Formatter(),
    }

    def __init__(self, schema):
        self.schema = schema

    def __call__(self, value):
        if value is None:
            return

        self.validate(value)

        return self.unmarshal(value)

    def validate(self, value):
        raise NotImplementedError

    def unmarshal(self, value):
        raise NotImplementedError
Пример #12
0
class ObjectUnmarshaller(ComplexUnmarshaller):

    FORMATTERS = {
        None: Formatter.from_callables(partial(is_object, None), dict),
    }

    @property
    def model_factory(self):
        return ModelFactory()

    def unmarshal(self, value):
        try:
            value = self.formatter.unmarshal(value)
        except ValueError as exc:
            raise InvalidSchemaFormatValue(value, self.schema.format, exc)
        else:
            return self._unmarshal_object(value)

    def _unmarshal_object(self, value):
        if "oneOf" in self.schema:
            properties = None
            for one_of_schema in self.schema / "oneOf":
                try:
                    unmarshalled = self._unmarshal_properties(
                        value, one_of_schema)
                except (UnmarshalError, ValueError):
                    pass
                else:
                    if properties is not None:
                        log.warning("multiple valid oneOf schemas found")
                        continue
                    properties = unmarshalled

            if properties is None:
                log.warning("valid oneOf schema not found")

        else:
            properties = self._unmarshal_properties(value)

        if "x-model" in self.schema:
            name = self.schema["x-model"]
            return self.model_factory.create(properties, name=name)

        return properties

    def _unmarshal_properties(self, value, one_of_schema=None):
        all_props = get_all_properties(self.schema)
        all_props_names = get_all_properties_names(self.schema)

        if one_of_schema is not None:
            all_props.update(get_all_properties(one_of_schema))
            all_props_names |= get_all_properties_names(one_of_schema)

        value_props_names = list(value.keys())
        extra_props = set(value_props_names) - set(all_props_names)

        properties = {}
        additional_properties = self.schema.getkey("additionalProperties",
                                                   True)
        if isinstance(additional_properties, dict):
            additional_prop_schema = self.schema / "additionalProperties"
            for prop_name in extra_props:
                prop_value = value[prop_name]
                properties[prop_name] = self.unmarshallers_factory.create(
                    additional_prop_schema)(prop_value)
        elif additional_properties is True:
            for prop_name in extra_props:
                prop_value = value[prop_name]
                properties[prop_name] = prop_value

        for prop_name, prop in list(all_props.items()):
            read_only = prop.getkey("readOnly", False)
            if self.context == UnmarshalContext.REQUEST and read_only:
                continue
            write_only = prop.getkey("writeOnly", False)
            if self.context == UnmarshalContext.RESPONSE and write_only:
                continue
            try:
                prop_value = value[prop_name]
            except KeyError:
                if "default" not in prop:
                    continue
                prop_value = prop["default"]

            properties[prop_name] = self.unmarshallers_factory.create(prop)(
                prop_value)

        return properties
Пример #13
0
class BooleanUnmarshaller(PrimitiveTypeUnmarshaller):

    FORMATTERS = {
        None: Formatter.from_callables(partial(is_bool, None), forcebool),
    }
Пример #14
0
class ObjectUnmarshaller(ComplexUnmarshaller):

    FORMATTERS = {
        SchemaFormat.NONE:
        Formatter.from_callables(partial(is_object, None), dict),
    }

    @property
    def model_factory(self):
        return ModelFactory()

    def unmarshal(self, value):
        try:
            value = self.formatter.unmarshal(value)
        except ValueError as exc:
            raise InvalidSchemaFormatValue(value, self.schema.format, exc)
        else:
            return self._unmarshal_object(value)

    def _unmarshal_object(self, value=NoValue):
        if self.schema.one_of:
            properties = None
            for one_of_schema in self.schema.one_of:
                try:
                    unmarshalled = self._unmarshal_properties(
                        value, one_of_schema)
                except (UnmarshalError, ValueError):
                    pass
                else:
                    if properties is not None:
                        log.warning("multiple valid oneOf schemas found")
                        continue
                    properties = unmarshalled

            if properties is None:
                log.warning("valid oneOf schema not found")

        else:
            properties = self._unmarshal_properties(value)

        if 'x-model' in self.schema.extensions:
            extension = self.schema.extensions['x-model']
            return self.model_factory.create(properties, name=extension.value)

        return properties

    def _unmarshal_properties(self, value=NoValue, one_of_schema=None):
        all_props = self.schema.get_all_properties()
        all_props_names = self.schema.get_all_properties_names()

        if one_of_schema is not None:
            all_props.update(one_of_schema.get_all_properties())
            all_props_names |= one_of_schema.\
                get_all_properties_names()

        value_props_names = value.keys()
        extra_props = set(value_props_names) - set(all_props_names)

        properties = {}
        if isinstance(self.schema.additional_properties, Schema):
            for prop_name in extra_props:
                prop_value = value[prop_name]
                properties[prop_name] = self.unmarshallers_factory.create(
                    self.schema.additional_properties)(prop_value)
        elif self.schema.additional_properties is True:
            for prop_name in extra_props:
                prop_value = value[prop_name]
                properties[prop_name] = prop_value

        for prop_name, prop in iteritems(all_props):
            if self.context == UnmarshalContext.REQUEST and prop.read_only:
                continue
            if self.context == UnmarshalContext.RESPONSE and prop.write_only:
                continue
            try:
                prop_value = value[prop_name]
            except KeyError:
                if prop.default is NoValue:
                    continue
                prop_value = prop.default

            properties[prop_name] = self.unmarshallers_factory.create(prop)(
                prop_value)

        return properties
Пример #15
0
        if not isinstance(value, str):
            return False

        if not value:
            return True

        return self.regex.match(value)


CUSTOM_FORMATTERS = {
    'uri':
    Formatter.from_callables(
        RegexValidator(
            r'^(?:http|ftp)s?://'
            r'(?:(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+(?:[A-Z]{2,6}\.?|[A-Z0-9-]{2,}\.?)|'  # noqa: E501
            r'localhost|'
            r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})'
            r'(?::\d+)?'
            r'(?:/?|[/?]\S+)$', ),
        str,
    ),
    'iso8601':
    Formatter.from_callables(
        RegexValidator(r'^\d{4}-\d\d-\d\dT\d\d:\d\d:\d\d\.\d{6}$'),
        str,
    ),
    'email':
    Formatter.from_callables(
        RegexValidator(r'[^@]+@[^@]+\.[^@]+'),
        str,
    ),
}
Пример #16
0
class AnyUnmarshaller(ComplexUnmarshaller):

    FORMATTERS = {
        None: Formatter(),
    }

    SCHEMA_TYPES_ORDER = [
        'object',
        'array',
        'boolean',
        'integer',
        'number',
        'string',
    ]

    def unmarshal(self, value=NoValue):
        one_of_schema = self._get_one_of_schema(value)
        if one_of_schema:
            return self.unmarshallers_factory.create(one_of_schema)(value)

        all_of_schema = self._get_all_of_schema(value)
        if all_of_schema:
            return self.unmarshallers_factory.create(all_of_schema)(value)

        for schema_type in self.SCHEMA_TYPES_ORDER:
            unmarshaller = self.unmarshallers_factory.create(
                self.schema, type_override=schema_type)
            # validate with validator of formatter (usualy type validator)
            try:
                unmarshaller._formatter_validate(value)
            except ValidateError:
                continue
            else:
                return unmarshaller(value)

        log.warning("failed to unmarshal any type")
        return value

    def _get_one_of_schema(self, value):
        if 'oneOf' not in self.schema:
            return

        one_of_schemas = self.schema / 'oneOf'
        for subschema in one_of_schemas:
            unmarshaller = self.unmarshallers_factory.create(subschema)
            try:
                unmarshaller.validate(value)
            except ValidateError:
                continue
            else:
                return subschema

    def _get_all_of_schema(self, value):
        if 'allOf' not in self.schema:
            return

        all_of_schemas = self.schema / 'allOf'
        for subschema in all_of_schemas:
            if 'type' not in subschema:
                continue
            unmarshaller = self.unmarshallers_factory.create(subschema)
            try:
                unmarshaller.validate(value)
            except ValidateError:
                continue
            else:
                return subschema