From 4e4d0ca9caf32ecc75ebba78c15d885501d25ebc Mon Sep 17 00:00:00 2001 From: montezdesousa <79287829+montezdesousa@users.noreply.github.com> Date: Wed, 18 Jan 2023 13:52:05 +0000 Subject: [PATCH] change .env loading priority (#4005) --- openbb_terminal/core/config/paths.py | 22 +++++++++++---- openbb_terminal/featflags_controller.py | 37 ++++++++++++------------- openbb_terminal/feature_flags.py | 14 ++++------ openbb_terminal/helper_funcs.py | 5 ++-- openbb_terminal/settings_controller.py | 28 +++++++++---------- openbb_terminal/terminal_controller.py | 6 ++-- 6 files changed, 58 insertions(+), 54 deletions(-) diff --git a/openbb_terminal/core/config/paths.py b/openbb_terminal/core/config/paths.py index 3aea1930ef3..a710d05e476 100644 --- a/openbb_terminal/core/config/paths.py +++ b/openbb_terminal/core/config/paths.py @@ -1,14 +1,26 @@ # IMPORTATION STANDARD from pathlib import Path import os -import dotenv +from dotenv import load_dotenv + + +def load_dotenv_with_priority(): + """Loads the dotenv files in the following order: + 1. Repository .env file + 2. Package .env file + 3. User .env file + + This allows the user to override the package settings with their own + settings, and the package to override the repository settings. + """ + load_dotenv(REPOSITORY_ENV_FILE, override=True) + load_dotenv(PACKAGE_ENV_FILE, override=True) + load_dotenv(USER_ENV_FILE, override=True) def get_user_data_directory(): - """ " - Gets user data path from .env file - """ - dotenv.load_dotenv(USER_ENV_FILE) + """Gets user data path from .env file or returns default path""" + load_dotenv_with_priority() if os.getenv("OPENBB_USER_DATA_DIRECTORY"): user_data_directory = Path(os.getenv("OPENBB_USER_DATA_DIRECTORY")) else: diff --git a/openbb_terminal/featflags_controller.py b/openbb_terminal/featflags_controller.py index 8d52c1b5700..8470d349766 100644 --- a/openbb_terminal/featflags_controller.py +++ b/openbb_terminal/featflags_controller.py @@ -10,6 +10,7 @@ from dotenv import set_key # IMPORTATION INTERNAL from openbb_terminal import feature_flags as obbff +from openbb_terminal.core.config.paths import USER_ENV_FILE from openbb_terminal.custom_prompt_toolkit import NestedCompleter from openbb_terminal.decorators import log_start_end from openbb_terminal.menu import session @@ -78,24 +79,20 @@ class FeatureFlagsController(BaseController): def call_retryload(self, _): """Process retryload command""" obbff.RETRY_WITH_LOAD = not obbff.RETRY_WITH_LOAD - set_key( - obbff.USER_ENV_FILE, "OPENBB_RETRY_WITH_LOAD", str(obbff.RETRY_WITH_LOAD) - ) + set_key(USER_ENV_FILE, "OPENBB_RETRY_WITH_LOAD", str(obbff.RETRY_WITH_LOAD)) @log_start_end(log=logger) def call_tab(self, _): """Process tab command""" obbff.USE_TABULATE_DF = not obbff.USE_TABULATE_DF - set_key( - obbff.USER_ENV_FILE, "OPENBB_USE_TABULATE_DF", str(obbff.USE_TABULATE_DF) - ) + set_key(USER_ENV_FILE, "OPENBB_USE_TABULATE_DF", str(obbff.USE_TABULATE_DF)) @log_start_end(log=logger) def call_cls(self, _): """Process cls command""" obbff.USE_CLEAR_AFTER_CMD = not obbff.USE_CLEAR_AFTER_CMD set_key( - obbff.USER_ENV_FILE, + USER_ENV_FILE, "OPENBB_USE_CLEAR_AFTER_CMD", str(obbff.USE_CLEAR_AFTER_CMD), ) @@ -104,14 +101,14 @@ class FeatureFlagsController(BaseController): def call_color(self, _): """Process color command""" obbff.USE_COLOR = not obbff.USE_COLOR - set_key(obbff.USER_ENV_FILE, "OPENBB_USE_COLOR", str(obbff.USE_COLOR)) + set_key(USER_ENV_FILE, "OPENBB_USE_COLOR", str(obbff.USE_COLOR)) @log_start_end(log=logger) def call_promptkit(self, _): """Process promptkit command""" obbff.USE_PROMPT_TOOLKIT = not obbff.USE_PROMPT_TOOLKIT set_key( - obbff.USER_ENV_FILE, + USER_ENV_FILE, "OPENBB_USE_PROMPT_TOOLKIT", str(obbff.USE_PROMPT_TOOLKIT), ) @@ -121,7 +118,7 @@ class FeatureFlagsController(BaseController): """Process thoughts command""" obbff.ENABLE_THOUGHTS_DAY = not obbff.ENABLE_THOUGHTS_DAY set_key( - obbff.USER_ENV_FILE, + USER_ENV_FILE, "OPENBB_ENABLE_THOUGHTS_DAY", str(obbff.ENABLE_THOUGHTS_DAY), ) @@ -131,7 +128,7 @@ class FeatureFlagsController(BaseController): """Process reporthtml command""" obbff.OPEN_REPORT_AS_HTML = not obbff.OPEN_REPORT_AS_HTML set_key( - obbff.USER_ENV_FILE, + USER_ENV_FILE, "OPENBB_OPEN_REPORT_AS_HTML", str(obbff.OPEN_REPORT_AS_HTML), ) @@ -141,7 +138,7 @@ class FeatureFlagsController(BaseController): """Process exithelp command""" obbff.ENABLE_EXIT_AUTO_HELP = not obbff.ENABLE_EXIT_AUTO_HELP set_key( - obbff.USER_ENV_FILE, + USER_ENV_FILE, "OPENBB_ENABLE_EXIT_AUTO_HELP", str(obbff.ENABLE_EXIT_AUTO_HELP), ) @@ -151,7 +148,7 @@ class FeatureFlagsController(BaseController): """Process rcontext command""" obbff.REMEMBER_CONTEXTS = not obbff.REMEMBER_CONTEXTS set_key( - obbff.USER_ENV_FILE, + USER_ENV_FILE, "OPENBB_REMEMBER_CONTEXTS", str(obbff.REMEMBER_CONTEXTS), ) @@ -160,20 +157,20 @@ class FeatureFlagsController(BaseController): def call_dt(self, _): """Process dt command""" obbff.USE_DATETIME = not obbff.USE_DATETIME - set_key(obbff.USER_ENV_FILE, "OPENBB_USE_DATETIME", str(obbff.USE_DATETIME)) + set_key(USER_ENV_FILE, "OPENBB_USE_DATETIME", str(obbff.USE_DATETIME)) @log_start_end(log=logger) def call_rich(self, _): """Process rich command""" obbff.ENABLE_RICH = not obbff.ENABLE_RICH - set_key(obbff.USER_ENV_FILE, "OPENBB_ENABLE_RICH", str(obbff.ENABLE_RICH)) + set_key(USER_ENV_FILE, "OPENBB_ENABLE_RICH", str(obbff.ENABLE_RICH)) @log_start_end(log=logger) def call_richpanel(self, _): """Process richpanel command""" obbff.ENABLE_RICH_PANEL = not obbff.ENABLE_RICH_PANEL set_key( - obbff.USER_ENV_FILE, + USER_ENV_FILE, "OPENBB_ENABLE_RICH_PANEL", str(obbff.ENABLE_RICH_PANEL), ) @@ -182,20 +179,20 @@ class FeatureFlagsController(BaseController): def call_ion(self, _): """Process ion command""" obbff.USE_ION = not obbff.USE_ION - set_key(obbff.USER_ENV_FILE, "OPENBB_USE_ION", str(obbff.USE_ION)) + set_key(USER_ENV_FILE, "OPENBB_USE_ION", str(obbff.USE_ION)) @log_start_end(log=logger) def call_watermark(self, _): """Process watermark command""" obbff.USE_WATERMARK = not obbff.USE_WATERMARK - set_key(obbff.USER_ENV_FILE, "OPENBB_USE_WATERMARK", str(obbff.USE_WATERMARK)) + set_key(USER_ENV_FILE, "OPENBB_USE_WATERMARK", str(obbff.USE_WATERMARK)) @log_start_end(log=logger) def call_cmdloc(self, _): """Process cmdloc command""" obbff.USE_CMD_LOCATION_FIGURE = not obbff.USE_CMD_LOCATION_FIGURE set_key( - obbff.USER_ENV_FILE, + USER_ENV_FILE, "OPENBB_USE_CMD_LOCATION_FIGURE", str(obbff.USE_CMD_LOCATION_FIGURE), ) @@ -207,7 +204,7 @@ class FeatureFlagsController(BaseController): console.print("Will take effect when running terminal next.") obbff.TOOLBAR_HINT = not obbff.TOOLBAR_HINT set_key( - obbff.USER_ENV_FILE, + USER_ENV_FILE, "OPENBB_TOOLBAR_HINT", str(obbff.TOOLBAR_HINT), ) diff --git a/openbb_terminal/feature_flags.py b/openbb_terminal/feature_flags.py index 3e2eec9f24a..964bd09b9c9 100644 --- a/openbb_terminal/feature_flags.py +++ b/openbb_terminal/feature_flags.py @@ -3,27 +3,25 @@ import os import os.path # IMPORTATION THIRDPARTY -from dotenv import load_dotenv import i18n # IMPORTATION INTERNAL from openbb_terminal.core.config.paths import ( MISCELLANEOUS_DIRECTORY, - PACKAGE_ENV_FILE, - REPOSITORY_ENV_FILE, USER_DATA_SOURCES_DEFAULT_FILE, - USER_ENV_FILE, + load_dotenv_with_priority, ) from openbb_terminal.core.config import paths_helper -from openbb_terminal.base_helpers import load_env_vars, strtobool +from openbb_terminal.base_helpers import ( + load_env_vars, + strtobool, +) paths_helper.init_userdata() # pylint: disable=no-member,c-extension-no-member -load_dotenv(USER_ENV_FILE) -load_dotenv(REPOSITORY_ENV_FILE, override=True) -load_dotenv(PACKAGE_ENV_FILE, override=True) +load_dotenv_with_priority() try: __import__("git") diff --git a/openbb_terminal/helper_funcs.py b/openbb_terminal/helper_funcs.py index 42bfdaa9893..031eaa74442 100644 --- a/openbb_terminal/helper_funcs.py +++ b/openbb_terminal/helper_funcs.py @@ -45,6 +45,7 @@ from openbb_terminal.core.config.paths import ( HOME_DIRECTORY, USER_ENV_FILE, USER_EXPORTS_DIRECTORY, + load_dotenv_with_priority, ) from openbb_terminal.core.config import paths @@ -1121,7 +1122,7 @@ def get_flair() -> str: def set_default_timezone() -> None: """Set a default (America/New_York) timezone if one doesn't exist.""" - dotenv.load_dotenv(USER_ENV_FILE) + load_dotenv_with_priority() user_tz = os.getenv("OPENBB_TIMEZONE") if not user_tz: dotenv.set_key(USER_ENV_FILE, "OPENBB_TIMEZONE", "America/New_York") @@ -1151,7 +1152,7 @@ def get_user_timezone() -> str: str user timezone based on .env file """ - dotenv.load_dotenv(USER_ENV_FILE, override=True) + load_dotenv_with_priority() user_tz = os.getenv("OPENBB_TIMEZONE") if user_tz: return user_tz diff --git a/openbb_terminal/settings_controller.py b/openbb_terminal/settings_controller.py index 29b898790b1..1d1b460f278 100644 --- a/openbb_terminal/settings_controller.py +++ b/openbb_terminal/settings_controller.py @@ -153,7 +153,7 @@ class SettingsController(BaseController): def call_dt(self, _): """Process dt command""" obbff.USE_DATETIME = not obbff.USE_DATETIME - set_key(obbff.USER_ENV_FILE, "OPENBB_USE_DATETIME", str(obbff.USE_DATETIME)) + set_key(USER_ENV_FILE, "OPENBB_USE_DATETIME", str(obbff.USE_DATETIME)) @log_start_end(log=logger) def call_source(self, other_args: List[str]): @@ -189,7 +189,7 @@ class SettingsController(BaseController): console.print(e) obbff.PREFERRED_DATA_SOURCE_FILE = ns_parser.value set_key( - obbff.USER_ENV_FILE, + USER_ENV_FILE, "OPENBB_PREFERRED_DATA_SOURCE_FILE", str(ns_parser.value), ) @@ -199,7 +199,7 @@ class SettingsController(BaseController): """Process autoscaling command""" obbff.USE_PLOT_AUTOSCALING = not obbff.USE_PLOT_AUTOSCALING set_key( - obbff.USER_ENV_FILE, + USER_ENV_FILE, "OPENBB_USE_PLOT_AUTOSCALING", str(obbff.USE_PLOT_AUTOSCALING), ) @@ -225,7 +225,7 @@ class SettingsController(BaseController): other_args.insert(0, "-v") ns_parser = self.parse_simple_args(parser, other_args) if ns_parser and ns_parser.value: - set_key(obbff.USER_ENV_FILE, "OPENBB_PLOT_DPI", str(ns_parser.value)) + set_key(USER_ENV_FILE, "OPENBB_PLOT_DPI", str(ns_parser.value)) cfg_plot.PLOT_DPI = ns_parser.value @log_start_end(log=logger) @@ -249,7 +249,7 @@ class SettingsController(BaseController): other_args.insert(0, "-v") ns_parser = self.parse_simple_args(parser, other_args) if ns_parser: - set_key(obbff.USER_ENV_FILE, "OPENBB_PLOT_HEIGHT", str(ns_parser.value)) + set_key(USER_ENV_FILE, "OPENBB_PLOT_HEIGHT", str(ns_parser.value)) cfg_plot.PLOT_HEIGHT = ns_parser.value @log_start_end(log=logger) @@ -273,7 +273,7 @@ class SettingsController(BaseController): other_args.insert(0, "-v") ns_parser = self.parse_simple_args(parser, other_args) if ns_parser: - set_key(obbff.USER_ENV_FILE, "OPENBB_PLOT_WIDTH", str(ns_parser.value)) + set_key(USER_ENV_FILE, "OPENBB_PLOT_WIDTH", str(ns_parser.value)) cfg_plot.PLOT_WIDTH = ns_parser.value @log_start_end(log=logger) @@ -297,7 +297,7 @@ class SettingsController(BaseController): ns_parser = self.parse_simple_args(parser, other_args) if ns_parser: set_key( - obbff.USER_ENV_FILE, + USER_ENV_FILE, "OPENBB_PLOT_HEIGHT_PERCENTAGE", str(ns_parser.value), ) @@ -324,7 +324,7 @@ class SettingsController(BaseController): ns_parser = self.parse_simple_args(parser, other_args) if ns_parser: set_key( - obbff.USER_ENV_FILE, + USER_ENV_FILE, "OPENBB_PLOT_WIDTH_PERCENTAGE", str(ns_parser.value), ) @@ -350,7 +350,7 @@ class SettingsController(BaseController): other_args.insert(0, "-v") ns_parser = self.parse_simple_args(parser, other_args) if ns_parser: - set_key(obbff.USER_ENV_FILE, "OPENBB_MONITOR", str(ns_parser.value)) + set_key(USER_ENV_FILE, "OPENBB_MONITOR", str(ns_parser.value)) cfg_plot.MONITOR = ns_parser.value @log_start_end(log=logger) @@ -373,7 +373,7 @@ class SettingsController(BaseController): other_args.insert(0, "-v") ns_parser = self.parse_simple_args(parser, other_args) if ns_parser: - set_key(obbff.USER_ENV_FILE, "OPENBB_BACKEND", str(ns_parser.value)) + set_key(USER_ENV_FILE, "OPENBB_BACKEND", str(ns_parser.value)) if ns_parser.value == "None": cfg_plot.BACKEND = None # type: ignore else: @@ -402,9 +402,7 @@ class SettingsController(BaseController): ns_parser = self.parse_simple_args(parser, other_args) if ns_parser: if ns_parser.value: - set_key( - obbff.USER_ENV_FILE, "OPENBB_USE_LANGUAGE", str(ns_parser.value) - ) + set_key(USER_ENV_FILE, "OPENBB_USE_LANGUAGE", str(ns_parser.value)) obbff.USE_LANGUAGE = ns_parser.value else: console.print( @@ -462,7 +460,7 @@ class SettingsController(BaseController): ns_parser.emoji = "" else: ns_parser.emoji = " ".join(ns_parser.emoji) - set_key(obbff.USER_ENV_FILE, "OPENBB_USE_FLAIR", str(ns_parser.emoji)) + set_key(USER_ENV_FILE, "OPENBB_USE_FLAIR", str(ns_parser.emoji)) obbff.USE_FLAIR = ns_parser.emoji @log_start_end(log=logger) @@ -547,7 +545,7 @@ class SettingsController(BaseController): else: # Do not update userdata_folder path since we will keep the same as before console.print( - "[yellow]User data to keep being saved in" + "[yellow]User data to keep being saved in " + f"the selected folder: {str(USER_DATA_DIRECTORY)}[/yellow]" ) success_userdata = True diff --git a/openbb_terminal/terminal_controller.py b/openbb_terminal/terminal_controller.py index ce9f2dfcc93..75e15dc479f 100644 --- a/openbb_terminal/terminal_controller.py +++ b/openbb_terminal/terminal_controller.py @@ -14,7 +14,6 @@ import webbrowser from typing import List, Dict, Optional import contextlib -import dotenv import certifi from rich import panel @@ -29,11 +28,11 @@ from openbb_terminal.terminal_helper import is_packaged_application from openbb_terminal.core.config.paths import ( HOME_DIRECTORY, MISCELLANEOUS_DIRECTORY, - REPOSITORY_ENV_FILE, REPOSITORY_DIRECTORY, USER_DATA_DIRECTORY, USER_ENV_FILE, USER_ROUTINES_DIRECTORY, + load_dotenv_with_priority, ) from openbb_terminal.helper_funcs import ( @@ -838,8 +837,7 @@ def terminal(jobs_cmds: List[str] = None, test_mode=False): t_controller.print_help() check_for_updates() - dotenv.load_dotenv(USER_ENV_FILE) - dotenv.load_dotenv(REPOSITORY_ENV_FILE, override=True) + load_dotenv_with_priority() while ret_code: if obbff.ENABLE_QUICK_EXIT: