kinto
kinto copied to clipboard
Kinto plugins settings can't be loaded using ENV variable
During the initialization phase, we are checking for each Kinto default settings if any env variable are defined.
https://github.com/Kinto/kinto/blob/master/kinto/core/initialization.py#L512-L514
However it only works for kinto default settings, I believe it doesn't for plugin's settings.
We iterate on the settings defined in the .ini + the defaults:
https://github.com/Kinto/kinto/blob/86a9943b428b8e7fab53190bf840222f5c833225/kinto/core/initialization.py#L480-L497
What would we be your suggestion?
Note that the plugin include happens after the initialization phase:
https://github.com/Kinto/kinto/blob/86a9943b428b8e7fab53190bf840222f5c833225/kinto/core/init.py#L202-L205
Does it means that if we want to override a value with ENV variables we need to define it with a wrong value in the ini file?
According to my understanding of the code, it seems like a workaround yes
Unless we add a helper like request.get_setting("key", 128) and use it instead of request.registry.settings.get() I don't see how we could fix this.
This might be a stupid question, but why? Can't we just iterate over everything in sys.env and look for things that seem like they could be settings?
Ok, we can add an additional initialization step that does that.
But I think the input list should be settings names because I'm not sure we can reverse (SIGNER_CID_PATH should be signer.cid.path or signer_cid.path?)
I like the idea of a helper like request.config() with options similar to python-decouple
config.kinto_setting("mail.host", default="localhost")
config.kinto_setting("mail.port", cast=int, default=25)
config.kinto_setting("mail.password", env="PASSWD")
In core/__init__.py, add a kinto_setting directive with something like that:
def kinto_setting(config, name, default=None, cast=None, env=None):
config.registry.kinto_settings[name] = {
"default": default,
"cast": cast,
"env": env or name.upper(),
}
config.add_directive("kinto_setting", kinto_setting)
And then in load_default_settings(config, default_settings), read these info from config.registry.kinto_settings to enhance/process the config.settings values that come from the .ini file.
Depending on the order of things at startup (whether load_default_settings() or config.kinto_setting("mail.host") is called first), it could be relevant to enhance the config.settings from the kinto_setting() directive.
def kinto_setting(config, name, default=None, cast=None, env=None):
enhanced = {}
from_env = os.getenv(env or name.upper(), default)
value = config.settings.get(name, from_env)
if cast:
value = cast(value)
enhanced[name] = value
config.add_settings(enhanced)