Create self-validating Python objects using JSON schema.
Warlock is available on PyPI:
shell
pip install warlock
1) Create your schema
```python
>>> schema = {
'name': 'Country',
'properties': {
'name': {'type': 'string'},
'abbreviation': {'type': 'string'},
'population': {'type': 'integer'},
},
'additionalProperties': False,
}
```
2) Create a model
```python
>>> import warlock
>>> Country = warlock.model_factory(schema)
```
3) Create an object using your model
```python
>>> sweden = Country(name='Sweden', abbreviation='SE')
```
4) Let the object validate itself
```python
>>> sweden.name = 5
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "warlock/core.py", line 53, in __setattr__
raise InvalidOperation(msg)
warlock.core.InvalidOperation: Unable to set 'name' to '5'
>>> sweden.overlord = 'Bears'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "warlock/core.py", line 53, in __setattr__
raise InvalidOperation(msg)
warlock.core.InvalidOperation: Unable to set 'overlord' to 'Bears'
```
5) Generate a JSON Patch document to track changes
```python
>>> sweden.population=9453000
>>> sweden.patch
'[{"path": "/population", "value": 9453000, "op": "add"}]'
```
Can JSON Created Classes be Persisted to Disk or Writing to .py Files?
Thank you,
Added a convenience capability to read with dot notation for nested dicts and lists in model.
Example:
```
d = {'level1':{'level2':[{'leve3':'a'},{'level3':'b'}]}} f = warlock.model_factory({})
m = f(d) m.level1.level2[0].level3 'a' ``` Fixes #50
Hello, is there a way to enforce the rfc3339 date-time format (e.g. '2020-07-02T07:27:15+02:00')?
Currently this property would allow any string. 'time': {'type': 'string', 'format': 'date-time'}
Thanks in advance, Patrick
Hello,
If a JSON Schema is for a simple JSON object (string/number/integer), warlock will fail to bind and we can't instantiate object.
For example, given the following JSON Schema:
schema={
"$schema": "http://json-schema.org/draft-04/schema#",
"title": "Example",
"type": "string",
"enum": ['abc', 'xyz']
}
warlock
will fail to create an object
```
import warlock Example=warlock.model_factory(schema) Example('xyz') Traceback (most recent call last): File "
", line 1, in File "/usr/local/lib/python3.6/site-packages/warlock/core.py", line 35, in init base_class.init(self, args, kwargs) File "/usr/local/lib/python3.6/site-packages/warlock/model.py", line 30, in init d = dict(args, **kwargs) ValueError: dictionary update sequence element #0 has length 1; 2 is required ```
or
```
Example(='xyz') Traceback (most recent call last): File "/usr/local/lib/python3.6/site-packages/warlock/model.py", line 140, in validate jsonschema.validate(obj, self.schema) File "/usr/local/lib/python3.6/site-packages/jsonschema/validators.py", line 934, in validate raise error jsonschema.exceptions.ValidationError: {'': 'xyz'} is not of type 'string'
Failed validating 'type' in schema: {'$schema': 'http://json-schema.org/draft-04/schema#', 'enum': ['abc', 'xyz'], 'title': 'Example', 'type': 'string'}
On instance: {'_': 'xyz'}
During handling of the above exception, another exception occurred:
Traceback (most recent call last): File "/usr/local/lib/python3.6/site-packages/warlock/model.py", line 33, in init self.validate(d) File "/usr/local/lib/python3.6/site-packages/warlock/model.py", line 142, in validate raise exceptions.ValidationError(str(exc)) warlock.exceptions.ValidationError: {'_': 'xyz'} is not of type 'string'
Failed validating 'type' in schema: {'$schema': 'http://json-schema.org/draft-04/schema#', 'enum': ['abc', 'xyz'], 'title': 'Example', 'type': 'string'}
On instance: {'_': 'xyz'}
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "
Failed validating 'type' in schema: {'$schema': 'http://json-schema.org/draft-04/schema#', 'enum': ['abc', 'xyz'], 'title': 'Example', 'type': 'string'}
On instance: {'_': 'xyz'} ```
Got KeyError referring to schema object with default value:
``` import warlock
schema = { "title": "Message", "type": "object", "properties": { "sender": { "title": "Sender", "type": "string" }, "trace": { "title": "Trace", "default": [], "type": "array", "items": { "type": "string" } } }, "required": [ "sender" ], 'additionalProperties': True }
Message = warlock.model_factory(schema) m = Message(sender="who")
m.trace # got error ```
I am using MongoDB and since MongoDB adds a "_id" field before saving an element to the Database, I made a Base class as follows:
python
mongo_db_base_schema = {
'type': 'object',
'properties': {'_id': {}},
}
BaseClass = warlock.model_factory(mongo_db_base_schema)
When I now use SomeOtherModel = warlock.model_factory(other_model_schema, base_class=BaseClass)
where other_model_schema
contains an enum, my enum validation stops working.
EDIT: It does not seem to just break enum validation. For me it breaks the entire validation. So using a BaseClass is pretty much useless because my entire validation breaks.
poetry.lock
file in version control. #44 Model.changes
. #46 assertEquals
in tests. #45model_factory
back to pre-1.3 call signature. #39Picking the project back up. 🎉
Changes are mostly limited to project scaffolding and CI testing (dropping support for a few EOL-ed Python versions). Most importantly this release bumps the dependency requirement of jsonschema
to make it compatible with v3 of the package and therefore add support for JSON schema draft 7.
Should your project depend on Warlock validating against Draft 4 of JSON Schema, make sure to declare a direct dependency on jsonschema<3
in your project's requirements.
<4
tests/
directory