A Dict-to-Dict YAML/JSON serializable template language
Project description
# girolamo
JSON/YAML serializable templates for dict-to-dict transformations.
## Quickstart
### Installation
```shell
$ pip install -r requirements-dev.txt
$ pip install .
```
### Hello World !
```python
from girolamo import Template
HELLO_WORLD_TPL = {
'a': 'Girolamo fecit',
'hw': {'$list-join': [' ', ['$$a', '$$b', '!']]},
}
DICTIN = {
'a': 'Hello',
'b': 'World'
}
ctemplate = Template.compile(HELLO_WORLD_TPL)
dictout = ctemplate.eval(data=DICTIN)
print dictout
```
Result
```python
{'a': 'Girolamo fecit', 'hw': 'Hello World !'}
```
### Templates in YAML/JSON
*girolamo* templates can be directly represented in YAML:
```yaml
a: Girolamo fecit
hw:
$list-join:
- ' '
- [$$a, $$b, '!']
```
and JSON
```json
{
"a": "Girolamo fecit",
"hw": {
"$list-join": [
" ",
[ "$$a", "$$b", "!" ]
]
}
}
```
## Templates
Templates in *girolamo* are dictionaries. The value of each key in the template is an expression. Each key in the template becomes a key in the output dictionary with value the result of the evaluation of the associated expression.
## Expressions
|Expression *exp*|Value *eval(exp)*|
|----------|-----|
|*number*|The number|
|*string*|The string|
|*None*|*None*|
|{ key1: *exp1*, key2: *exp2*, ... }|The dictionary { key1: *eval(exp1)*, key2: *eval(exp2)*, ... }|
|[ *exp1*, *exp2*, ... ]|The list [ *eval(exp1)*, *eval(exp2)*, ... ]|
|$$*key*|The value of *key* in the input dictionary|
|$*symbol*|The value of *symbol* in the current environment|
|{$*function*: [ *exp1*, *exp2*, ... ]}|The result of calling *function* with [ *eval(exp1)*, *eval(exp2)*, ... ]|
|{$*function*: *exp1*}|The result of calling *function* with [ *eval(exp1)* ]|
### if...then...else
The special function *if* can be used for conditionals. The format is:
```python
{
"$if": [
pred,
conseq,
alt
]
}
```
where *pred*, *conseq* and *alt* are expressions. If *pred* is true then *conseq* is evaluated and the result is returned, otherwise *conseq* is evaluated and the result returned.
Example:
```yaml
# is_network is true if __indicator is an IP Network
is_network:
$if:
- { $is-unicast: $$__indicator }
- false
- true
```
### Match
The special function *match* can be used to select between multiple options. The format is:
```python
{
"$match": [
var,
[pred1, exp1], [pred2, exp2], ...],
default
]
}
```
The expression *var* is evaluated and the value compared in order with the predicate expressions *pred1*, *pred2*, ... When a predicate expression is true the associated expression is evaluated and the result is returned. If none of the predicate expressions is true *default* is evaluated and the result returned.
Example:
```yaml
# ip_version is set to 4 if the type key of the input dictionary is "IPv4"
# set to 6 if the type key is "IPv6"
# set to null/None otherwise
ip_version:
$match:
- $$type
- [["IPv4", 4], ["IPv6", 6]]
- null
```
### Assignments
The special function *define* can be used to assign a value to a symbol in the current environment. The format is:
```python
{
"$define": [
symbol,
value
]
}
```
The expression *value* is evaluated and the result assigned to *symbol* in the current environment. Return value of *define* is *None*.
### Lambdas
The special function *lambda* can be used to define anonymous functions. The format is:
```python
{
"$lambda": [
[ formal1, formal2, ... ],
body
]
}
```
If a single formal is required the needed could also be:
```python
{
"$lambda": [
formal1,
body
]
}
```
### Quick lambdas
A function call with paramater *$_* evaluates in a lambda function. Basically the format:
```python
{
"$function": [ exp1, exp2, "$_" ]
}
```
is equivalent to:
```python
{
"$lambda": [
"$_",
{ "$function": [ exp1, exp2, "$_" ] }
]
}
```
## Globals in template ($ Keys)
A template key starting with *$* is handled as the definition of a global symbol that can be used in the evaluation of all the template keys.
Example:
```python
{
# defines the interesting-fields symbol
"$interesting-fields": [
"phishme_threatType",
"phishme_label",
"phishme_threatDetailURL",
"recordedfuture_entityurl",
"proofpoint_etintelligence_max_score",
"proofpoint_etintelligence_categories",
"bambenekconsulting_description",
"bambenekconsulting_info"
]
}
```
JSON/YAML serializable templates for dict-to-dict transformations.
## Quickstart
### Installation
```shell
$ pip install -r requirements-dev.txt
$ pip install .
```
### Hello World !
```python
from girolamo import Template
HELLO_WORLD_TPL = {
'a': 'Girolamo fecit',
'hw': {'$list-join': [' ', ['$$a', '$$b', '!']]},
}
DICTIN = {
'a': 'Hello',
'b': 'World'
}
ctemplate = Template.compile(HELLO_WORLD_TPL)
dictout = ctemplate.eval(data=DICTIN)
print dictout
```
Result
```python
{'a': 'Girolamo fecit', 'hw': 'Hello World !'}
```
### Templates in YAML/JSON
*girolamo* templates can be directly represented in YAML:
```yaml
a: Girolamo fecit
hw:
$list-join:
- ' '
- [$$a, $$b, '!']
```
and JSON
```json
{
"a": "Girolamo fecit",
"hw": {
"$list-join": [
" ",
[ "$$a", "$$b", "!" ]
]
}
}
```
## Templates
Templates in *girolamo* are dictionaries. The value of each key in the template is an expression. Each key in the template becomes a key in the output dictionary with value the result of the evaluation of the associated expression.
## Expressions
|Expression *exp*|Value *eval(exp)*|
|----------|-----|
|*number*|The number|
|*string*|The string|
|*None*|*None*|
|{ key1: *exp1*, key2: *exp2*, ... }|The dictionary { key1: *eval(exp1)*, key2: *eval(exp2)*, ... }|
|[ *exp1*, *exp2*, ... ]|The list [ *eval(exp1)*, *eval(exp2)*, ... ]|
|$$*key*|The value of *key* in the input dictionary|
|$*symbol*|The value of *symbol* in the current environment|
|{$*function*: [ *exp1*, *exp2*, ... ]}|The result of calling *function* with [ *eval(exp1)*, *eval(exp2)*, ... ]|
|{$*function*: *exp1*}|The result of calling *function* with [ *eval(exp1)* ]|
### if...then...else
The special function *if* can be used for conditionals. The format is:
```python
{
"$if": [
pred,
conseq,
alt
]
}
```
where *pred*, *conseq* and *alt* are expressions. If *pred* is true then *conseq* is evaluated and the result is returned, otherwise *conseq* is evaluated and the result returned.
Example:
```yaml
# is_network is true if __indicator is an IP Network
is_network:
$if:
- { $is-unicast: $$__indicator }
- false
- true
```
### Match
The special function *match* can be used to select between multiple options. The format is:
```python
{
"$match": [
var,
[pred1, exp1], [pred2, exp2], ...],
default
]
}
```
The expression *var* is evaluated and the value compared in order with the predicate expressions *pred1*, *pred2*, ... When a predicate expression is true the associated expression is evaluated and the result is returned. If none of the predicate expressions is true *default* is evaluated and the result returned.
Example:
```yaml
# ip_version is set to 4 if the type key of the input dictionary is "IPv4"
# set to 6 if the type key is "IPv6"
# set to null/None otherwise
ip_version:
$match:
- $$type
- [["IPv4", 4], ["IPv6", 6]]
- null
```
### Assignments
The special function *define* can be used to assign a value to a symbol in the current environment. The format is:
```python
{
"$define": [
symbol,
value
]
}
```
The expression *value* is evaluated and the result assigned to *symbol* in the current environment. Return value of *define* is *None*.
### Lambdas
The special function *lambda* can be used to define anonymous functions. The format is:
```python
{
"$lambda": [
[ formal1, formal2, ... ],
body
]
}
```
If a single formal is required the needed could also be:
```python
{
"$lambda": [
formal1,
body
]
}
```
### Quick lambdas
A function call with paramater *$_* evaluates in a lambda function. Basically the format:
```python
{
"$function": [ exp1, exp2, "$_" ]
}
```
is equivalent to:
```python
{
"$lambda": [
"$_",
{ "$function": [ exp1, exp2, "$_" ] }
]
}
```
## Globals in template ($ Keys)
A template key starting with *$* is handled as the definition of a global symbol that can be used in the evaluation of all the template keys.
Example:
```python
{
# defines the interesting-fields symbol
"$interesting-fields": [
"phishme_threatType",
"phishme_label",
"phishme_threatDetailURL",
"recordedfuture_entityurl",
"proofpoint_etintelligence_max_score",
"proofpoint_etintelligence_categories",
"bambenekconsulting_description",
"bambenekconsulting_info"
]
}
```