From 27961e5282970f7eacbcec1a9a3be8b860401017 Mon Sep 17 00:00:00 2001 From: komuw Date: Tue, 29 Apr 2025 19:16:37 +0300 Subject: [PATCH 1/4] - Allow users to set config values through environment variables. - Fixes: https://github.com/Tautulli/Tautulli/issues/2309 --- plexpy/config.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/plexpy/config.py b/plexpy/config.py index 3e9862ff..1e45a234 100644 --- a/plexpy/config.py +++ b/plexpy/config.py @@ -487,6 +487,11 @@ class Config(object): """ Cast any value in the config to the right type or use the default """ key, definition_type, section, ini_key, default = self._define(key) self.check_section(section) + my_val = self._from_env(key, definition_type) + if my_val: + self._config[section][ini_key] = my_val + return my_val + try: my_val = definition_type(self._config[section][ini_key]) except Exception: @@ -494,6 +499,15 @@ class Config(object): self._config[section][ini_key] = my_val return my_val + def _from_env(self, key, definition_type): + """ Get key from environment variables, if it exists """ + val = os.environ.get(key) + try: + if val: + return definition_type(val) + except Exception: + return None + def write(self): """ Make a copy of the stored config and write it to the configured file """ new_config = ConfigObj(encoding="UTF-8") From 4610bf37692d5c1629f9d3d90999f3db5d224b46 Mon Sep 17 00:00:00 2001 From: komuw Date: Sat, 10 May 2025 21:18:02 +0300 Subject: [PATCH 2/4] Prefix environment variables with `TAUTULLI_` For: https://github.com/Tautulli/Tautulli/issues/2309 --- plexpy/config.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plexpy/config.py b/plexpy/config.py index 1e45a234..04997c16 100644 --- a/plexpy/config.py +++ b/plexpy/config.py @@ -501,7 +501,8 @@ class Config(object): def _from_env(self, key, definition_type): """ Get key from environment variables, if it exists """ - val = os.environ.get(key) + env_key = "TAUTULLI_" + key + val = os.environ.get(env_key) try: if val: return definition_type(val) From 5ef991104943de32bfccfca36cc38b7705584911 Mon Sep 17 00:00:00 2001 From: JonnyWong16 <9099342+JonnyWong16@users.noreply.github.com> Date: Sat, 10 May 2025 18:36:36 -0700 Subject: [PATCH 3/4] Update handling Tautulli environment variables --- plexpy/config.py | 67 ++++++++++++++++++++++++++---------------------- 1 file changed, 37 insertions(+), 30 deletions(-) diff --git a/plexpy/config.py b/plexpy/config.py index 04997c16..db254886 100644 --- a/plexpy/config.py +++ b/plexpy/config.py @@ -479,35 +479,45 @@ class Config(object): """ Check if INI section exists, if not create it """ if section not in self._config: self._config[section] = {} - return True - else: - return False - def check_setting(self, key): - """ Cast any value in the config to the right type or use the default """ - key, definition_type, section, ini_key, default = self._define(key) + def check_setting(self, name): + """ Check if INI key exists, if not create it """ + key, definition_type, section, ini_key, default = self._define(name) self.check_section(section) - my_val = self._from_env(key, definition_type) - if my_val: - self._config[section][ini_key] = my_val - return my_val - - try: - my_val = definition_type(self._config[section][ini_key]) - except Exception: - my_val = definition_type(default) - self._config[section][ini_key] = my_val - return my_val - - def _from_env(self, key, definition_type): + value = self._config[section].get(ini_key, default) + self._config[section][ini_key] = self._cast_setting(definition_type, value, default) + + def get_setting(self, name): + """ Get the value of a setting, either from the config file or environment variable """ + key, definition_type, section, ini_key, default = self._define(name) + # Check if the key is in the environment variables + value = self._from_env(key) + if not value: + # If not, check if the key is in the config file + value = self._config[section].get(ini_key, default) + return self._cast_setting(definition_type, value, default) + + def set_setting(self, name, value): + """ Set the value of a setting in the config file """ + key, definition_type, section, ini_key, default = self._define(name) + # Check if the key is in the environment variables + env_value = self._from_env(key) + if not env_value: + # If not, set the value in the config file + self._config[section][ini_key] = self._cast_setting(definition_type, value, default) + return self._config[section][ini_key] + + def _from_env(self, key): """ Get key from environment variables, if it exists """ - env_key = "TAUTULLI_" + key - val = os.environ.get(env_key) + env_key = f"TAUTULLI_{key}" + return os.environ.get(env_key) + + def _cast_setting(self, definition_type, value, default=None): + """ Cast the value to the correct type, or use the default if it fails """ try: - if val: - return definition_type(val) + return definition_type(value) except Exception: - return None + return definition_type(default) def write(self): """ Make a copy of the stored config and write it to the configured file """ @@ -548,7 +558,7 @@ class Config(object): if not re.match(r'[A-Z0-9_]+$', name): return super(Config, self).__getattr__(name) else: - return self.check_setting(name) + return self.get_setting(name) def __setattr__(self, name, value): """ @@ -559,9 +569,7 @@ class Config(object): super(Config, self).__setattr__(name, value) return value else: - key, definition_type, section, ini_key, default = self._define(name) - self._config[section][ini_key] = definition_type(value) - return self._config[section][ini_key] + return self.set_setting(name, value) def __delattr__(self, name): """ @@ -578,8 +586,7 @@ class Config(object): Given a big bunch of key value pairs, apply them to the ini. """ for name, value in kwargs.items(): - key, definition_type, section, ini_key, default = self._define(name) - self._config[section][ini_key] = definition_type(value) + self.__setattr__(name.upper(), value) def _upgrade(self): """ From 136ef21a86fd57fd7857caeb5d74e86a6cc70f87 Mon Sep 17 00:00:00 2001 From: JonnyWong16 <9099342+JonnyWong16@users.noreply.github.com> Date: Sun, 11 May 2025 19:37:19 -0700 Subject: [PATCH 4/4] Add log message when environment variable not saved to config --- plexpy/config.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/plexpy/config.py b/plexpy/config.py index db254886..2c4fa8b4 100644 --- a/plexpy/config.py +++ b/plexpy/config.py @@ -502,10 +502,13 @@ class Config(object): key, definition_type, section, ini_key, default = self._define(name) # Check if the key is in the environment variables env_value = self._from_env(key) - if not env_value: - # If not, set the value in the config file - self._config[section][ini_key] = self._cast_setting(definition_type, value, default) - return self._config[section][ini_key] + if env_value: + logger.warn("Tautulli Config :: '%s' set by environment variable. Setting not saved to config.", key) + return + + # If not, set the value in the config file + self._config[section][ini_key] = self._cast_setting(definition_type, value, default) + return self._config[section][ini_key] def _from_env(self, key): """ Get key from environment variables, if it exists """