def string_to_boolean(value): validator = Boolean() value, error = validator.validate_or_error(value) if value is None: return False else: return value
def test_union(): validator = Union(any_of=[Integer(), String()]) value, error = validator.validate_or_error("abc") assert value == "abc" assert error is None validator = Union(any_of=[Integer(), String()]) value, error = validator.validate_or_error(123) assert value == 123 assert error is None validator = Union(any_of=[Integer(), String()]) value, error = validator.validate_or_error(None) assert value is None assert error == ValidationError(text="May not be null.", code="null") validator = Union(any_of=[Integer(), String()]) value, error = validator.validate_or_error(True) assert value is None assert error == ValidationError(text="Did not match any valid type.", code="union") validator = Union(any_of=[Integer(allow_null=True), String()]) value, error = validator.validate_or_error(None) assert error is None assert value is None validator = Union(any_of=[Integer(), String()], allow_null=True) value, error = validator.validate_or_error(None) assert error is None assert value is None validator = Union(any_of=[Integer(maximum=1000), String()]) value, error = validator.validate_or_error(9999) assert value is None assert error == ValidationError(text="Must be less than or equal to 1000.", code="maximum") validator = Integer() | String() | Boolean() value, error = validator.validate_or_error(123) assert value == 123 validator = Integer() | (String() | Boolean()) value, error = validator.validate_or_error(123) assert value == 123
def from_json_schema_type(data: dict, type_string: str, allow_null: bool, definitions: SchemaDefinitions) -> Field: """ Build a typed field from a JSON schema object. """ if type_string == "number": kwargs = { "allow_null": allow_null, "minimum": data.get("minimum", None), "maximum": data.get("maximum", None), "exclusive_minimum": data.get("exclusiveMinimum", None), "exclusive_maximum": data.get("exclusiveMaximum", None), "multiple_of": data.get("multipleOf", None), "default": data.get("default", NO_DEFAULT), } return Float(**kwargs) elif type_string == "integer": kwargs = { "allow_null": allow_null, "minimum": data.get("minimum", None), "maximum": data.get("maximum", None), "exclusive_minimum": data.get("exclusiveMinimum", None), "exclusive_maximum": data.get("exclusiveMaximum", None), "multiple_of": data.get("multipleOf", None), "default": data.get("default", NO_DEFAULT), } return Integer(**kwargs) elif type_string == "string": min_length = data.get("minLength", 0) kwargs = { "allow_null": allow_null, "allow_blank": min_length == 0, "min_length": min_length if min_length > 1 else None, "max_length": data.get("maxLength", None), "format": data.get("format"), "pattern": data.get("pattern", None), "default": data.get("default", NO_DEFAULT), } return String(**kwargs) elif type_string == "boolean": kwargs = { "allow_null": allow_null, "default": data.get("default", NO_DEFAULT) } return Boolean(**kwargs) elif type_string == "array": items = data.get("items", None) if items is None: items_argument: typing.Union[None, Field, typing.List[Field]] = None elif isinstance(items, list): items_argument = [ from_json_schema(item, definitions=definitions) for item in items ] else: items_argument = from_json_schema(items, definitions=definitions) additional_items = data.get("additionalItems", None) if additional_items is None: additional_items_argument: typing.Union[bool, Field] = True elif isinstance(additional_items, bool): additional_items_argument = additional_items else: additional_items_argument = from_json_schema( additional_items, definitions=definitions) kwargs = { "allow_null": allow_null, "min_items": data.get("minItems", 0), "max_items": data.get("maxItems", None), "additional_items": additional_items_argument, "items": items_argument, "unique_items": data.get("uniqueItems", False), "default": data.get("default", NO_DEFAULT), } return Array(**kwargs) elif type_string == "object": properties = data.get("properties", None) if properties is None: properties_argument: typing.Optional[typing.Dict[str, Field]] = None else: properties_argument = { key: from_json_schema(value, definitions=definitions) for key, value in properties.items() } pattern_properties = data.get("patternProperties", None) if pattern_properties is None: pattern_properties_argument: typing.Optional[typing.Dict[ str, Field]] = (None) else: pattern_properties_argument = { key: from_json_schema(value, definitions=definitions) for key, value in pattern_properties.items() } additional_properties = data.get("additionalProperties", None) if additional_properties is None: additional_properties_argument: typing.Union[None, bool, Field] = (None) elif isinstance(additional_properties, bool): additional_properties_argument = additional_properties else: additional_properties_argument = from_json_schema( additional_properties, definitions=definitions) property_names = data.get("propertyNames", None) if property_names is None: property_names_argument: typing.Optional[Field] = None else: property_names_argument = from_json_schema(property_names, definitions=definitions) kwargs = { "allow_null": allow_null, "properties": properties_argument, "pattern_properties": pattern_properties_argument, "additional_properties": additional_properties_argument, "property_names": property_names_argument, "min_properties": data.get("minProperties", None), "max_properties": data.get("maxProperties", None), "required": data.get("required", None), "default": data.get("default", NO_DEFAULT), } return Object(**kwargs) assert False, f"Invalid argument type_string={type_string!r}" # pragma: no cover
Number(), "multipleOf": Number(exclusive_minimum=0), # Object "properties": Object(additional_properties=Reference("JSONSchema", definitions=definitions)), "minProperties": Integer(minimum=0), "maxProperties": Integer(minimum=0), "patternProperties": Object(additional_properties=Reference("JSONSchema", definitions=definitions)), "additionalProperties": ( Reference("JSONSchema", definitions=definitions) | Boolean()), "required": Array(items=String(), unique_items=True), # Array "items": ( Reference("JSONSchema", definitions=definitions) | Array(items=Reference("JSONSchema", definitions=definitions), min_items=1)), "additionalItems": ( Reference("JSONSchema", definitions=definitions) | Boolean()), "minItems": Integer(minimum=0), "maxItems": Integer(minimum=0), "uniqueItems": Boolean(),
def test_array(): validator = Array() value, error = validator.validate_or_error([]) assert value == [] validator = Array() value, error = validator.validate_or_error(None) assert error == ValidationError(text="May not be null.", code="null") validator = Array() value, error = validator.validate_or_error(123) assert error == ValidationError(text="Must be an array.", code="type") validator = Array(allow_null=True) value, error = validator.validate_or_error(None) assert value is None assert error is None validator = Array(min_items=1) value, error = validator.validate_or_error([]) assert error == ValidationError(text="Must not be empty.", code="empty") validator = Array(min_items=1) value, error = validator.validate_or_error([1]) assert value == [1] validator = Array(min_items=2) value, error = validator.validate_or_error([]) assert error == ValidationError(text="Must have at least 2 items.", code="min_items") validator = Array(min_items=2) value, error = validator.validate_or_error([1, 2]) assert value == [1, 2] validator = Array(max_items=2) value, error = validator.validate_or_error([]) assert value == [] validator = Array(max_items=2) value, error = validator.validate_or_error([1, 2, 3]) assert error == ValidationError(text="Must have no more than 2 items.", code="max_items") validator = Array(exact_items=2) value, error = validator.validate_or_error([1, 2]) assert value == [1, 2] validator = Array(exact_items=2) value, error = validator.validate_or_error([1, 2, 3]) assert error == ValidationError(text="Must have 2 items.", code="exact_items") validator = Array(items=Integer()) value, error = validator.validate_or_error(["1", 2, "3"]) assert value == [1, 2, 3] validator = Array(items=Integer()) value, error = validator.validate_or_error(["a", 2, "c"]) assert dict(error) == {0: "Must be a number.", 2: "Must be a number."} validator = Array(items=[String(), Integer()]) value, error = validator.validate_or_error(["a", "b", "c"]) assert error == ValidationError(text="Must have 2 items.", code="exact_items") validator = Array(items=[String(), Integer()]) value, error = validator.validate_or_error(["a", "123"]) assert value == ["a", 123] validator = Array(items=[String(), Integer()], additional_items=Integer()) value, error = validator.validate_or_error(["a", "123", "456"]) assert value == ["a", 123, 456] validator = Array(items=String(), unique_items=True) value, error = validator.validate_or_error(["a", "b"]) assert value == ["a", "b"] validator = Array(items=String(), unique_items=True) value, error = validator.validate_or_error(["a", "a"]) assert dict(error) == {1: "Items must be unique."} validator = Array(items=[String(), Integer(), Boolean()], min_items=1) value, error = validator.validate_or_error(["a"]) assert value == ["a"] validator = Array(items=[String(), Integer(), Boolean()], min_items=1) value, error = validator.validate_or_error(["a", "123"]) assert value == ["a", 123] validator = Array(items=[String(), Integer(), Boolean()], min_items=1) value, error = validator.validate_or_error([]) assert error == ValidationError(text="Must not be empty.", code="empty") validator = Array(items=[String(), Integer(), Boolean()], min_items=2) value, error = validator.validate_or_error([]) assert error == ValidationError(text="Must have at least 2 items.", code="min_items")
def test_boolean(): validator = Boolean() value, error = validator.validate_or_error(True) assert value is True validator = Boolean() value, error = validator.validate_or_error(False) assert value is False validator = Boolean() value, error = validator.validate_or_error("True") assert value is True validator = Boolean() value, error = validator.validate_or_error(1) assert value is True validator = Boolean() value, error = validator.validate_or_error(None) assert error == ValidationError(text="May not be null.", code="null") validator = Boolean() value, error = validator.validate_or_error(2) assert error == ValidationError(text="Must be a boolean.", code="type") validator = Boolean(allow_null=True) value, error = validator.validate_or_error(None) assert value is None assert error is None validator = Boolean(allow_null=True) value, error = validator.validate_or_error("") assert value is None assert error is None validator = Boolean() value, error = validator.validate_or_error("True", strict=True) assert error == ValidationError(text="Must be a boolean.", code="type")