API Reference¶
Data¶
-
lollipop.types.
MISSING
= <MISSING>¶ Special singleton value (like None) to represent case when value is missing.
Types¶
-
class
lollipop.types.
Type
(validate=None, *args, **kwargs)[source]¶ Base class for defining data types.
Parameters: validate (list) – A validator or list of validators for this data type. Validator is a callable that takes serialized data and raises ValidationError
if data is invalid. Validator return value is ignored.-
dump
(value, context=None)[source]¶ Serialize data to primitive types. Raises
ValidationError
if data is invalid.Parameters: - value – Value to serialize.
- context – Context data.
Returns: Serialized data.
Raises:
-
load
(data, context=None)[source]¶ Deserialize data from primitive types. Raises
ValidationError
if data is invalid.Parameters: - data – Data to deserialize.
- context – Context data.
Returns: Loaded data
Raises:
-
-
class
lollipop.types.
Any
(validate=None, *args, **kwargs)[source]¶ Any type. Does not transform/validate given data.
-
class
lollipop.types.
Integer
(validate=None, *args, **kwargs)[source]¶ An integer type.
-
num_type
¶ alias of
int
-
-
class
lollipop.types.
Float
(validate=None, *args, **kwargs)[source]¶ A float type.
-
num_type
¶ alias of
float
-
-
class
lollipop.types.
List
(item_type, **kwargs)[source]¶ A homogenous list type.
Example:
List(String()).load(['foo', 'bar', 'baz'])
Parameters:
-
class
lollipop.types.
Tuple
(item_types, **kwargs)[source]¶ A heterogenous list type.
Example:
Tuple([String(), Integer(), Boolean()]).load(['foo', 123, False])
Parameters: - item_types (list) – List of item types.
- kwargs – Same keyword arguments as for
Type
.
-
class
lollipop.types.
Dict
(value_types=<Any>, **kwargs)[source]¶ A dict type. You can specify either a single type for all dict values or provide a dict-like mapping object that will return proper Type instance for each given dict key.
Example:
Dict(Integer()).load({'key0': 1, 'key1': 5, 'key2': 15}) Dict({'foo': String(), 'bar': Integer()}).load({ 'foo': 'hello', 'bar': 123, })
Parameters:
-
class
lollipop.types.
OneOf
(types, load_hint=<function type_name_hint>, dump_hint=<function type_name_hint>, *args, **kwargs)[source]¶ Example:
class Foo(object): def __init__(self, foo): self.foo = foo class Bar(object): def __init__(self, bar): self.bar = bar FooType = Object({'foo': String()}, constructor=Foo) BarType = Object({'bar': Integer()}, constructor=Bar) def object_with_type(name, subject_type): return Object(subject_type, {'type': name}, constructor=subject_type.constructor) FooBarType = OneOf({ 'Foo': object_with_type('Foo', FooType), 'Bar': object_with_type('Bar', BarType), }, dump_hint=type_name_hint, load_hint=dict_value_hint('type')) List(FooBarType).dump([Foo(foo='hello'), Bar(bar=123)]) # => [{'type': 'Foo', 'foo': 'hello'}, {'type': 'Bar', 'bar': 123}] List(FooBarType).load([{'type': 'Foo', 'foo': 'hello'}, {'type': 'Bar', 'bar': 123}]) # => [Foo(foo='hello'), Bar(bar=123)]
-
lollipop.types.
type_name_hint
(data)[source]¶ Returns type name of given value.
To be used as a type hint in
OneOf
.
-
lollipop.types.
dict_value_hint
(key, mapper=None)[source]¶ Returns a function that takes a dictionary and returns value of particular key. The returned value can be optionally processed by
mapper
function.To be used as a type hint in
OneOf
.
-
class
lollipop.types.
Field
(field_type, *args, **kwargs)[source]¶ Base class for describing
Object
fields. Defines a way to access object fields during serialization/deserialization. Usually it extracts data to serialize/deserialize and callself.field_type.load()
to do data transformation.Parameters: field_type (Type) – Field type. -
dump
(name, obj, *args, **kwargs)[source]¶ Serialize data to primitive types. Raises
ValidationError
if data is invalid.Parameters: - name (str) – Name of attribute to serialize.
- obj – Application object to extract serialized value from.
Returns: Serialized data.
Raises:
-
get_value
(name, obj, context=None)[source]¶ Get value of field
name
from objectobj
.Params str name: Field name. Params obj: Object to get field value from. Returns: Field value.
-
load
(name, data, *args, **kwargs)[source]¶ Deserialize data from primitive types. Raises
ValidationError
if data is invalid.Parameters: - name (str) – Name of attribute to deserialize.
- data – Raw data to get value to deserialize from.
- kwargs – Same keyword arguments as for
Type.load()
.
Returns: Loaded data.
Raises:
-
load_into
(obj, name, data, inplace=True, *args, **kwargs)[source]¶ Deserialize data from primitive types updating existing object. Raises
ValidationError
if data is invalid.Parameters: - obj – Object to update with deserialized data.
- name (str) – Name of attribute to deserialize.
- data – Raw data to get value to deserialize from.
- inplace (bool) – If True update data inplace; otherwise - create new data.
- kwargs – Same keyword arguments as for
load()
.
Returns: Loaded data.
Raises:
-
-
class
lollipop.types.
AttributeField
(field_type, attribute=None, *args, **kwargs)[source]¶ Field that corresponds to object attribute. Subclasses can use
name_to_attribute
field to convert field names to attribute names.Parameters: - field_type (Type) – Field type.
- attribute – Can be either string or callable. If string, use given attribute name instead of field name defined in object type. If callable, should take a single argument - name of field - and return name of corresponding object attribute to obtain value from.
-
class
lollipop.types.
MethodField
(field_type, get=None, set=None, *args, **kwargs)[source]¶ Field that is result of method invocation.
Example:
class Person(object): def __init__(self, first_name, last_name): self.first_name = first_name self.last_name = last_name def get_name(self): return self.first_name + ' ' + self.last_name PersonType = Object({ 'name': MethodField(String(), 'get_name'), }, constructor=Person)
Parameters: - field_type (Type) – Field type.
- get – Can be either string or callable. If string, use target object method with given name to obain value. If callable, should take field name and return name of object method to use. Referenced method should take no argument - new field value to set.
- set – Can be either string or callable. If string, use target object method with given name to set value in object. If callable, should take field name and return name of object method to use. Referenced method should take 1 argument - new field value to set.
- kwargs – Same keyword arguments as for
Field
.
-
class
lollipop.types.
FunctionField
(field_type, get=None, set=None, *args, **kwargs)[source]¶ Field that is result of function invocation.
Example:
class Person(object): def __init__(self, first_name, last_name): self.first_name = first_name self.last_name = last_name def get_name(person): return person.first_name + ' ' + person.last_name PersonType = Object({ 'name': FunctionField(String(), get_name), }, constructor=Person)
Parameters: - field_type (Type) – Field type.
- get (callable) – Function that takes source object and returns field value.
- set (callable) – Function that takes source object and new field value and sets that value to object field. Function return value is ignored.
-
class
lollipop.types.
Object
(bases_or_fields=None, fields=None, constructor=None, default_field_type=None, allow_extra_fields=None, only=None, exclude=None, immutable=None, ordered=None, **kwargs)[source]¶ An object type. Serializes to a dict of field names to serialized field values. Parametrized with field names to types mapping. The way values are obtained during serialization is determined by type of field object in
fields
mapping (seeAttributeField
,MethodField
orFunctionField
for details). You can specify eitherField
object, aType
object or any other value.In case of
Type
, it will be automatically wrapped with a default field type, which is controlled bydefault_field_type
constructor argument.In case of any other value it will be transformed into
Constant
.Example:
class Person(object): def __init__(self, name, age): self.name = name self.age = age PersonType = Object({ 'name': String(), 'age': Integer(), }, constructor=Person) PersonType.load({'name': 'John', 'age': 42}) # => Person(name='John', age=42)
Parameters: - base_or_fields – Either
Object
instance or fields (Seefields
argument). In case of fields, the actual fields argument should not be specified. - fields – List of name-to-value tuples or mapping of object field names to
Type
,Field
objects or constant values. - contructor (callable) – Deserialized value constructor. Constructor should take all fields values as keyword arguments.
- default_field_type (Field) – Default field type to use for fields defined by their type.
- allow_extra_fields (bool) – If False, it will raise
ValidationError
for all extra dict keys during deserialization. If True, will ignore all extra fields. - only – Field name or list of field names to include in this object from it’s base classes. All other base classes’ fields won’t be used. Does not affect own fields.
- exclude – Field name or list of field names to exclude from this object from base classes. All other base classes’ fields will be included. Does not affect own fields.
- ordered (bool) – Serialize data into OrderedDict following fields order. Fields in this case should be declared with a dictionary which also supports ordering or with a list of tuples.
- immutable (bool) – If False, object is allowed to be modified in-place;
if True - always create a copy with
constructor
. - kwargs – Same keyword arguments as for
Type
.
-
load_into
(obj, data, inplace=True, *args, **kwargs)[source]¶ Load data and update existing object.
Parameters: - obj – Object to update with deserialized data.
- data – Raw data to get value to deserialize from.
- inplace (bool) – If True update data inplace; otherwise - create new data.
- kwargs – Same keyword arguments as for
Type.load()
.
Returns: Updated object.
Raises:
-
validate_for
(obj, data, *args, **kwargs)[source]¶ Takes target object and serialized data, tries to update that object with data and validate result. Returns validation errors or None. Object is not updated.
Parameters: - obj – Object to check data validity against. In case the data is partial object is used to get the rest of data from.
- data – Data to validate. Can be partial (not all schema field data is present).
- kwargs – Same keyword arguments as for
Type.load()
.
Returns: validation errors or None
- base_or_fields – Either
-
class
lollipop.types.
Constant
(value, field_type=<Any>, *args, **kwargs)[source]¶ Type that always serializes to given value and checks this value on deserialize.
Parameters: - value – Value constant for this field.
- field_type (Type) – Field type.
-
class
lollipop.types.
Optional
(inner_type, load_default=None, dump_default=None, **kwargs)[source]¶ A wrapper type which makes values optional: if value is missing or None, it will not transform it with an inner type but instead will return None (or any other configured value).
Example:
UserType = Object({ 'email': String(), # by default types require valid values 'name': Optional(String()), # value can be omitted or None 'role': Optional( # when value is omitted or None, use given value String(validate=AnyOf(['admin', 'customer'])), load_default='customer', ), })
Parameters: - inner_type (Type) – Actual type that should be optional.
- load_default – Value or callable. If value - it will be used when value is missing on deserialization. If callable - it will be called with no arguments to get value to use when value is missing on deserialization.
- dump_default – Value or callable. If value - it will be used when value is missing on serialization. If callable - it will be called with no arguments to get value to use when value is missing on serialization.
- kwargs – Same keyword arguments as for
Type
.
Validators¶
-
class
lollipop.validators.
Validator
(error_messages=None, *args, **kwargs)[source]¶ Base class for all validators.
Validator is used by types to validate data during deserialization. Validator class should define
__call__
method with either one or two arguments. In both cases, first argument is value being validated. In case of two arguments, the second one is the context. If given value fails validation,__call__
method should raiseValidationError
. Return value is always ignored.
-
class
lollipop.validators.
Predicate
(predicate, error=None, **kwargs)[source]¶ Validator that succeeds if given predicate returns True.
Parameters: - predicate (callable) – Predicate that takes value and returns True or False. One- and two-argument predicates are supported. First argument in both cases is value being validated. In case of two arguments, the second one is context.
- error (str) – Error message in case of validation error.
Can be interpolated with
data
.
-
class
lollipop.validators.
Range
(min=None, max=None, error=None, **kwargs)[source]¶ Validator that checks value is in given range.
Parameters: - min (int) – Minimum length. If not provided, minimum won’t be checked.
- max (int) – Maximum length. If not provided, maximum won’t be checked.
- error (str) – Error message in case of validation error.
Can be interpolated with
data
,min
ormax
.
-
class
lollipop.validators.
Length
(exact=None, min=None, max=None, error=None, **kwargs)[source]¶ Validator that checks value length (using
len()
) to be in given range.Parameters: - exact (int) – Exact length. If provided,
min
andmax
are not checked. If not provided,min
andmax
checks are performed. - min (int) – Minimum length. If not provided, minimum length won’t be checked.
- max (int) – Maximum length. If not provided, maximum length won’t be checked.
- error (str) – Error message in case of validation error.
Can be interpolated with
data
,length
,exact
,min
ormax
.
- exact (int) – Exact length. If provided,
-
class
lollipop.validators.
NoneOf
(values, error=None, **kwargs)[source]¶ Validator that succeeds if
value
is not a member of givenvalues
.Parameters: - values (iterable) – A sequence of invalid values.
- error (str) – Error message in case of validation error.
Can be interpolated with
data
andvalues
.
-
class
lollipop.validators.
AnyOf
(choices, error=None, **kwargs)[source]¶ Validator that succeeds if
value
is a member of givenchoices
.Parameters: - choices (iterable) – A sequence of allowed values.
- error (str) – Error message in case of validation error.
Can be interpolated with
data
andchoices
.
-
class
lollipop.validators.
Regexp
(regexp, flags=0, error=None, **kwargs)[source]¶ Validator that succeeds if
value
matches givenregex
.Parameters: - regexp (str) – Regular expression string.
- flags (int) – Regular expression flags, e.g. re.IGNORECASE. Not used if regexp is not a string.
- error (str) – Error message in case of validation error.
Can be interpolated with
data
andregexp
.
-
class
lollipop.validators.
Unique
(key=<function identity>, error=None, **kwargs)[source]¶ Validator that succeeds if items in collection are unqiue. By default items themselves should be unique, but you can specify a custom function to get uniqueness key from items.
Parameters: - key (callable) – Function to get uniqueness key from items.
- error (str) – Erorr message in case item appear more than once.
Can be interpolated with
data
(the item that is not unique) andkey
(uniquness key that is not unique).
Errors¶
-
lollipop.errors.
SCHEMA
= '_schema'¶ Name of an error key for cases when you have both errors for the object and for it’s fields:
{'field1': 'Field error', '_schema': 'Whole object error'}
-
exception
lollipop.errors.
ValidationError
(messages)[source]¶ Exception to report validation errors.
Examples of valid error messages:
raise ValidationError('Error') raise ValidationError(['Error 1', 'Error 2']) raise ValidationError({ 'field1': 'Error 1', 'field2': {'subfield1': ['Error 2', 'Error 3']} })
Parameters: messages – Validation error messages. String, list of strings or dict where keys are nested fields and values are error messages.
-
class
lollipop.errors.
ValidationErrorBuilder
[source]¶ Helper class to report multiple errors.
Example:
def validate_all(data): builder = ValidationErrorBuilder() if data['foo']['bar'] >= data['baz']['bam']: builder.add_error('foo.bar', 'Should be less than bam') if data['foo']['quux'] >= data['baz']['bam']: builder.add_fields('foo.quux', 'Should be less than bam') ... builder.raise_errors()
-
add_error
(path, error)[source]¶ Add error message for given field path.
Example:
builder = ValidationErrorBuilder() builder.add_error('foo.bar.baz', 'Some error') print builder.errors # => {'foo': {'bar': {'baz': 'Some error'}}}
Parameters: - path (str) – ‘.’-separated list of field names
- error (str) – Error message
-
add_errors
(errors)[source]¶ Add errors in dict format.
Example:
builder = ValidationErrorBuilder() builder.add_errors({'foo': {'bar': 'Error 1'}}) builder.add_errors({'foo': {'baz': 'Error 2'}, 'bam': 'Error 3'}) print builder.errors # => {'foo': {'bar': 'Error 1', 'baz': 'Error 2'}, 'bam': 'Error 3'}
Parameters: list or dict errors (str,) – Errors to merge
-
raise_errors
()[source]¶ Raise
ValidationError
if errors are not empty; do nothing otherwise.
-
-
lollipop.errors.
merge_errors
(errors1, errors2)[source]¶ Deeply merges two error messages. Error messages can be string, list of strings or dict of error messages (recursively). Format is the same as accepted by
ValidationError
. Returns new error messages.
Type registry¶
-
class
lollipop.type_registry.
TypeRegistry
[source]¶ Storage for type instances with ability to get type instance proxy with delayed type resolution for implementing mutual cross-references.
Example:
TYPES = TypeRegistry() PersonType = TYPES.add('Person', lt.Object({ 'name': lt.String(), 'books': lt.List(lt.Object(TYPES['Book'], exclude='author')), }, constructor=Person)) BookType = TYPES.add('Book', lt.Object({ 'title': lt.String(), 'author': lt.Object(TYPES['Person'], exclude='books'), }, constructor=Book))