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 invalidSchemaError
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 viaisinstance
. Seevalidating-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, aRefResolver
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 eachformat
property present in the schema. If unprovided, no validation will be done forformat
.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
iftype
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
ValidationError
s
>>> 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 int
s and float
s. If you wanted to
additionally validate decimal.Decimal
objects, you'd use
Draft3Validator(={"type" : "number"},
schema={"number" : (int, float, decimal.Decimal)},
types )
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 (str
s,
number
s, bool
s) 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 FormatChecker
s 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