Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/outbrain-inc/valid_model
valid_model
https://github.com/outbrain-inc/valid_model
Last synced: 1 day ago
JSON representation
valid_model
- Host: GitHub
- URL: https://github.com/outbrain-inc/valid_model
- Owner: outbrain-inc
- License: mit
- Created: 2014-10-03T14:42:11.000Z (about 10 years ago)
- Default Branch: master
- Last Pushed: 2023-03-31T12:21:05.000Z (over 1 year ago)
- Last Synced: 2024-11-12T17:02:33.896Z (about 1 month ago)
- Language: Python
- Size: 38.1 KB
- Stars: 9
- Watchers: 11
- Forks: 4
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
valid_model
===========The valid_model library is intended to allow declarative modeling of an object schema in a similar way to various ORM and form validation libraries while making as few assumptions as possible about the way it will be used.
Attributes in a `valid_model.Object` instance are guaranteed to have all fields exist with defined restrictions and defaults available. In addition each field can have a mutator function applied to it to enforce uniformity. An example of this could be make a `String` attribute always be uppercase.
You can nest `Object` classes inside one another using the `EmbeddedObject`, `Set`, `Dict`, and `List` descriptors
The available descriptors are in `valid_model.descriptors` and include:
`Generic`, `String`, `Integer`, `Float`, `Bool`, `DateTime`, `TimeDelta`, `List`, `Set`, `Dict`, and `EmbeddedObject`When initializing an `Object` all initial values should be passed in as keyword arguments.
When setting an `EmbeddedObject` attribute, it will automatically convert a `dict` to the appropriate `Object` subclass.`Object` instances have `Object.__json__` defined to be used as a hook to convert objects into `dict` for easy serialization.
```python
class Person(Object):
name = String(nullable=False)
homepage = String()class BlogPost(Object):
title = String(nullable=False, mutator=lambda x: x.title())
updated = DateTime(nullable=False, default=datetime.utcnow) # default to time object is created
published = DateTime() # default value will be None
author = EmbeddedObject(Person)
contributors = List(value=EmbeddedObject(Person))
tags = List(value=String(nullable=False))def validate(self):
super(BlogPost, self).validate()
if self.published is not None and self.published > self.updated:
raise ValidationError('a post cannot be published at a later date than it was updated')post = BlogPost(title='example post', author={'name': 'Josh'}, tags=['tag1', 'tag2'])
"""
post.__json__() would output
{
'title': 'Example Post',
'author': {
'name': 'Josh',
'homepage': None
},
'contributors': [],
'updated': datetime(2014, 10, 6, 10, 23),
'published': None,
'tags': ['tag1', 'tag2']
}
"""
```
##Descriptor Options|Keyword Arg | Default | Description |
|:-----------|--------|:------------------
|nullable | `True`1 | determines if it is valid for an attribute to be set to None
|mutator | no mutator | allows some mutation to occur on the value. a common use case would be to format a string to always be uppercase
|validator | no validator| a function which returns truthy if the value is valid
|default | `None`2 | a scalar value or function which the attribute will be set to on object initialization if no value is specified at in the constuctor
|value| no descriptor3 | a descriptor to validate values in the container attribute
| key | no descriptor4 | a descriptor to validate keys in the container attribute
1 Not available on `Set`, `List`, and `Dict`. If an attribute with that descriptor is set to `None` it will actually set it to an empty instance of their respective types
2 Container objects `Set`, `List`, and `Dict` initialize to an empty instance of their respective types
3 Only available on `Dict`, `List`, and `Set`
4 Only available on `Dict``EmbededObject` takes one argument which is the `Object` class that is being embedded.
##How Validation Works
Validation occurs whenever an attribute is set.1. Typechecking and any type coercion implemented occurs
2. The value is checked if it is None
* If it is None and nullable == False a ValidationError is raised otherwise it is set to None
3. If mutator function is defined it will run
4. If a validator function is defined it will run
* A ValidationError is raised if the validator function returns falsey### Complex Validation
In addition to validators being defined on individual attributes there is a validate method on Object instances which may be overridden for more complicated validation logic that may include a combination of multiple fields. By default it will just revalidate all attributes of an `Object` instance.