tiramisu/doc/browse.md

350 lines
6.7 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Browse the Config
## Getting the options
Create a simple Config:
```python
from asyncio import run
from tiramisu import Config
from tiramisu import StrOption, OptionDescription
# let's declare some options
var1 = StrOption('var1', 'first option')
# an option with a default value
var2 = StrOption('var2', 'second option', 'value')
# let's create a group of options
od1 = OptionDescription('od1', 'first OD', [var1, var2])
# let's create another group of options
rootod = OptionDescription('rootod', '', [od1])
async def main():
# let's create the config
cfg = await Config(rootod)
# the api is read only
await cfg.property.read_only()
# the read_write api is available
await cfg.property.read_write()
return cfg
cfg = run(main())
```
We retrieve by path an option named "var1" and then we retrieve its name and its docstring:
```python
async def main():
print(await cfg.option('od1.var1').option.name())
print(await cfg.option('od1.var1').option.doc())
run(main())
```
returns:
```
var1
first option
```
## Accessing the values of the options
Let's browse the configuration structure and option values.
You have getters as a "get" method on option objects:
1. getting all the options
```python
async def main():
print(await cfg.value.dict())
run(main())
```
returns:
```
{'var1': None, 'var2': 'value'}
```
2. getting the "od1" option description
```python
async def main():
print(await cfg.option('od1').value.dict())
run(main())
```
returns:
```
{'od1.var1': None, 'od1.var2': 'value'}
```
3. getting the var1 option's value
```python
async def main():
print(await cfg.option('od1.var1').value.get())
run(main())
```
returns:
```
None
```
4. getting the var2 option's default value
```python
async def main():
print(await cfg.option('od1.var2').value.get())
run(main())
```
returns:
```
value
```
5. trying to get a non existent option's value
```python
async def main():
try:
await cfg.option('od1.idontexist').value.get()
except AttributeError as err:
print(str(err))
run(main())
```
returns:
```
unknown option "idontexist" in optiondescription "first OD"
```
## Setting the value of an option
An important part of the setting's configuration consists of setting the
value's option.
You have setters as a "set" method on option objects.
And if you wanna come back to a default value, use the "reset()" method.
1. changing the "od1.var1" value
```python
async def main():
await cfg.option('od1.var1').value.set('éééé')
print(await cfg.option('od1.var1').value.get())
run(main())
```
returns:
```
éééé
```
2. carefull to the type of the value to be set
```python
async def main():
try:
await cfg.option('od1.var1').value.set(23454)
except ValueError as err:
print(str(err))
run(main())
```
returns:
```
"23454" is an invalid string for "first option"
```
3. let's come back to the default value
```python
async def main():
await cfg.option('od1.var2').value.reset()
print(await cfg.option('od1.var2').value.get())
run(main())
```
returns:
```
value
```
> **_Important_** If the config is "read only", setting an option's value isn't allowed, see [property](property.md).
Let's make the protocol of accessing a Config's option explicit
(because explicit is better than implicit):
1. If the option has not been declared, an "Error" is raised,
2. If an option is declared, but neither a value nor a default value has
been set, the returned value is "None",
3. If an option is declared and a default value has been set, but no value
has been set, the returned value is the default value of the option,
4. If an option is declared, and a value has been set, the returned value is
the value of the option.
But there are special exceptions. We will see later on that an option can be a
mandatory option. A mandatory option is an option that must have a value
defined.
Searching for an option
~~~~~~~~~~~~~~~~~~~~~~~~~~
In an application, knowing the path of an option is not always feasible.
That's why a tree of options can easily be searched with the "find()" method.
```python
from asyncio import run
from tiramisu import Config
from tiramisu import OptionDescription, StrOption
from tiramisu.setting import undefined
var1 = StrOption('var1', '')
var2 = StrOption('var2', '')
var3 = StrOption('var3', '')
od1 = OptionDescription('od1', '', [var1, var2, var3])
var4 = StrOption('var4', '')
var5 = StrOption('var5', '')
var6 = StrOption('var6', '')
var7 = StrOption('var1', '', 'value')
od2 = OptionDescription('od2', '', [var4, var5, var6, var7])
rootod = OptionDescription('rootod', '', [od1, od2])
```
Let's find an option by it's name
And let's find first an option by it's name
The search can be performed in a subtree
```python
async def main():
cfg = await Config(rootod)
print(await cfg.option.find(name='var1'))
run(main())
```
returns:
```
[<tiramisu.api.TiramisuOption object at 0x7f490a530f98>, <tiramisu.api.TiramisuOption object at 0x7f490a530748>]
```
If the option name is unique, the search can be stopped once one matched option has been found:
```python
async def main():
cfg = await Config(rootod)
print(await cfg.option.find(name='var1', first=True))
run(main())
```
returns:
```
<tiramisu.api.TiramisuOption object at 0x7ff27fc93c70>
```
Search object behaves like a cfg object, for example:
```python
async def main():
cfg = await Config(rootod)
option = await cfg.option.find(name='var1', first=True)
print(await option.option.name())
print(await option.option.doc())
run(main())
```
returns:
```
var1
var1
```
Search can be made with various criteria:
```python
async def main():
cfg = await Config(rootod)
await cfg.option.find(name='var3', value=undefined)
await cfg.option.find(name='var3', type=StrOption)
run(main())
```
The find method can be used in subconfigs:
```python
async def main():
cfg = await Config(rootod)
print(await cfg.option('od2').find('var1'))
run(main())
```
## The "dict" flattening utility
In a config or a subconfig, you can print a dict-like representation
In a "fullpath" or a "flatten" way
- get the "od1" option description:
```python
async def main():
cfg = await Config(rootod)
print(await cfg.option('od1').value.dict(fullpath=True))
run(main())
```
returns:
```
{'od1.var1': None, 'od1.var2': None, 'od1.var3': None}
```
```python
async def main():
cfg = await Config(rootod)
print(await cfg.option('od1').value.dict(fullpath=False))
run(main())
>>> print(cfg.option('od1').value.dict(fullpath=True))
```
returns:
```
{'var1': None, 'var2': None, 'var3': None}
```
> **_NOTE_** be carefull with this "flatten" parameter, because we can just loose some options if there are same name (some option can be overriden).