Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ability to read config variables from env #933

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 29 additions & 6 deletions donkeycar/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
"""
import os
import types

import ast
from logging import getLogger

class Config:

Expand Down Expand Up @@ -39,9 +40,18 @@ def show(self):
if attr.isupper():
print(attr, ":", getattr(self, attr))


def load_config(config_path=None, myconfig="myconfig.py"):

"""
There's an ability to read config variables from env

Usage example:

`DONKEYCAR_CFG_MAX_LOOPS=2000 python manage.py drive`

this command will override config variable MAX_LOOPS and set it to 2000
this is the equivalent of having MAX_LOOPS=2000 in the myconfig.py
"""

if config_path is None:
import __main__ as main
main_path = os.path.dirname(os.path.realpath(main.__file__))
Expand All @@ -51,19 +61,20 @@ def load_config(config_path=None, myconfig="myconfig.py"):
if os.path.exists(local_config):
config_path = local_config

print('loading config file: {}'.format(config_path))
logger = getLogger()
logger.info('loading config file: {}' . format(config_path))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great, we should be moving to logging. Can you please also use f-strings?

cfg = Config()
cfg.from_pyfile(config_path)

# look for the optional myconfig.py in the same path.
personal_cfg_path = config_path.replace("config.py", myconfig)
if os.path.exists(personal_cfg_path):
print("loading personal config over-rides from", myconfig)
logger.info(f"loading personal config over-rides from {myconfig}")
personal_cfg = Config()
personal_cfg.from_pyfile(personal_cfg_path)
cfg.from_object(personal_cfg)
else:
print("personal config: file not found ", personal_cfg_path)
logger.info(f"personal config: file not found {personal_cfg_path}")

# derived settings
if hasattr(cfg, 'IMAGE_H') and hasattr(cfg, 'IMAGE_W'):
Expand All @@ -72,4 +83,16 @@ def load_config(config_path=None, myconfig="myconfig.py"):
if hasattr(cfg, 'IMAGE_DEPTH'):
cfg.TARGET_D = cfg.IMAGE_DEPTH

# from env
for attr in dir(cfg):
if attr.isupper():
cfg_name = f'DONKEYCAR_CFG_{attr}'
new_value = os.getenv(cfg_name)
if new_value is not None:
old_val = getattr(cfg, attr)
new_value_casted = ast.literal_eval(new_value)
attr_type = type(new_value_casted)
setattr(cfg, attr, new_value_casted)
logger.info(f'Set cfg var from env: {attr}={new_value} (type={attr_type} old_val={old_val})')

return cfg