Files
deb-python-jsonschema/docs/validate.rst
Julian Berman 701b2ecfcd Share code.
2013-02-16 23:55:07 -05:00

12 KiB

Schema Validation

jsonschema

The Basics

The simplest way to validate an instance under a given schema is to use the validate function.

validate

Validate an instance under the given schema.

>>> validate([2, 3, 4], {"maxItems" : 2}) Traceback (most recent call last): ... ValidationError: [2, 3, 4] is too long

validate will first verify that the provided schema is itself valid, since not doing so can lead to less obvious error messages and fail in less obvious or consistent ways. If you know you have a valid schema already or don't care, you might prefer using the validate method directly on a specific validator (e.g. Draft3Validator.validate).

cls is a validator class that will be used to validate the instance. By default this is a draft 3 validator. Any other provided positional and keyword arguments will be provided to this class when constructing a validator.

raises

ValidationError if the instance is invalid

SchemaError if the schema itself is invalid

The Validator Interface

jsonschema defines an (informal) interface that all validators should adhere to.

argument dict schema

the schema that the validator will validate with. It is assumed to be valid, and providing an invalid schema can lead to undefined behavior. See IValidator.check_schema to validate a schema first.

argument types

Override or extend the list of known types when validating the type property. Should map strings (type names) to class objects that will be checked via isinstance. See validating-types for details.

type types

dict or iterable of 2-tuples

argument resolver

an object with a resolve() method that will be used to resolve $ref properties (JSON references). If unprovided, a RefResolver is created and used.

argument format_checker

an object with a conform() method that will be called to check and see if instances conform to each format property present in the schema. If unprovided, no validation will be done for format. FormatChecker is a concrete implementation of an object of this form that can be used for common formats.

DEFAULT_TYPES

The default mapping of JSON types to Python types used when validating type properties in JSON schemas.

META_SCHEMA

An object representing the validator's meta schema (the schema that describes valid schemas in the given version).

schema

The schema that was passed in when initializing the validator.

check_schema(schema)

Validate the given schema against the validator's META_SCHEMA.

raises

SchemaError if the schema is invalid

is_type(instance, type)

Check if the instance is of the given (JSON Schema) type.

type type

str

rtype

bool

raises

UnknownType if type is not a known type.

The special type "any" is valid for any given instance.

is_valid(instance)

Check if the instance is valid under the current schema.

rtype

bool

>>> schema = {"maxItems" : 2} >>> Draft3Validator(schema).is_valid([2, 3, 4]) False

iter_errors(instance)

Lazily yield each of the validation errors in the given instance.

rtype

an iterable of ValidationErrors

>>> schema = { ... "type" : "array", ... "items" : {"enum" : [1, 2, 3]}, ... "maxItems" : 2, ... } >>> v = Draft3Validator(schema) >>> for error in sorted(v.iter_errors([2, 3, 4]), key=str): ... print(error) 4 is not one of [1, 2, 3] [2, 3, 4] is too long

validate(instance)

Check if the instance is valid under the current schema.

raises

ValidationError if the instance is invalid

>>> schema = {"maxItems" : 2} >>> Draft3Validator(schema).validate([2, 3, 4]) Traceback (most recent call last): ... ValidationError: [2, 3, 4] is too long

All of the versioned validators <versioned-validators> that are included with jsonschema adhere to the interface, and implementors of validators that extend or complement the ones included should adhere to it as well. For more information see creating-validators.

Validating With Additional Types

Occasionally it can be useful to provide additional or alternate types when validating the JSON Schema's type property. Validators allow this by taking a types argument on construction that specifies additional types, or which can be used to specify a different set of Python types to map to a given JSON type.

For instance, JSON defines a number type, which can be validated with a schema such as {"type" : "number"}. By default, this will validate correctly for Python ints and floats. If you wanted to additionally validate decimal.Decimal objects, you'd use

Draft3Validator(
    schema={"type" : "number"},
    types={"number" : (int, float, decimal.Decimal)},
)

The list of default Python types for each JSON type is available on each validator in the IValidator.DEFAULT_TYPES attribute. Note that you need to specify all types to match if you override one of the existing JSON types, so you may want to access the set of default types to add it to the ones being appended.

Versioned Validators

