Skip to main content

Validation and parsing library

Project description

Trafaret is validation library with support to convert data structures. Sample usage:

import datetime
import trafaret as t

date = t.Dict(year=t.Int, month=t.Int, day=t.Int) >> (lambda d: datetime.datetime(**d))
assert date.check({'year': 2012, 'month': 1, 'day': 12}) == datetime.datetime(2012, 1, 12)

t.Dict creates new dict structure validator with three t.Int elements. >> operation adds lambda function to the converters of given checker. Some checkers have default converter, but when you use >> or .append, you disable default converter with your own.

This does not mean that Int will not convert numbers to int, this mean that some checkers, like String with regular expression, have special converters applied to that can be overriden by your own.

Converters can be chained. You can raise DataError in converters.

Features

Trafaret has very handy features, read below some samples.

Regex String

String can work with regular expressions, and this givs you real power:

>>> c = t.String(regex=r'^name=(\w+)$') >> (lambda m: m.groups()[0])
>>> c.check('name=Jeff')
'Jeff'

Some way you can use all re.Match power to extract from strings dicts and so on.

Dict and Key

Dict get dict with keys and checkers, like {'a': t.Int}. But instead of string key you can use Key class. And Key instance can rename given key name to something else:

>>> c = t.Dict(t.Key('uNJ') >> 'user_name': t.String})
>>> c.check({'uNJ': 'Adam'})
{'user_name': 'Adam'}

And we can do more with right converter:

>>> from trafaret.utils import fold
>>> c = t.Dict({t.Key('uNJ') >> 'user__name': t.String}) >> fold
>>> c.check({'uNJ': 'Adam'})
{'user': {'name': 'Adam'}}

We have some example of enhanced Key in extras:

>>> from trafaret.extras import KeysSubset
>>> cmp_pwds = lambda x: {'pwd': x['pwd'] if x.get('pwd') == x.get('pwd1') else DataError('Not equal')}
>>> d = Dict({KeysSubset('pwd', 'pwd1'): cmp_pwds, 'key1': String})
>>> d.check({'pwd': 'a', 'pwd1': 'a', 'key1': 'b'}).keys()
{'pwd': 'a', 'key1': 'b'}

DataError

Exception class that used in library. Exception hold errors in error attribute. For simple checkers it will be just a string. For nested structures it will be dict instance.

Trafaret

Base class for checkers. Use it to make new checkers. In derrived classes you need to implement _check or _check_val methods. _check_val must return value, _check must return None on success.

You can implement converter method if you want to convert value somehow, but want to make free for developer to apply his own converters to raw data. This used to return strings instead of Match object in String trafaret.

Subclassing

For your own trafaret creation you need to subclass Trafaret class and implement check_value or check_and_return methods. check_value can return nothing on success, check_and_return must return value. In case of failure you need to raise DataError. You can use self._failure shortcut function to do this. Check library code for samples.

Type

Checks that data is instance of given class. Just instantitate it with any class, like int, float, str. Sample:

>>> Type(int).check(4)
4

Any

Will match any element.

Or

Get other converters as args. This samples are equivalent:

>>> Or(t.Int, t.Null).check(None)
None
>>> (t.Int | t.Null).check(5)
5

Null

Value must be None.

Bool

Check if value is boolean:

>>> t.Bool.check(True)
True

Float

Check if value is float or can be converted to. Supports lte, gte, lt, gt parameters:

>>> t.Float(gt=3.5).check(4)
4

Int

Similar to Float, but checking for int:

>>> t.Int(gt=3).check(4)
4

Atom

Value must be exactly equal to Atom first arg:

>>> t.Atom('this_key_must_be_this').check('this_key_must_be_this')
'this_key_must_be_this'

This may be useful in Dict in pair with Or statements.

String, Email, URL

Basicaly just check that arg is string. Argument allow_blank indicates if string can be blank ot not. If you will provide regex param - will return re.Match object. Default converter will return match.group() result. You will get re.Match object in converter.

Email and URL just provide regular expressions and a bit of logic for IDNA domains. Default converters return email and domain, but you will get re.Match in converter.

So, some examples to make things clear:

