From 3d2f24d691ab8915546e8d1641cb3a368eabd2ce Mon Sep 17 00:00:00 2001 From: Josue Nina Date: Fri, 6 Feb 2026 01:40:29 -0500 Subject: [PATCH 1/4] Prevent duplicate token requests --- lean/models/json_module.py | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/lean/models/json_module.py b/lean/models/json_module.py index 7c5b2e55..c656cfc3 100644 --- a/lean/models/json_module.py +++ b/lean/models/json_module.py @@ -28,6 +28,8 @@ _logged_messages = set() +# Cache OAuth tokens to prevent duplicate API calls +_auth_cache = {} class JsonModule(ABC): """The JsonModule class is the base class extended for all json modules.""" @@ -235,17 +237,24 @@ def config_build(self, logger.debug(f"skipping configuration '{configuration._id}': no choices available.") continue elif isinstance(configuration, AuthConfiguration): - lean_config["project-id"] = self.get_project_id(lean_config["project-id"], - configuration.require_project_id) - logger.debug(f'project_id: {lean_config["project-id"]}') - auth_authorizations = get_authorization(container.api_client.auth0, self._display_name.lower(), - logger, lean_config["project-id"], no_browser=no_browser) - logger.debug(f'auth: {auth_authorizations}') - configuration._value = auth_authorizations.get_authorization_config_without_account() + # Create a unique cache key based on brokerage + project_id + cache_key = f"{self._display_name.lower()}_{lean_config.get('project-id', 0)}" + + if cache_key not in _auth_cache: + # Only get the token if it's not in the cache + lean_config["project-id"] = self.get_project_id(lean_config["project-id"], + configuration.require_project_id) + logger.debug(f'project_id: {lean_config["project-id"]}') + auth_authorizations = get_authorization(container.api_client.auth0, self._display_name.lower(), + logger, lean_config["project-id"], no_browser=no_browser) + logger.debug(f'auth: {auth_authorizations}') + _auth_cache[cache_key] = auth_authorizations + + configuration._value = _auth_cache[cache_key].get_authorization_config_without_account() for inner_config in self._lean_configs: if any(condition._dependent_config_id == configuration._id for condition in inner_config._filter._conditions): - api_account_ids = auth_authorizations.get_account_ids() + api_account_ids = _auth_cache[cache_key].get_account_ids() config_dash = inner_config._id.replace('-', '_') inner_config._choices = api_account_ids if user_provided_options and config_dash in user_provided_options: From a176811619b3d66e28a589c30f3a5da37320d40f Mon Sep 17 00:00:00 2001 From: Josue Nina Date: Fri, 6 Feb 2026 11:25:48 -0500 Subject: [PATCH 2/4] Solve review comments --- lean/models/json_module.py | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/lean/models/json_module.py b/lean/models/json_module.py index c656cfc3..33d80b46 100644 --- a/lean/models/json_module.py +++ b/lean/models/json_module.py @@ -28,9 +28,6 @@ _logged_messages = set() -# Cache OAuth tokens to prevent duplicate API calls -_auth_cache = {} - class JsonModule(ABC): """The JsonModule class is the base class extended for all json modules.""" @@ -240,7 +237,7 @@ def config_build(self, # Create a unique cache key based on brokerage + project_id cache_key = f"{self._display_name.lower()}_{lean_config.get('project-id', 0)}" - if cache_key not in _auth_cache: + if cache_key not in lean_config: # Only get the token if it's not in the cache lean_config["project-id"] = self.get_project_id(lean_config["project-id"], configuration.require_project_id) @@ -248,13 +245,14 @@ def config_build(self, auth_authorizations = get_authorization(container.api_client.auth0, self._display_name.lower(), logger, lean_config["project-id"], no_browser=no_browser) logger.debug(f'auth: {auth_authorizations}') - _auth_cache[cache_key] = auth_authorizations + lean_config[cache_key] = auth_authorizations - configuration._value = _auth_cache[cache_key].get_authorization_config_without_account() + cached_auth = lean_config[cache_key] + configuration._value = cached_auth.get_authorization_config_without_account() for inner_config in self._lean_configs: if any(condition._dependent_config_id == configuration._id for condition in inner_config._filter._conditions): - api_account_ids = _auth_cache[cache_key].get_account_ids() + api_account_ids = cached_auth.get_account_ids() config_dash = inner_config._id.replace('-', '_') inner_config._choices = api_account_ids if user_provided_options and config_dash in user_provided_options: From 91a4728d63be6c38e7756f9daefc33be7fbc8a11 Mon Sep 17 00:00:00 2001 From: Josue Nina Date: Fri, 6 Feb 2026 16:00:58 -0500 Subject: [PATCH 3/4] Cache only what is necessary --- lean/models/json_module.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/lean/models/json_module.py b/lean/models/json_module.py index 33d80b46..acaa70eb 100644 --- a/lean/models/json_module.py +++ b/lean/models/json_module.py @@ -245,14 +245,17 @@ def config_build(self, auth_authorizations = get_authorization(container.api_client.auth0, self._display_name.lower(), logger, lean_config["project-id"], no_browser=no_browser) logger.debug(f'auth: {auth_authorizations}') - lean_config[cache_key] = auth_authorizations + lean_config[cache_key] = { + "config": auth_authorizations.get_authorization_config_without_account(), + "account_ids": auth_authorizations.get_account_ids() + } cached_auth = lean_config[cache_key] - configuration._value = cached_auth.get_authorization_config_without_account() + configuration._value = cached_auth["config"] for inner_config in self._lean_configs: if any(condition._dependent_config_id == configuration._id for condition in inner_config._filter._conditions): - api_account_ids = cached_auth.get_account_ids() + api_account_ids = cached_auth["account_ids"] config_dash = inner_config._id.replace('-', '_') inner_config._choices = api_account_ids if user_provided_options and config_dash in user_provided_options: From 0068adce41c605218f6dc1ea314363dead5808be Mon Sep 17 00:00:00 2001 From: Josue Nina Date: Fri, 6 Feb 2026 16:07:23 -0500 Subject: [PATCH 4/4] Minor fix --- lean/models/json_module.py | 1 + 1 file changed, 1 insertion(+) diff --git a/lean/models/json_module.py b/lean/models/json_module.py index acaa70eb..73e9a027 100644 --- a/lean/models/json_module.py +++ b/lean/models/json_module.py @@ -28,6 +28,7 @@ _logged_messages = set() + class JsonModule(ABC): """The JsonModule class is the base class extended for all json modules."""