Accessing Config values¶
The Data Context¶
Once the data is loaded, it can be accessed anywhere in your application by just accessing the attribute on your config object.
var = config.my_var
Whenever you access a value on the config object, it searches through all of the rulesets that is has for the specified key. It then uses its current_context to pick the one that is a match with the highest specificity. In the above example, there is no context, so it searches with “” as the selector string. You can use config.context(selector) as a context manager to get deeper values-
with config.context("task.default_task environment"):
assert config.setting_a == "inner"
The context works like the nested tree of an html structure. the model
with config.context("el.myclass"):
config.the_value
with config.context("child"):
config.the_value
with config.context("par#inner"):
config.the_value
would have the same effect as an html structure of
<el class="myclass">
the_value
<child>
the_value
<par id=inner>
the_value
</par>
</child>
</el>
if you had a ruleset like
the_value: 0
el:
the_value: 1
child:
the_value: 2
par:
the_value: 3
.myclass:
the_value: 4
#inner:
the_value: 5
.myclass #inner:
the_value: 6
el child:
the_value: 7
The output would be - 4 - 7 - 6
Using Schemas¶
Schemas let you enforce structure on rules- what attributes are actually valid for any particular element type. We have seen how to define them, lets see how you can use them.
class Task(ElementSchema):
taskval: str
config = SettingsManager([data], [Task])
print(config.task().someval)
Each ElementSchema has a _name_ associated with it. When you access that name on the SettingsManager object, it will create an instance of the Schema for you. Basically, it will push the element onto the search context so that any values you lookup will come from that element. You can pass extra context as well using the name and identifier arguments-
with config.context("parent"):
config.task(identifier="mytask").someval
In this case, someval would be looked up with the context “parent task#mytask”. Schema objects aren’t context managers, they keep a closure of the context when they were created, so this
with config.context("parent"):
task = config.task(identifier="mytask")
val = task.someval
would work the same way as the previous example. Schema objects also provides a convenience method load() which will return a dictionary of all of the resolved properties that are defined on the schema. Its the equivalent of
data = {key: getattr(task, key) for key in Task.__props__}
Debugging¶
It can be hard to figure out the problem if the program doesn’t find a key you expect. To get better info, set the logging level to DEBUG, or if your app doesn’t use logging, set the environment variable SETTINGS_LOGGER=DEBUG