Tutorial

Relief allows you to easily model data structures using schemas. A very simple schema is relief.Integer, which represents a single integer.

Basics

You can create an instance of Integer to validate objects, to find out whether they match your schema.

>>> from relief import Integer
>>> element = Integer()
>>> element.set_from_raw(1)
>>> element.validate()
True

Conversion

Quite often you deal with data that quite but not exactly matches a schema, especially when dealing with user input. A lot of the time this data can be converted to something that does match your schema, such as the string "1" to the integer 1. Relief will do that for your by default:

>>> element.set_from_raw('1')
>>> element.validate()
True

In order to work with the converted data you can get it using the value attribute, the raw value you passed to the schema is available as raw_value.

>>> element.value
1
>>> element.raw_value
'1'

Sometimes you don’t want any conversion to happen though, in these cases you want a schema that behaves differently. Conversion behaviour is controlled with the strict class attribute, we could change that by creating subclass of Integer, this however would add quite a bit of syntax overhead for something so frequently needed. This problem is solved by the using() class method.

>>> StrictInteger = Integer.using(strict=True)
>>> element = StrictInteger()
>>> element.set_from_raw("1")
>>> element.validate()
False

using() provides a convenient way to create subclasses purely for the purpose of changing class attributes. Subclassing schemas to change their behaviour in some way is a common pattern within Relief you need to make yourself familiar with.

Validation

Before we start modelling more complex data structures, let’s take a look at another important feature: validation.

Validation is performed by using validators, these are callables that take a schema instance and a context (which we ignore for now), and return either True or False to signal whether the element was validated successfully or not.

>>> from relief import Unspecified, NotUnserializable
>>> def is_greater_than_3(element, context):
...     if element.value is Unspecified:
...         return False
...     elif element.value is NotUnserializable:
...         return False
...     return element.value > 3

As you can see a validator has to handle three cases, if validate() is called before a value has been set the value is relief.Unspecified, if a value has been set but it couldn’t be converted it’s relief.NotUnserializable and if it’s neither of these it’s a value that ignoring validatation would be considered valid.

In order to use such a validator you create a new schema that includes the validator using validated_by(), similar to how we created a new schema with using().

>>> element = Integer.validated_by([is_greater_than_3])()
>>> element.set_from_raw(4)
>>> element.validate()
True
>>> element.set_from_raw(3)
>>> element.validate()
False

You can find a couple of commonly used validators in relief.validation.

Containers

When modelling data structures most of the time you work with containers, meaning data structures that contain other data structures to form information. Corresponding with that such data structures are modelled in Relief with schemas, that contain other schemas.

>>> from relief import List
>>> ListOfIntegers = List.of(Integer)
>>> element = ListOfIntegers()
>>> element.set_from_raw([1, 2, 3])
>>> element.validate()
True

Schemas that contain other schemas are containers – like relief.List which is used in the above example – have an of() class method. of() works similar to using() or validated_by() in that it returns a modified schema, unlike these, which can be called to perform modifications, of() must be called to create a usable schema.

List just as any other container is abstract and attempting to use it without defining what it contains, will raise an exception.

>>> List()
Traceback (most recent call last):
...
TypeError: member_schema is unknown

To learn more about which schemas are available, take a look at the relief module.

Project Versions

Table Of Contents

Previous topic

Relief documentation

Next topic

relief

This Page