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), }
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), }
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), }
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), }
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), }
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), }
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), }
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))
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))
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
class BooleanUnmarshaller(PrimitiveTypeUnmarshaller): FORMATTERS = { None: Formatter.from_callables(partial(is_bool, None), forcebool), }
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
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, ), }