Skip to main content

Validator for district42 schema

Project description

valera

Codecov PyPI PyPI - Downloads Python Version

Validator for district42 schema

(!) Work in progress, breaking changes are possible until v2.0 is released

Installation

pip3 install valera

Usage

eq returns True or False

from district42 import schema
from valera import eq

assert eq(schema.int, 42)

# syntax sugar
assert schema.int == 42

validate returns ValidationResult

from district42 import schema
from valera import validate

res = validate(schema.int, 42)
assert res.get_errors() == []

validate_or_fail returns True or raise ValidationException

from district42 import schema
from valera import validate_or_fail

assert validate_or_fail(schema.int, 42)

Documentation

None

schema.none

sch = schema.none

assert sch == None

assert sch != False  # incorrect type

Bool

schema.bool

sch = schema.bool

assert sch == True
assert sch == False

assert sch != None  # incorrect type

schema.bool(value)

sch = schema.bool(True)

assert sch == True

assert sch != False  # incorrect value

Int

schema.int

sch = schema.int

assert sch == 42

assert sch != 3.14  # incorrect type
assert sch != "42"  # incorrect type

schema.int(value)

sch = schema.int(42)

assert sch == 42

assert sch != 43  # incorrect value

schema.int.min(value)

sch = schema.int.min(0)

assert sch == 0
assert sch == 1

assert sch != -1  # < min

schema.int.max(value)

sch = schema.int.max(0)

assert sch == 0
assert sch == -1

assert sch != 1  # > max

Float

schema.float

sch = schema.float

assert sch == 3.14

assert sch != 3  # incorrect type
assert sch != "3.14"  # incorrect type

schema.float(value)

sch = schema.float(3.14)

assert sch == 3.14

assert sch != 3.15  # incorrect value

schema.float.min(value)

sch = schema.float.min(0.0)

assert sch == 0.0
assert sch == 0.1

assert sch != -0.1  # < min

schema.float.max(value)

sch = schema.float.max(0.0)

assert sch == 0.0
assert sch == -0.1

assert sch != 0.1  # > max

Str

schema.str

sch = schema.str

assert sch == ""
assert sch == "banana"

assert sch != None  # incorrect type

schema.str.len(length)

sch = schema.str.len(2)

assert sch == "ab"

assert sch != "a"  # missing symbol

schema.str.len(min_length, max_length)

sch = schema.str.len(1, ...)

assert sch == "a"
assert sch == "ab"

assert sch != ""  # missing symbol
sch = schema.str.len(..., 2)

assert sch == ""
assert sch == "ab"

assert sch != "abc"  # extra symbol
sch = schema.str.len(1, 2)
assert sch == "a"
assert sch == "ab"

assert sch != ""  # missing symbol
assert sch != "abc"  # extra symbol

schema.str.alphabet(letters)

digits = "01234567890"
sch = schema.str.alphabet(digits)

assert sch == "123"

assert sch != "abc"  # incorrect alphabet

schema.str.contains(substr)

sch = schema.str.contains("banana")

assert sch == "banana!"

assert sch != ""

schema.str.regex(pattern)

sch = schema.str.regex(r"[a-z]+")

assert sch == "abc"

assert sch != "123"  # pattern missmatch

List

schema.list

sch = schema.list
assert sch == []
assert sch == [1, 2]

assert sch != {}  # incorrect type

schema.list(elements)

sch = schema.list([schema.int(1), schema.int(2)])

assert sch == [1, 2]

assert sch != [1]  # missing element "2"

schema.list(type)

sch = schema.list(schema.int)

assert sch == [42]

assert sch != ["42"]  # incorrect type

schema.list(type).len(length)

sch = schema.list(schema.int).len(3)

assert sch == [1, 2, 3]

assert sch != [1, 2]  # missing element

schema.list(type).len(min_length, max_length)

sch = schema.list(schema.int).len(1, ...)

assert sch == [1]
assert sch == [1, 2]

assert sch != []  # missing element
sch = schema.list(schema.int).len(..., 2)

assert sch == []
assert sch == [1, 2]

assert sch != [1, 2, 3]  # extra element
sch = schema.list(schema.int).len(1, 2)

assert sch == [1]
assert sch == [1, 2]

assert sch != []  # missing element
assert sch != [1, 2, 3]  # extra element

Dict

schema.dict

sch = schema.dict

assert sch == {}
assert sch == {"id": 1}

assert sch != []

schema.dict(keys)

strict

sch = schema.dict({
    "id": schema.int,
    optional("name"): schema.str
})

assert sch == {"id": 1}
assert sch == {"id": 1, "name": "Bob"}

assert sch != {"id": 1, "field": "value"}  # extra key 'field'
assert sch != {"id": 1, "name": None}  # incorrect type

relaxed

sch = schema.dict({
    "id": schema.int,
    optional("name"): schema.str,
    ...: ...
})

assert sch == {"id": 1}
assert sch == {"id": 1, "name": "Bob"}
assert sch == {"id": 1, "field": "value"}
assert sch == {"id": 1, "name": "Bob", "field": "value"}

assert sch != {"id": 1, "name": None}  # incorrect type

Any

schema.any

sch = schema.any

assert sch == None
assert sch == 42
assert sch == "banana"
assert sch == []
assert sch == {}

schema.any(*types)

sch = schema.any(schema.str, schema.none)

assert sch == None
assert sch == "banana"

assert sch != 42  # incorrect type

Custom Types

1. Declare Schema

from typing import Any
from uuid import UUID
from district42 import Props, SchemaVisitor, SchemaVisitorReturnType as ReturnType
from district42.types import Schema
from niltype import Nilable


class UUIDProps(Props):
    @property
    def value(self) -> Nilable[UUID]:
        return self.get("value")


class UUIDSchema(Schema[UUIDProps]):
    def __accept__(self, visitor: SchemaVisitor[ReturnType], **kwargs: Any) -> ReturnType:
        return visitor.visit_uuid(self, **kwargs)

    def __call__(self, /, value: UUID) -> "UUIDSchema":
        return self.__class__(self.props.update(value=value))

2. Register Validator

from typing import Any
from uuid import UUID
from niltype import Nil, Nilable
from th import PathHolder
from valera import ValidationResult, Validator


class UUIDValidator(Validator, extend=True):
    def visit_uuid(self, schema: UUIDSchema, *,
                   value: Any = Nil, path: Nilable[PathHolder] = Nil,
                   **kwargs: Any) -> ValidationResult:
        result = self._validation_result_factory()
        if path is Nil:
            path = self._path_holder_factory()

        if error := self._validate_type(path, value, UUID):
            return result.add_error(error)

        if schema.props.value is not Nil:
            if error := self._validate_value(path, value, schema.props.value):
                return result.add_error(error)

        return result

3. Use

from uuid import uuid4
from district42 import register_type, schema
from valera import validate_or_fail

register_type("uuid", UUIDSchema)

assert validate_or_fail(schema.uuid, uuid4())

Full code available here: district42_exp_types/uuid

Project details


Download files

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

Source Distribution

valera-1.4.0.tar.gz (19.4 kB view hashes)

Uploaded Source

Built Distribution

valera-1.4.0-py3-none-any.whl (25.2 kB view hashes)

Uploaded Python 3

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