Specialized Data Formats
This guide demonstrates how to validate specialized data formats such as URLs, UUIDs, Enums, and JSON strings using pydantic-core. These schemas provide high-performance validation and often return specialized objects for easier manipulation.
Identity and Type Checks
You can validate that a value matches a specific literal value or is an instance/subclass of a specific Python class.
Literal Values
Use literal_schema to ensure a value is exactly one of the expected values.
from pydantic_core import SchemaValidator, core_schema
# Define a schema for specific allowed strings
schema = core_schema.literal_schema(['apple', 'banana'])
v = SchemaValidator(schema)
assert v.validate_python('apple') == 'apple'
# v.validate_python('orange') # Raises ValidationError
Instance and Subclass Checks
Use is_instance_schema and is_subclass_schema to perform standard Python type checks. Note that these require Python objects and cannot validate raw JSON strings directly.
from pydantic_core import SchemaValidator, core_schema
class Animal:
pass
class Dog(Animal):
pass
# Check if value is an instance of Animal
instance_schema = core_schema.is_instance_schema(cls=Animal)
v_instance = SchemaValidator(instance_schema)
dog = Dog()
assert v_instance.validate_python(dog) is dog
# Check if value is a subclass of Animal
subclass_schema = core_schema.is_subclass_schema(cls=Animal)
v_subclass = SchemaValidator(subclass_schema)
assert v_subclass.validate_python(Dog) is Dog
Enumerations
The enum_schema validates that a value belongs to a specific Python Enum. You must explicitly provide the enum members.
from enum import Enum
from pydantic_core import SchemaValidator, core_schema
class Status(Enum):
ACTIVE = 'active'
PENDING = 'pending'
# Define schema with the Enum class and its members
schema = core_schema.enum_schema(
Status,
list(Status.__members__.values())
)
v = SchemaValidator(schema)
assert v.validate_python('active') is Status.ACTIVE
assert v.validate_python(Status.PENDING) is Status.PENDING
Coercion with Sub-types
If your Enum inherits from str or int, use the sub_type parameter to enable coercion from the base type.
class IntStatus(int, Enum):
ON = 1
OFF = 0
schema = core_schema.enum_schema(
IntStatus,
list(IntStatus.__members__.values()),
sub_type='int'
)
v = SchemaValidator(schema)
# Coerces the integer 1 to IntStatus.ON
assert v.validate_python(1) is IntStatus.ON
Network and Identifiers
pydantic-core provides specialized validators for URLs and UUIDs that return optimized objects.
URLs
The url_schema validates URL strings and returns a pydantic_core.Url object. You can constrain allowed schemes and require specific components.
from pydantic_core import SchemaValidator, core_schema
schema = core_schema.url_schema(
allowed_schemes=['https', 'ftp'],
host_required=True,
default_path='/api'
)
v = SchemaValidator(schema)
url = v.validate_python('https://example.com')
assert str(url) == 'https://example.com/api'
assert url.scheme == 'https'
assert url.host == 'example.com'
Multi-Host URLs
For connection strings that support multiple hosts (like Redis or Postgres clusters), use multi_host_url_schema.
from pydantic_core import SchemaValidator, core_schema
schema = core_schema.multi_host_url_schema(allowed_schemes=['redis'])
v = SchemaValidator(schema)
url = v.validate_python('redis://host1:6379,host2:6379/0')
assert url.scheme == 'redis'
assert len(url.hosts()) == 2
UUIDs
The uuid_schema validates UUIDs and can be restricted to specific versions (1, 3, 4, 5, 7).
from pydantic_core import SchemaValidator, core_schema
# Validate only UUID v4
schema = core_schema.uuid_schema(version=4)
v = SchemaValidator(schema)
import uuid
val = uuid.uuid4()
assert v.validate_python(str(val)) == val
JSON Strings
The json_schema is used when a field contains a stringified JSON object that needs to be parsed and then validated against an inner schema.
from pydantic_core import SchemaValidator, core_schema
# Inner schema for the parsed JSON content
inner_schema = core_schema.dict_schema(
core_schema.str_schema(),
core_schema.int_schema()
)
# Schema that expects a JSON string
schema = core_schema.json_schema(schema=inner_schema)
v = SchemaValidator(schema)
# Validates a string, parses it as JSON, then validates the dict
result = v.validate_python('{"count": 42}')
assert result == {"count": 42}
Troubleshooting
Needs Python Object
If you use is_instance_schema or is_subclass_schema with JSON input, you will encounter a needs_python_object error. These validators only work on Python objects. To validate these from JSON, you must use a before validator to instantiate the object first.
Enum Members Requirement
The enum_schema requires the members list to be passed explicitly. If you add new members to your Enum, ensure you update the schema or use list(MyEnum.__members__.values()) dynamically when building the schema.
URL Path Normalization
By default, url_schema converts empty paths to /. If you need to preserve the empty path, set preserve_empty_path=True in the url_schema configuration.
schema = core_schema.url_schema(preserve_empty_path=True)
v = SchemaValidator(schema)
assert str(v.validate_python('https://example.com')) == 'https://example.com'