Skip to main content

A simple and extensible schema validator.

Project description

py_schema

A simple and extensible schema validator.

travis codecov

Install

pip install py-schema

Usage

from py_schema import SchemaValidator, SchemaValidationError
from py_schema import DictField, ListField, StrField, IntField


schema = DictField(
    schema={
        'name': StrField(min_length=2, max_length=50),
        'age': IntField(min=0, max=130),
        'pets': ListField(
            min_items=1,
            item_schema=StrField()
        )
    }
)

value = {
    'name': 'Bruce',
    'age': 40,
    'pets': ['Billy', False]
}

try:
    validator = SchemaValidator(
        schema=schema,
        value=value
    )

    validator.validate()

except SchemaValidationError as err:
    print(err.code)  # STR_TYPE
    print(err.path)  # $root.pets.$1

You can check the complete list of errors in each field spec.

Fields

BaseField

This is the abstract field that all the fields inherit from.

It has some shared props that you can use in all fields.

required

If marked as True (default) and the value is None, it will raise a REQUIRED_VALUE error.

from py_schema import SchemaValidator, SchemaValidationError, StrField

try:
    schema = StrField(required=True)
    value = None

    validator = SchemaValidator(schema, value)
    validator.validate()
except SchemaValidationError as err:
    print(err.code)  # "REQUIRED_VALUE"

IntField

Validate if the value is an integer.

from py_schema import SchemaValidator, IntField


schema = IntField(
    min=1,
    max=100
)

value = 80

validator = SchemaValidator(schema, value)

validator.validate()

min (int, optional, default None)

If provided, it will validate if the value is >= of the min.

If not, it will raise a INT_MIN error.

max (int, optional, default None)

If provided, it will validate if the value is <= of the max.

If not, it will raise a INT_MAX error.

StrField

Validate if the value is a string.

from py_schema import SchemaValidator, StrField


schema = StrField(
    min_length=2,
    max_length=50
)

value = 'Luca Turilli'

validator = SchemaValidator(schema, value)

validator.validate()

min_length (int, optional, default None)

If provided, it will validate if the string len is >= of the min_length.

If not, it will raise a STR_MIN_LENGTH error.

max_length (int, optional, default None)

If provided, it will validate if the string len is <= of the max_length.

If not, it will raise a STR_MAX_LENGTH error.

FloatField

Validate if the value is a float.

from py_schema import SchemaValidator, FloatField

schema = FloatField(
    min=0.0,
    max=99.0
)

value = 50.0

validator = SchemaValidator(schema, value)

validator.validate()

min (int, optional, default None)

If provided, it will validate if the value is >= of the min.

If not, it will raise a FLOAT_MIN error.

max (int, optional, default None)

If provided, it will validate if the value is <= of the max.

If not, it will raise a FLOAT_MAX error.

BoolField

Validate if the value is a bool.

from py_schema import SchemaValidator, BoolField

schema = BoolField()

value = False

validator = SchemaValidator(schema, value)

validator.validate()

DictField

Validate if the value is a dict and each field inside it.

from py_schema import SchemaValidator, DictField, StrField, BoolField


schema = DictField(
    schema={
        'name': StrField(),
        'admin': BoolField(),
        'contacts': DictField(
            schema={
                'phone': StrField(),
                'email': StrField()
            },
            optional_props=['phone']
        )
    },
    strict=True,
    optional_props=['contacts']
)

value = {
    'name': 'Dargor The Lord',
    'admin': True,
    'contacts': {
        'email': 'dargor@blackmountain.com'
    }
}

validator = SchemaValidator(schema, value)

validator.validate()

schema (dict, required)

The definition of the dictionary.

strict (bool, optional, default False)

If the schema should reject dictionary keys that is not present in the schema.

For example:

from py_schema import SchemaValidator, SchemaValidationError, DictField, StrField, BoolField

try:
    schema = DictField(
        schema={
            'name': StrField(),
            'admin': BoolField()
        },
        strict=True
    )

    value = {
        'name': 'Dargor The Lord',
        'admin': True,
        'contacts': {
            'email': 'dargor@blackmountain.com'
        }
    }

    validator = SchemaValidator(schema, value)
    validator.validate()

except SchemaValidationError as err:
    print(err.code)  # DICT_PROP_NOT_ALLOWED
    print(err.extra)  # {'prop': 'contacts'}

In this case, the contacts property in the value is not present in the schema.

It will raise a DICT_PROP_NOT_ALLOWED.

optional_props ([str], optional, default [])

This prop indicates which properties are optional in schema.