>>> t.String().check('werwerwer')
'werwerwer'
>>> t.String(regex='^\s+$).check('   ')
'   '
>>> t.String(regex='^name=(\w+)$').check('name=Jeff')
'Jeff'

And one wild sample:

>>> todt = lambda  m: datetime(*[int(i) for i in m.groups()])
>>> (t.String(regex='^year=(\d+),month=(\d+),day=(\d+)$') >> todt).check('year=2011,month=07,day=23')
datetime.datetime(2011, 7, 23, 0, 0)

List

Just List of elements of one type. In converter you will get list of converted elements. Sample:

>>> t.List(t.Int).check(range(100))
[0, 1, 2, ... 99]
>>> t.extract_error(t.List(t.Int).check(['a']))
{0: 'value cant be converted to int'}

Dict

Dict include named params. You can use for keys plain strings and Key instances. In case you provide just string keys, they will converted to Key instances. Actual checking proceeded in Key instance.

Methods:

allow_extra(*names) : where names can be key names or * to allow any additional keys.

make_optional(*names) : where names can be key names or * to make all options optional.

ignore_extra(*names): where names are the names of the keys or * to exclude listed key names or all unspecified ones from the validation process and final result

Key

Special class to create dict keys. Parameters are:

  • name - key name

  • default - default if key is not present

  • optional - if True allow to not provide arg

  • to_name - instead of key name will be returned this key

You can provide to_name with >> operation::

Key(‘javaStyleData’) >> ‘plain_cool_data’

KeysSubset

Experimental feature, not stable API. Sometimes you need to make something with part of dict keys. So you can:

>>> join = (lambda d: {'name': ' '.join(d.values())})
>>> Dict({KeysSubset('name', 'last'): join}).check({'name': 'Adam', 'last': 'Smith'})
{'name': 'Smith Adam'}

As you can see you need to return dict from checker.

Error raise

In Dict you can just return error from checkers or converters, there is need not to raise them.

Mapping

Check both keys and values:

>>> trafaret = Mapping(String, Int)
>>> trafaret
<Mapping(<String> => <Int>)>
>>> trafaret.check({"foo": 1, "bar": 2})
{'foo': 1, 'bar': 2}

Enum

This checker check that value one from provided. Like::
>>> Enum(1, 2, 'error').check('2')
2

Callable

Check if data is callable.

Call

Take a function that will be called in check. Function must return value or DataError.

Forward

This checker is container for any checker, that you can provide later. To provide container use provide method or << operation:

>> node = Forward()
>> node << Dict(name=String, children=List[node])

guard

Decorator for function:

>>> @guard(a=String, b=Int, c=String)
... def fn(a, b, c="default"):
...     '''docstring'''
...     return (a, b, c)

GuardError

Derived from DataError.

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

trafaret-0.5.4.tar.gz (21.0 kB view details)

Uploaded Source

Built Distribution

trafaret-0.5.4-py3-none-any.whl (22.4 kB view details)

Uploaded Python 3

File details

Details for the file trafaret-0.5.4.tar.gz.

File metadata

  • Download URL: trafaret-0.5.4.tar.gz
  • Upload date:
  • Size: 21.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No

File hashes

Hashes for trafaret-0.5.4.tar.gz
Algorithm Hash digest
SHA256 5d2513b6b11973b88a10ff33394dddfcbaab45d551adde8fafcfc742c7437dfe
MD5 38cc8d8973790344f7d79fafaa1ec8f2
BLAKE2b-256 7074eed1a69e8a18fada357a74d63ecab493c5035f6726d6d2f13a6eada15fb9

See more details on using hashes here.

File details

Details for the file trafaret-0.5.4-py3-none-any.whl.

File metadata

File hashes

Hashes for trafaret-0.5.4-py3-none-any.whl
Algorithm Hash digest
SHA256 ae2d3b332064d8bfde7330daff8d3e1461d36c850a5e65ded6ad6b1aa92452ba
MD5 eea55db03a0fafb283ba7575f850d896
BLAKE2b-256 52f17e265bd86519ea48aa7f611dfff4aa392ff2960896f835d141ef853cb9f7

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page