Python extensible schema validations and declarative syntax helpers.
pip install valley
class Animal(Schema):
name = CharProperty(required=True)
species = CharProperty(required=True)
color = CharProperty(required=True)
meal_type = CharProperty()
age = IntegerProperty(required=True)
frog = Animal(name='Kermit',species='frog',color='green',meal='carnivore',age=1)
frog.validate()
Python 3.6+
- kev - K.E.V. (Keys, Extra Stuff, and Values) is a Python ORM for key-value stores. Currently supported backends are Redis, S3, DynamoDB, and a S3/Redis hybrid backend.
- formy - Formy is a Python forms library with Jinja2 templates
The schema class (valley.contrib.Schema) provides the model for validating properties. Valley also includes utilities (valley.declarative) to make building declarative syntax validation libraries easier. See an example below.
from six import with_metaclass
from valley.declarative import DeclaredVars as DV, \
DeclarativeVariablesMetaclass as DVM
from valley.schema import BaseSchema
from valley.properties import *
class DeclaredVars(DV):
base_field_class = BaseProperty
base_field_type = '_base_properties'
class DeclarativeVariablesMetaclass(DVM):
declared_vars_class = DeclaredVars
class Schema(with_metaclass(DeclarativeVariablesMetaclass, BaseSchema)):
_create_error_dict = False
BUILTIN_DOC_ATTRS = []
#If you just want to build upon an existing schema use valley.contrib.Schema
class Animal(Schema):
name = CharProperty(required=True)
species = CharProperty(required=True)
color = CharProperty(required=True)
meal_type = CharProperty()
age = IntegerProperty(required=True)
>>bear = Animal(name="Yogi",species="bear",color="brown",meal_type="carnivore",age=5)
>>bear.is_valid
False
>>bear.validate()
>>bear.is_valid
True
>>frog = Animal(name="Kermit",species="frog",color="green",meal_type="carnivore")
>>frog.is_valid
False
>>frog.validate()
ValidationException Traceback (most recent call last)
1 frog = Animal(name='Frog',color='Green',meal_type='carnivore')
2
3 frog.validate()
/home/coder/workspace/valley/valley/schema.pyc in validate(self)
55 self._errors[key] = e.error_msg
56 else:
57 raise e
58 value = prop.get_python_value(data.get(key))
59 data[key] = value
ValidationException: age: This value is required
Base class that all of the following properties are subclassed from.
- RequiredValidator (if the required kwarg is set)
Validates that the input is a string type.
from valley.properties import CharProperty
first_name = CharProperty(required=True,min_length=1,max_length=20)
first_name.validate('Some string','First Name')
- Validators from BaseProperty
- StringValidator
- MinLengthValidator (if min_length kwarg is set)
- MaxLengthValidator (if max_length kwarg is set)
Validates that the input is a string type but is also a slug (ex. this-is-a-slug).
from valley.properties import SlugProperty
slug = SlugProperty(required=True,min_length=1,max_length=20)
slug.validate('some-slug','Slug')
- Validators from BaseProperty
- StringValidator
- MinLengthValidator (if min_length kwarg is set)
- MaxLengthValidator (if max_length kwarg is set)
- SlugValidator
Validates that the input is a string type but is also in valid email format.
from valley.properties import EmailProperty
email = EmailProperty(required=True,min_length=1,max_length=20)
email.validate('[email protected]','Email')
- Validators from BaseProperty
- StringValidator
- MinLengthValidator (if min_length kwarg is set)
- MaxLengthValidator (if max_length kwarg is set)
- EmailValidator
Validates that the input is a integer type.
from valley.properties import IntegerProperty
age = IntegerProperty(required=True,min_value=1,max_value=20)
age.validate(5,'Age')
- Validators from BaseProperty
- IntegerValidator
- MinValuehValidator (if min_value kwarg is set)
- MaxLengthValidator (if max_value kwarg is set)
Validates that the input is a float type.
from valley.properties import FloatProperty
gpa = FloatProperty(required=True,min_value=1,max_value=20)
gpa.validate(4.0,'GPA')
- Validators from BaseProperty
- FloatValidator
- MinValuehValidator (if min_value kwarg is set)
- MaxLengthValidator (if max_value kwarg is set)
Validataes that the input is a bool type.
from valley.properties import BooleanProperty
active = BooleanProperty()
active.validate(True,'Active')
- Validators from BaseProperty
- BooleanValidator
Validates that the input is a date object or a string that can be transformed to a date object.
from valley.properties import DateProperty
active = DateProperty(required=True)
active.validate('2017-03-27','Active')
- Validators from BaseProperty
- DateValidator
Validates that the input is a datetime object or a string that can be transformed to a datetime object.
from valley.properties import DateTimeProperty
active = DateTimeProperty(required=True)
active.validate('2017-03-03 12:00:00','Active')
- Validators from BaseProperty
- DateTimeValidator
Validates that the input is a dict object.
from valley.properties import DictProperty
person = DictProperty(required=True)
person.validate({'first':'Eddie','last':'Murphy'},'First Name')
- Validators from BaseProperty
- DictValidator
Validates that the input is a list object.
from valley.properties import ListProperty
schools = ListProperty(required=True)
schools.validate(['Jones School','Edwards School'],'Schools')
- Validators from BaseProperty
- ListValidator
Validates that the input is an instance of another class
from valley.properties import ForeignProperty
district = ForeignProperty(District,required=True)
district.validate(District(name='Durham'),'District')
- Validators from BaseProperty
- ForeignValidator
Validates that the input is an instance of another class
from valley.properties import ForeignListProperty
great_schools = ForeignListProperty(School,required=True)
great_schools.validate([School(name='Duke'),School(name='Hampton University')],'Great Schools')
#Go Duke
terrible_schools = ForeignListProperty(School,required=True)
terrible_schools.validate([School(name='UNC'),School(name='Howard')],'Terrible Schools')
- Validators from BaseProperty
- ListValidator
- ForeignListValidator
Paired with the json.dumps it parses through Schema objects and returns valid json.
import json
from valley.utils.json_utils import ValleyEncoder
from valley.contrib import Schema
from valley.properties import *
class NameSchema(Schema):
_create_error_dict = True
name = CharProperty(required=True)
def __unicode__(self):
return self.name
class Breed(NameSchema):
pass
class Dog(NameSchema):
breed = ForeignProperty(Breed,required=True)
class Troop(NameSchema):
dogs = ForeignListProperty(Dog)
primary_breed = ForeignProperty(Breed)
>>> cocker = Breed(name='Cocker Spaniel')
>>> cockapoo = Breed(name='Cockapoo')
>>> bruno = Dog(name='Bruno',breed=cocker)
>>> blitz = Dog(name='Blitz',breed=cockapoo)
>>> durham = Troop(name='Durham',dogs=[bruno,blitz],primary_breed=cocker)
>>> print(json.dumps(durham, cls=ValleyEncoder))
{
"dogs": [
{
"breed": {
"name": "Cocker Spaniel",
"_type": "valley.tests.examples.schemas.Breed"
},
"name": "Bruno",
"_type": "valley.tests.examples.schemas.Dog"
},
{
"breed": {
"name": "Cockapoo",
"_type": "valley.tests.examples.schemas.Breed"
},
"name": "Blitz",
"_type": "valley.tests.examples.schemas.Dog"
}
],
"primary_breed": {
"name": "Cocker Spaniel",
"_type": "valley.tests.examples.schemas.Breed"
},
"name": "Durham",
"_type": "valley.tests.examples.schemas.Troop"
}
Same as ValleyEncoder except it doesn't add _type attributes.
import json
from valley.utils.json_utils import ValleyEncoderNoType
from valley.contrib import Schema
from valley.properties import *
class NameSchema(Schema):
_create_error_dict = True
name = CharProperty(required=True)
def __unicode__(self):
return self.name
class Breed(NameSchema):
pass
class Dog(NameSchema):
breed = ForeignProperty(Breed,required=True)
class Troop(NameSchema):
dogs = ForeignListProperty(Dog)
primary_breed = ForeignProperty(Breed)
>>> cocker = Breed(name='Cocker Spaniel')
>>> cockapoo = Breed(name='Cockapoo')
>>> bruno = Dog(name='Bruno',breed=cocker)
>>> blitz = Dog(name='Blitz',breed=cockapoo)
>>> durham = Troop(name='Durham',dogs=[bruno,blitz],primary_breed=cocker)
>>> print(json.dumps(durham, cls=ValleyEncoderNoType))
{
"dogs": [
{
"breed": {
"name": "Cocker Spaniel"
},
"name": "Bruno"
},
{
"breed": {
"name": "Cockapoo"
},
"name": "Blitz"
}
],
"primary_breed": {
"name": "Cocker Spaniel"
},
"name": "Durham"
}
Paired with the json.loads it create Schema objects from json
import json
from valley.utils.json_utils import ValleyDecoder
json_string = '{
"dogs": [
{
"breed": {
"name": "Cocker Spaniel",
"_type": "valley.tests.examples.schemas.Breed"
},
"name": "Bruno",
"_type": "valley.tests.examples.schemas.Dog"
},
{
"breed": {
"name": "Cockapoo",
"_type": "valley.tests.examples.schemas.Breed"
},
"name": "Blitz",
"_type": "valley.tests.examples.schemas.Dog"
}
],
"primary_breed": {
"name": "Cocker Spaniel",
"_type": "valley.tests.examples.schemas.Breed"
},
"name": "Durham",
"_type": "valley.tests.examples.schemas.Troop"
}'
>>> durham = json.loads(json_string,cls=ValleyDecoder)
<Troop: Durham >
>>> durham.name
'Durham
>>> durham.primary_breed.name
Cocker Spaniel