Strict Dict (json) with schema validation embedded
Project description
stricto
Strict json structure with schema validation
The way to use is very simple, see Quickstart for a basic setup.
The main difference with jsonschema is that the schema is directly in types of data. You don't have to validate them.
Installation
pip install git+https://github.com/bwallrich/stricto
Quickstart
from stricto import Dict, Int, String, List
a=Dict({
"name" : String(),
"address" : Dict({
"num" : Int(),
"street" : String()
}),
"nicknames" : List( String() )
})
a.set({
"name" : "Edward",
"address" : {
"num" : 22,
"street" : "acacia avenue"
},
"nicknames" : [ "Ed" ]
})
print(a.address.num) # 22
print(a.address) # { "num" : 22, "street" : "acacia avenue" }
a.name = 666 # -> raise a typeError (must be a string)
print (a) # { "name" : "Edward", ... }
a.nicknames.append(666) # -> raise a typeError (must be a string)
a.nicknames.append("Eddy")
a.nickname[1] # -> Eddy
b=a # b is a reference on a
c=a.copy() # c is a different object : c is a copy
c == b # return True (you can test and do operators directly on objects)
b.nicknames.pop()
c == b # return False
Basic types
All basic class from python are implemented in stricto.
| python class | type in stricto |
|---|---|
| bool | Bool() |
| int | Int() |
| float | Float() |
| string | String() |
| list | List() |
| dict | Dict() |
| In() |
# example
from stricto import Dict, Int
a = Int()
a.set(22) # -> ok
a.set(23.1) # raise an error
a.set("the number of the beast") # raise an error
# WARNING
a = "the number of the beast" # works ! the affectation of "a" change. Now it is a string. This is python.
# Inside a Dict().
test=Dict({
"a" : Int()
})
test.a = 22 # -> ok
test.a = 23.1 # raise an error
test.a = "the number of the beast" # raise an error
json
use .get_value() to extract a dict from a Dict and do the json.dumps like usual.
# example
from stricto import Int, List, String, Dict, Error
import json
model={
"b" : Int(),
"e" : List( String())
}
a=Dict(model)
b=Dict(model)
a.set({ "b" : 1, "e" : [ "aa", "bb"]})
sa = json.dumps(a.get_value()) # json dumps
b.set( json.loads(sa) )
b == a # return True
Types and options
All types
available options for all types ares :
| Option | Default | Description |
|---|---|---|
notNone=True|False |
False | cannot be None |
required=True|False |
False | similar to notNone |
description="whatever you want" |
None | a description of this object |
default=666 |
None | the default value |
in=[ 1, 2, 3, 5 ]|func |
None | the value must be one of those elements |
union=[ 1, 2, 3, 5 ]|func |
None | similar to in |
transform=func |
None | a function to transform the value before setting it |
constraint=func |
None | a constraints to check the value before setting it |
constraints=[func] |
None | a list of constraints to check the value before setting it |
onchange=func |
None | a onchange function trigged when the value change |
onChange=func |
None | similar to onchange |
set=func |
None | a read only value, calculated from other .See set or compute function |
compute=func |
None | similar to set |
exists=func |
True | a function to say if the object "exists", depending on values from other attributs. See exists for details |
See functions for mor details and examples how to use them.
Int()
Int( options ) is for integer.
Int( options ) use generic options.
available specific options for Int() ares :
| Option | Default | Description |
|---|---|---|
min= |
None | minimum value |
minimum=21 |
None | similar to min |
max=99 |
None | maximum value |
maximum=99 |
None | similar to max=99 |
# example
from stricto import Dict, Int, String
client = Dict{
"age" : Int( min=21, max=120)
}
client.age = 12 # -> raise an error
client.age = 120 # -> Ok
newAge = client.age+1 # -> raise an Error ( > max ) newAge is implicitly an Int( min=21, max=120))
newAge = 1+client.age # -> Ok (newAge is implicitly an int)
String()
String( options ) is for strings.
String( options ) use generic options.
available specific options for Int() ares :
| Option | Default | Description |
|---|---|---|
pattern=regexp |
None | must match this regexp |
patterns=[reg1, reg2] |
None | must match all regexps |
regexp= |
None | similar to pattern |
Examples
a=String( pattern='^A' )
a.set('Foo') # -> raise an error
a.set('AZERTY') # OK
# list of regexp
a=String( patterns=[ '^A', r'.*Z$' ] )
a.set('Allo') # -> raise an error
a.set('AtoZ') # OK
# function return a regexp
a=String( pattern=lambda self, value, root : r'.*Z$')
a.set('Allo') # -> raise an error
a.set('AtoZ') # OK
In()
In( [ Array of types ] ) is not a type, but an union of diffferent types.
In( options ) use generic options.
# example
from stricto import In, Int, String
a = In( [ Int(), String() ] )
a.set("hello") # -> OK
a.count('h') # -> return 1
a.set(12) # -> OK
a.bit_length() # -> return 4
a.count('h') # -> return None
a.set(3.14) # -> raise an error
Functions
a func can return a value to adapt the result. It can bee a lambda too.
transform
Please see transform function
# example
from stricto import Dict, Int, String
def upper(value, o):
"""
transform the value into upper
value : the current value given ("worldcompagny" in this example).
o : the full object
"""
return value.upper()
company=Dict({
"name" : String( transform=upper ),
})
company.name="worldcompagny"
print(company.name) # -> "WORLDCOMPAGNY"
set or compute
# example
from stricto import Dict, Int, String
a=Dict({
"b" : Int( default = 0, set=lambda o: o.c+1 ),
"d" : Int( default = 0, set=lambda o: o.b+1 ),
"c" : Int( ),
})
# "b" and "d" cannot be modified by hand. the are recalculated every time another value
# change in the Dict.
a.b = 3 # -> raise an error
a.c = 2
print(a.b) # -> 3
print(a.d) # -> 4
constraints
# example
from stricto import Dict, Int, String
def check_pair(value, o): # pylint: disable=unused-argument
"""
return true if pair
"""
return not value % 2
a=Dict({
"b" : Int( default = 0, constraint=check_pair ), # check before setting
"d" : Int( constraint=lambda value, o : not value % 2 ), # same as above, with a lambda
"c" : Int( constraints=[ check_pair ] ), # A list of constraints
})
a.b = 2 # OK
a.c = 3 # -> raise an error
onchange
# example
from stricto import Dict, Int, String
def change_test(old_value, value, o): # pylint: disable=unused-argument
"""
just a change option
old_value -> The previous value
value -> the new one
o -> the root object = a in our example
"""
print(f"The value of b as changed from {old_value} to {value}")
a=Dict({
"b" : Int( default = 0, onchange=change_test )
})
a.b = 2 # -> output "The value of b as changed from 0 to 2"
a.b = 3-1 # -> nothing displayed
exists
A function wich must return True|False to say if this key exists.
# example
from stricto import Dict, Int, String
def check_if_female(value, o):
"""
return true if Female
"""
if o.gender == "Male":
return False
return True
cat=Dict({
"name" : String(),
"gender" : String( default = 'Male', in=[ 'Male', 'Female' ]),
"female_infos" : Dict(
{
"number_of_litter" : Int(default=0, required=True)
# ... some other attributes
}, exists=check_if_female )
})
a.set({ "name" : "Felix", "gender" : "Male" }
a.female_infos # -> None
a.female_infos.number_of_litter = 2 # -> Raise an Error
a.gender = "Female"
a.female_infos.number_of_litter = 2 # -> Ok
a.female_infos # -> { "number_of_litter" : 2 }
Tests
python -m unittest
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file stricto-0.0.2.tar.gz.
File metadata
- Download URL: stricto-0.0.2.tar.gz
- Upload date:
- Size: 90.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/5.0.0 CPython/3.9.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f971030427945ba5283195473b0ca3cac6b6449df7afed8827e1e5398d1117a0
|
|
| MD5 |
02cb95c269fd0d797adbb9cc85e28171
|
|
| BLAKE2b-256 |
d43031443e80dd4d3a699934250836019d0309a30beb380d8a060afb6c48f927
|
File details
Details for the file stricto-0.0.2-py3-none-any.whl.
File metadata
- Download URL: stricto-0.0.2-py3-none-any.whl
- Upload date:
- Size: 15.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/5.0.0 CPython/3.9.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ed1bb203341e78db73c80a14c9d297067b486759e09f1fc8e2e30c3f7407fd43
|
|
| MD5 |
a8d5343cf56e250c5ffabe7e52de448f
|
|
| BLAKE2b-256 |
ef8ae147d58239cb39b535371326ea96f0ce9d8eec2365b02c831dd8ba3a21f2
|