Python lib/cli for JSON/YAML schema validation
—
PyKwalify provides comprehensive type checking and validation utilities for all supported data types including scalars, collections, timestamps, dates, emails, and URLs with built-in validation functions.
Core type validation functions that determine if an object matches a specific type.
def is_string(obj):
"""
Check if object is a string.
Args:
obj: Object to check
Returns:
bool: True if object is string or bytes
"""
def is_int(obj):
"""
Check if object is an integer.
Note: True and False are not considered valid integers.
Args:
obj: Object to check
Returns:
bool: True if object is int and not bool
"""
def is_float(obj):
"""
Check if object is a float or string convertible to float.
Args:
obj: Object to check
Returns:
bool: True if object is float or string convertible to float (excluding bools)
"""
def is_bool(obj):
"""
Check if object is a boolean.
Args:
obj: Object to check
Returns:
bool: True if object is bool
"""
def is_number(obj):
"""
Check if object is a number (int or float).
Args:
obj: Object to check
Returns:
bool: True if object is int or float
"""def is_collection(obj):
"""
Check if object is a collection (dict or list).
Args:
obj: Object to check
Returns:
bool: True if object is dict or list
"""
def is_scalar(obj):
"""
Check if object is a scalar (not collection and not None).
Args:
obj: Object to check
Returns:
bool: True if object is not collection and not None
"""
def is_sequence_alias(alias):
"""
Check if alias represents a sequence type.
Args:
alias (str): Type alias to check
Returns:
bool: True if alias is in sequence_aliases
"""
def is_mapping_alias(alias):
"""
Check if alias represents a mapping type.
Args:
alias (str): Type alias to check
Returns:
bool: True if alias is in mapping_aliases
"""def is_text(obj):
"""
Check if object is text (string or number, but not bool).
Args:
obj: Object to check
Returns:
bool: True if object is string or number and not bool
"""
def is_any(obj):
"""
Always returns True - accepts any object.
Args:
obj: Object to check (ignored)
Returns:
bool: Always True
"""
def is_enum(obj):
"""
Check if object is valid for enum validation.
Args:
obj: Object to check
Returns:
bool: True if object is string
"""
def is_none(obj):
"""
Check if object is None.
Args:
obj: Object to check
Returns:
bool: True if object is None
"""def is_timestamp(obj):
"""
Check if object is a valid timestamp.
Accepts datetime objects, strings, integers, or floats.
Args:
obj: Object to check
Returns:
bool: True if object is valid timestamp format
"""
def is_date(obj):
"""
Check if object is a valid date.
Args:
obj: Object to check
Returns:
bool: True if object is string or datetime.date
"""def is_email(obj):
"""
Check if object matches email format using regex.
Args:
obj: Object to check
Returns:
bool: True if object matches email regex pattern
"""
def is_url(obj):
"""
Check if object matches URL format using regex.
Args:
obj: Object to check
Returns:
bool: True if object matches HTTP/HTTPS URL pattern
"""def type_class(type):
"""
Get Python class for type name.
Args:
type (str): Type name
Returns:
type: Corresponding Python class
"""
def is_builtin_type(type):
"""
Check if type is a built-in PyKwalify type.
Args:
type (str): Type name
Returns:
bool: True if type is in built-in types
"""
def is_collection_type(type):
"""
Check if type represents a collection.
Args:
type (str): Type name
Returns:
bool: True if type is 'map' or 'seq'
"""
def is_scalar_type(type):
"""
Check if type represents a scalar.
Args:
type (str): Type name
Returns:
bool: True if type is not collection type
"""
def is_correct_type(obj, type):
"""
Check if object is instance of given type.
Args:
obj: Object to check
type: Python type class
Returns:
bool: True if isinstance(obj, type)
"""DEFAULT_TYPE: str # Default type string ("str")
_types: dict # Mapping of type names to Python classes
"""
{
"str": str,
"int": int,
"float": float,
"number": None,
"bool": bool,
"map": dict,
"seq": list,
"timestamp": datetime.datetime,
"date": datetime.date,
"symbol": str,
"scalar": None,
"text": text,
"any": object,
"enum": str,
"none": None,
"email": str,
"url": str,
}
"""
sequence_aliases: list # ["sequence", "seq"]
mapping_aliases: list # ["map", "mapping"]
tt: dict # Mapping of type names to validation functions
"""
{
"str": is_string,
"int": is_int,
"bool": is_bool,
"float": is_float,
"number": is_number,
"text": is_text,
"any": is_any,
"enum": is_enum,
"none": is_none,
"timestamp": is_timestamp,
"scalar": is_scalar,
"date": is_date,
"email": is_email,
"url": is_url,
}
"""class TextMeta(type):
"""Metaclass for text type that implements custom instance checking."""
def __instancecheck__(self, instance):
return is_text(instance)
class text(object):
"""Special text type class for PyKwalify text validation."""
__metaclass__ = TextMetafrom pykwalify.types import is_string, is_int, is_float, is_bool
# Test various values
values = ["hello", 42, 3.14, True, False, None, [], {}]
for value in values:
print(f"Value: {value}")
print(f" String: {is_string(value)}")
print(f" Int: {is_int(value)}")
print(f" Float: {is_float(value)}")
print(f" Bool: {is_bool(value)}")
print()from pykwalify.types import is_collection, is_scalar, is_sequence_alias, is_mapping_alias
# Test collection types
test_values = [
{"name": "dict"},
["list", "items"],
"string",
42,
None
]
for value in test_values:
print(f"Value: {value}")
print(f" Collection: {is_collection(value)}")
print(f" Scalar: {is_scalar(value)}")
# Test type aliases
aliases = ["seq", "sequence", "map", "mapping", "list", "dict"]
for alias in aliases:
print(f"'{alias}' - Sequence: {is_sequence_alias(alias)}, Mapping: {is_mapping_alias(alias)}")from pykwalify.types import is_email, is_url, is_timestamp, is_date
from datetime import datetime, date
# Email validation
emails = ["test@example.com", "invalid-email", "user@domain.co.uk"]
for email in emails:
print(f"'{email}' is email: {is_email(email)}")
# URL validation
urls = ["https://example.com", "http://test.org", "not-a-url", "ftp://invalid.com"]
for url in urls:
print(f"'{url}' is URL: {is_url(url)}")
# Timestamp validation
timestamps = [datetime.now(), "2023-01-01T10:00:00", 1640995200, "invalid"]
for ts in timestamps:
print(f"'{ts}' is timestamp: {is_timestamp(ts)}")
# Date validation
dates = [date.today(), "2023-01-01", datetime.now(), 123]
for d in dates:
print(f"'{d}' is date: {is_date(d)}")from pykwalify.types import (
type_class, is_builtin_type, is_collection_type,
is_scalar_type, is_correct_type, tt
)
# Get Python class for type
print(f"'str' class: {type_class('str')}")
print(f"'int' class: {type_class('int')}")
print(f"'map' class: {type_class('map')}")
# Check built-in types
types_to_test = ["str", "int", "custom_type", "email", "unknown"]
for type_name in types_to_test:
print(f"'{type_name}' is builtin: {is_builtin_type(type_name)}")
# Check collection vs scalar types
for type_name in ["str", "int", "map", "seq", "float"]:
print(f"'{type_name}' - Collection: {is_collection_type(type_name)}, Scalar: {is_scalar_type(type_name)}")
# Use validation function mapping
value = "test@example.com"
validator = tt.get("email")
if validator:
print(f"Email validation result: {validator(value)}")from pykwalify.types import is_text, is_number, is_any, is_none
# Text type (string or number, not bool)
test_values = ["hello", 42, 3.14, True, False, [], None]
for value in test_values:
print(f"'{value}' is text: {is_text(value)}")
# Number type (int or float)
for value in test_values:
print(f"'{value}' is number: {is_number(value)}")
# Any type (always True)
for value in test_values:
print(f"'{value}' is any: {is_any(value)}")
# None checking
for value in test_values:
print(f"'{value}' is none: {is_none(value)}")from pykwalify.core import Core
from pykwalify.types import is_email
# Define data with various types
data = {
"name": "John Doe",
"age": 30,
"score": 95.5,
"active": True,
"email": "john@example.com",
"website": "https://johndoe.com",
"tags": ["python", "validation"],
"metadata": None
}
# Schema using various PyKwalify types
schema = {
"type": "map",
"mapping": {
"name": {"type": "str"},
"age": {"type": "int"},
"score": {"type": "float"},
"active": {"type": "bool"},
"email": {"type": "email"},
"website": {"type": "url"},
"tags": {
"type": "seq",
"sequence": [{"type": "str"}]
},
"metadata": {"type": "any", "nullable": True}
}
}
# Validate using Core
c = Core(source_data=data, schema_data=schema)
try:
c.validate(raise_exception=True)
print("All type validations passed!")
except Exception as e:
print(f"Type validation failed: {e}")Install with Tessl CLI
npx tessl i tessl/pypi-pykwalify