Liaison is a Python library for defining schemas, parsing and validating payloads
Project description
Liaison
A zero dependency Python library for defining schemas, parsing and validating payloads.
Liaison doesn't aim to be too clever. It doesn't use descriptors, fancy metaprogramming or type hints for defining
your schema. Simply inherit from the Schema base class, define your fields and call parse. In return, you'll
receive a simple Namespace object containing your parsed data.
Goals:
- Simplicity
- Extensibility
- Speed
- 100% test coverage
Installation:
pip install liaison
Example:
from liaison import Schema, ValidationError
from liaison.fields import StringField, IntField, BoolField, ListField, DateTimeField
class UserSchema(Schema):
name = StringField(required=True)
email = StringField(required=True)
age = IntField(min_val=18)
date_of_birth = DateTimeField(date_format="%d-%m-%Y")
subscribed = BoolField(default=False)
tags = ListField(min_len=1)
data = {
"name": "Bar",
"email": "foo@bar.com",
"age": 21,
"tags": ["Python"]
}
result = UserSchema.parse(data)
print(result.name, result.email, result.age, result.tags) # Bar foo@bar.com 21 ['Python']
Handling validation errors:
data = {
"name": "Bar",
"email": "foo@bar.com",
"age": 16
}
try:
result = UserSchema.parse(data)
except ValidationError as e:
print(e) # Value for 'age' must be at least 18
Defining custom field validators via the <field>.validator decorator:
class UserSchema(Schema):
name = StringField(required=True)
email = StringField(required=True)
age = IntField(min_val=18)
@name.validator
def validate_name(self, key, value):
# Define a custom validator, overrides the default validation method
if value == "Foo":
raise ValidationError(f"'{value}' is not a valid value for '{key}'")
return value
Custom validators can also be passed as a parameter to the field:
def name_validator(schema_cls, key, value):
if value in ("Foo", "Bar", "Baz"):
raise ValidationError(f"'{value}' is not a valid value for '{key}'")
return value
class UserSchema(Schema):
name = StringField(required=True, validator=name_validator)
email = StringField(required=True)
age = IntField(min_val=18)
Fields
Use fields to define your schema. By default, all fields accept the following common parameters:
| Parameter | Type | Description | Default |
|---|---|---|---|
required |
bool |
If the value is required | False |
default |
Any |
A default value | None |
choices |
List[Any] |
A list of choices | None |
validator |
Callable |
A function to override the default validation method | None |
strict_type |
bool |
If True, only accept the fields data type |
False |
StringField - Defining strings
| Parameter | Type | Description | Default |
|---|---|---|---|
min_len |
int |
The minimum length | None |
max_len |
int |
The maximum length | None |
IntField - Defining integers
| Parameter | Type | Description | Default |
|---|---|---|---|
min_val |
int |
The minimum value | None |
max_val |
int |
The maximum value | None |
FloatField - Defining floats
| Parameter | Type | Description | Default |
|---|---|---|---|
min_val |
int |
The minimum value | None |
max_val |
int |
The maximum value | None |
BoolField - Defining booleans
ListField - Defining lists
| Parameter | Type | Description | Default |
|---|---|---|---|
min_len |
int |
The minimum length | None |
max_len |
int |
The maximum length | None |
SetField - Defining sets
Note -
SetFieldshares the same behaviour asListField, returning aset.
| Parameter | Type | Description | Default |
|---|---|---|---|
min_len |
int |
The minimum length | None |
max_len |
int |
The maximum length | None |
DictField - Defining dictionaries
| Parameter | Type | Description | Default |
|---|---|---|---|
min_len |
int |
The minimum length | None |
max_len |
int |
The maximum length | None |
DateTimeField - Defining datetimes
Note -
DateTimeFieldfields will returndatetimeobjects
| Parameter | Type | Description |
|---|---|---|
date_format |
str |
The date format |
UUIDField - Defining UUIDs
Note -
UUIDFieldfields will NOT return aUUIDobejct, it will return a string.
Namespace
Calling the parse method on a Schema object will return a Namespace object, holding the parsed values as
attributes.
from liaison import Schema
from liaison.fields import StringField, IntField, BoolField, FloatField, UUIDField
class RESTBaseSchema(Schema):
offset = IntField(min_val=0, default=0)
limit = IntField(max_val=100)
search = StringField()
class ProductsRESTSchema(RESTBaseSchema):
product_id = UUIDField()
category = StringField()
price = FloatField()
in_stock = BoolField()
payload = {
"offset": 10,
"category": "shoes",
"in_stock": True
}
result = ProductsRESTSchema.parse(payload)
print(result.offset, result.limit, result.search, result.category, result.in_stock)
# 10 None None shoes True
Namespace objects have a to_dict method, returning a dictionary of the Namespace attributes and values:
print(result.to_dict())
# {'category': 'shoes', 'in_stock': True, 'limit': None, 'offset': 10, 'price': None, 'product_id': None, 'search': None}
An optional exclude parameter can be included to exclude certain attributes:
print(result.to_dict(exclude=("offset", "limit", "search")))
# {'category': 'shoes', 'in_stock': True, 'price': None, 'product_id': None}
Defining custom fields
Create your own fields and validation logic by inheriting from any of the field classes and implementing a
validate method.
Note - The
validatemethod must accept 2 params (key, value)
from liaison import Schema, ValidationError
from liaison.fields import StringField
class PasswordField(StringField):
def validate(self, key, value):
value = super().validate(key, value)
if len(value) < 9:
raise ValidationError("Value for 'password' must be at least 9 characters in length")
# etc...
return value
class UserSchema(Schema):
username = StringField(required=True)
password = PasswordField()
payload = {
"username": "FooBar",
"password": "password"
}
try:
result = UserSchema.parse(payload)
except ValidationError as e:
print(e) # Value for 'password' must be at least 9 characters in length
payload = {
"username": "FooBar",
"password": "password12345!"
}
result = UserSchema.parse(payload)
print(result.password) # password12345!
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file liaison-0.3.tar.gz.
File metadata
- Download URL: liaison-0.3.tar.gz
- Upload date:
- Size: 5.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.4.2 importlib_metadata/4.8.1 pkginfo/1.7.1 requests/2.26.0 requests-toolbelt/0.9.1 tqdm/4.62.3 CPython/3.9.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ad8092967d7b38ef1157ee390bb73c3e27ca2b64e609383a66c3418f25e9e143
|
|
| MD5 |
3c47a01fe4c1eaf2229fc2ecad018f85
|
|
| BLAKE2b-256 |
b7ff3849cd1aab615d9d472f704c3a68378431c6604f3e730b16151dd2283f16
|
File details
Details for the file liaison-0.3-py3-none-any.whl.
File metadata
- Download URL: liaison-0.3-py3-none-any.whl
- Upload date:
- Size: 6.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.4.2 importlib_metadata/4.8.1 pkginfo/1.7.1 requests/2.26.0 requests-toolbelt/0.9.1 tqdm/4.62.3 CPython/3.9.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
35ab3d77ed116bdf72e18cfc56ab64fcda7ceff642c0ab226384a9b63222862a
|
|
| MD5 |
9cfe5561729789d09ccefdd1cf44105a
|
|
| BLAKE2b-256 |
59ded0b6c4e9152b147cbbb3e9aa5bd74602a737aabfa17b826919c273c17cd8
|