If a prop is in this list and it's not in the value, it will be ignored.

Otherwise, it will raise a DICT_PROP_MISSING error.

Example:

from py_schema import SchemaValidator, DictField, StrField, BoolField

schema = DictField(
    schema={
        'name': StrField(),
        'admin': BoolField(),
        'gender': StrField() 
    },
    optional_props=['gender']
)

value = {
    'name': 'Dargor The Lord',
    'admin': True
}

validator = SchemaValidator(schema, value)
validator.validate() # valid
from py_schema import SchemaValidator, SchemaValidationError, DictField, StrField, BoolField

try:
    schema = DictField(
        schema={
            'name': StrField(),
            'admin': BoolField()
        }
    )

    value = {
        'name': 'Dargor The Lord'
    }

    validator = SchemaValidator(schema, value)
    validator.validate()

except SchemaValidationError as err:
    print(err.code)  # DICT_PROP_MISSING
    print(err.extra)  # {'prop': 'admin'}

ListField

Validate if the value is a list and the items inside it.

from py_schema import SchemaValidator, ListField, StrField


schema = ListField(
    min_items=1,
    max_items=3,
    item_schema=StrField()
)

value = ['Emerald', 'Sword']

validator = SchemaValidator(schema, value)
validator.validate()

item_schema (BaseField, required)

The schema for the item inside the list.

min_items (int, optional, default None)

Validate if the list contain at minimun min_items length.

If not, it will raise LIST_MIN_ITEMS error.

max_items (int, optional, default None)

Validate if the list contain at maximum max_items length.

If not, it will raise LIST_MAX_ITEMS error.

EnumField

Validate if the value is one of the allowed values.

from py_schema import SchemaValidator, EnumField


schema = EnumField(
    accept=[1, True, 'Immortal']
)

value = 1

validator = SchemaValidator(schema, value)
validator.validate()

accept (list, required)

The list of the values that can be accepted.

If the value is not in the accepted, it will raise a ENUM_VALUE_NOT_ACCEPT error.

Regex Field

Validate if the value matches the regex.

from py_schema import SchemaValidator, RegexField

schema = RegexField(regex='\\d{5}\\Z')

value = '12345'

validator = SchemaValidator(schema, value)

validator.validate()

regex (str, required)

The regex pattern.

OR Field

Validate if the value matches with at least one of given schemas.

from py_schema import OrField, StrField, BoolField, IntField, SchemaValidator, SchemaValidationError

schema = OrField(
    schemas=[
        StrField(),
        IntField()
    ]
)

value = True

validator = SchemaValidator(schema, value)

try:
    validator.validate()
except SchemaValidationError as e:
    print(e.extra['errors'])

schemas ([BaseField], required)

The list of the schemas to validate. If all the schemas failed, it will raise a OR_NO_MATCHING_SCHEMA error.

If the validation fail, you can check the error prop extra['errors'] to see all the validation results.

Misc

SchemaValidationError

If a validation fails, it will raise a SchemaValidationError.

Inside the error will will have:

from py_schema import SchemaValidationError

try:
    # ....
    pass
except SchemaValidationError as err:
    print(err.code)  # The code of the error
    print(err.path)  # The path in the schema that the error occurred.
    print(err.node)  # The BaseField node where the validation was raised.
    print(err.extra) # Any extra argument of the error.

Creating custom validators

For better context, let's use this sample:

from py_schema import DictField
from .my_field import MyField


schema = DictField(
    schema={
        'my_field': MyField()
    }
)

value = {
    'my_field': 'Avalon'
}
from py_schema import BaseField


class MyField(BaseField):
    def validator(self):
        ctx = self.ctx # the current SchemaValidator instance
        value = self.value # here is the current value of the schema (in this sample: "Avalon")

        if value != 'Avalon': # create you custom validation
            self.raise_error( # if your validation fails, raise an error
                code='MY_CUSTOM_CODE',
                extra="Any other extra info for your error (optional)"
            )

And that's it =).

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Files for py-schema, version 0.12.0
Filename, size File type Python version Upload date Hashes
Filename, size py_schema-0.12.0-py3-none-any.whl (8.2 kB) File type Wheel Python version py3 Upload date Hashes View
Filename, size py_schema-0.12.0.tar.gz (9.5 kB) File type Source Python version None Upload date Hashes View

Supported by

Pingdom Pingdom Monitoring Google Google Object Storage and Download Analytics Sentry Sentry Error logging AWS AWS Cloud computing DataDog DataDog Monitoring Fastly Fastly CDN DigiCert DigiCert EV certificate StatusPage StatusPage Status page