jsonweb.schema
¶
Table of Contents
jsonweb.schema
provides a layer of validation before json.decode
returns your object instances.
It can also be used simply to validate the resulting python data structures returned from json.loads()
. Here
is an example of validating the structure of a python dict:
>>> from jsonweb.schema import ObjectSchema, ValidationError
>>> from jsonweb.schema.validators import String
>>> class PersonSchema(ObjectSchema):
... first_name = String()
... last_name = String()
>>> try:
... PersonSchema.validate({"first_name": "shawn"})
... except ValidationError, e:
... print e.errors
{"last_name": "Missing required parameter."}
Validating plain old python data structures is fine, but the more interesting exercise is tying a schema to a class defination:
>>> from jsonweb.decode import from_object, loader
>>> from jsonweb.schema import ObjectSchema, ValidationError
>>> from jsonweb.schema.validators import String, Integer, EnsureType
>>> class PersonSchema(ObjectSchema):
... id = Integer()
... first_name = String()
... last_name = String()
... gender = String(optional=True)
... job = EnsureType("Job")
You can make any field optional by setting optional
to True
.
Warning
The field is only optional at the schema level. If you’ve bound a schema to
a class via from_object()
and the uderlying class requires that field a
ObjectAttributeError
will be raised if missing.
As you can see its fine to pass a class name as a string, which we have done for
the Job
class above. We must later define Job
and decorate it
with jsonweb.decode.from_object()
>>> class JobSchema(ObjectSchema):
... id = Integer()
... title = String()
>>> @from_object(schema=JobSchema)
... class Job(object):
... def __init__(self, id, title):
... self.id = id
... self.title = title
>>> @from_object(schema=PersonSchema)
... class Person(object):
... def __init__(self, first_name, last_name, job, gender=None):
... self.first_name = first_name
... self.last_name = last_name
... self.gender = gender
... self.job = job
... def __str__(self):
... return '<Person name="%s" job="%s">' % (
... " ".join((self.first_name, self.last_name)),
... self.job.title
... )
>>> person_json = '''
... {
... "__type__": "Person",
... "id": 1,
... "first_name": "Bob",
... "last_name": "Smith",
... "job": {"__type__": "Job", "id": 5, "title": "Police Officer"},
... }
... '''
>>> person = loader(person_json)
>>> print person
<Person name="Bob" job="Police Officer">
ValidationErrors¶
-
class
jsonweb.schema.
ValidationError
(message, errors=None)¶
Validators¶
Validators for use in jsonweb.schema
.
-
class
jsonweb.schema.validators.
String
(max_len=None, **kw)¶ Validates something is a string
>>> String().validate("foo") ... 'foo' >>> String().validate(1) Traceback (most recent call last): ... ValidationError: Expected str got int instead.
You can also specify a maximum string length
>>> String(max_len=3).validate("foobar") Traceback (most recent call last): ... ValidationError: String exceeds max length of 3.
-
class
jsonweb.schema.validators.
Number
(**kw)¶ Validates something is a number
>>> Number().validate(1) ... 1 >>> Number().validate(1.1) >>> 1.1 >>> Number().validate("foo") Traceback (most recent call last): ... ValidationError: Expected number got int instead.
-
class
jsonweb.schema.validators.
Integer
(**kw)¶ Validates something in an integer
-
class
jsonweb.schema.validators.
Float
(**kw)¶ Validates something is a float
-
class
jsonweb.schema.validators.
DateTime
(format='', **kw)¶ Validates that something is a date/datetime string
>>> DateTime().validate("2010-01-02 12:30:00") ... datetime.datetime(2010, 1, 2, 12, 30) >>> DateTime().validate("2010-01-02 12:300") Traceback (most recent call last): ... ValidationError: time data '2010-01-02 12:300' does not match format '%Y-%m-%d %H:%M:%S'
The default datetime format is
%Y-%m-%d %H:%M:%S
. You can specify your own>>> DateTime("%m/%d/%Y").validate("01/02/2010") ... datetime.datetime(2010, 1, 2, 0, 0)
-
class
jsonweb.schema.validators.
EnsureType
(_type, type_name=None, **kw)¶ Validates something is a certian type
>>> class Person(object): ... pass >>> EnsureType(Person).validate(Person()) ... <Person> >>> EnsureType(Person).validate(10) Traceback (most recent call last): ... ValidationError: Expected Person got int instead.
-
class
jsonweb.schema.validators.
List
(validator, **kw)¶ Validates a list of things. The List constructor accepts a validator and each item in a the list will be validated against it
>>> List(Integer).validate([1,2,3,4]) ... [1,2,3,4] >>> List(Integer).validate(10) ... ValidationError: Expected list got int instead.
Since
ObjectSchema
is also a validator we can do this>>> class PersonSchema(ObjectSchema): ... first_name = String() ... last_name = String() ... >>> List(PersonSchema).validate([ ... {"first_name": "bob", "last_name": "smith"}, ... {"first_name": "jane", "last_name": "smith"} ... ])