jsonschema ships with validators for various versions of the JSON Schema specification. For details on the methods and attributes that each validator provides see the IValidator interface, which each validator implements.

Draft3Validator

Validating Formats

JSON Schema defines the format property which can be used to check if primitive types (strs, numbers, bools) conform to well-defined formats. By default, no validation is enforced, but optionally, validation can be enabled by hooking in a format-checking object into an IValidator.

>>> validate("tomorrow", {"format" : "date"}) >>> validate( ... "tomorrow", {"format" : "date"}, format_checker=FormatChecker(), ... ) Traceback (most recent call last): ... ValidationError: "tomorrow" is not a "date"

FormatChecker

checkers

A mapping of currently known formats to functions that validate them. New checkers can be added and removed either per-instance or globally for all checkers using the FormatChecker.checks or FormatChecker.cls_checks decorators respectively.

cls_checks(format)

Register a decorated function as globally validating a new format.

Any instance created after this function is called will pick up the supplied checker.

argument str format

the format that the decorated function will check

There are a number of default checkers that FormatCheckers know how to validate. Their names can be viewed by inspecting the FormatChecker.checkers attribute.

from pprint import pprint

pprint(sorted(FormatChecker.checkers))

[...'color',

...'date', ...'date-time', ...'email', ...'host-name', ...'ip-address', ...'ipv6', ...'regex', ...'time', ...'uri']

The actual functions that do the validation are also exposed, in case there is any use for them. They are listed below, along with any limitations they come with.

is_date

Check if the instance is a date in YYYY-MM-DD format.

>>> is_date("1970-12-31") True >>> is_date("12/31/1970") False >>> is_date("0000-13-32") False

is_time

Check if the instance is a time in hh:mm:ss format.

>>> is_time("23:59:59") True >>> is_time("11:59:59 PM") False >>> is_time("59:60:61") False

is_regex

Check if the instance is a well-formed regular expression.

>>> is_regex("^(bob)?cat$") True >>> is_ipv6("^(bob?cat$") False

is_uri

Check if the instance is a valid URI.

Also supports relative URIs.

>>> is_uri("ftp://joe.bloggs@www2.example.com:8080/pub/os/") True >>> is_uri("http://www2.example.com:8000/pub/#os?user=joe.bloggs") True >>> is_uri(r"\\WINDOWSMy Files") False >>> is_uri("#/properties/foo") True

is_email

Check if the instance is a valid e-mail address.

Checking is based on RFC 2822

>>> is_email("joe.bloggs@example.com") True >>> is_email("joe.bloggs") False

is_host_name

Check if the instance is a valid host name.

>>> is_host_name("www.example.com") True >>> is_host_name("my laptop") False >>> is_host_name( ... "a.vvvvvvvvvvvvvvvvveeeeeeeeeeeeeeeeerrrrrrrrrrrrrrrrryyyyyyyy" ... "yyyyyyyyy.long.host.name" ... ) False

Note

Does not perform a DNS lookup.

>>> is_host_name("www.example.doesnotexist") True

is_ip_address

Check if the instance is a valid IP address.

>>> is_ip_address("192.168.0.1") True >>> is_ip_address("::1") False >>> is_ip_address("256.256.256.256") False

On OSes with the socket.inet_pton function, an additional checker for ipv6 will be enabled:

is_ipv6(instance)

Check if the instance is a valid IPv6 address.

>>> is_ipv6("::1") True >>> is_ipv6("192.168.0.1") False >>> is_ipv6("1:1:1:1:1:1:1:1:1") False

If the isodate library is present, a date-time checker will also be present.

is_date_time(instance)

Check if the instance is in ISO 8601 YYYY-MM-DDThh:mm:ssZ format.

>>> is_date_time("1970-01-01T00:00:00.0Z") True >>> is_date_time("0000-58-59T60:61:62") False

Additionally, if the webcolors library is present, some checkers related to CSS will be enabled:

is_css21_color(instance)

Check if the instance is a valid CSS 2.1 color name or code.

>>> is_css21_color("fuchsia") True >>> is_css21_color("pink") False >>> is_css_color_code("#CC8899") True

is_css3_color(instance)

Check if the instance is a valid CSS 3 color name or code.

>>> is_css3_color("pink") True >>> is_css3_color("puce") False >>> is_css_color_code("#CC8899") True