From 118f1c5c230350ad6a3e54541650914530d92198 Mon Sep 17 00:00:00 2001 From: 5ymb01 <5ymb01@users.noreply.github.com> Date: Mon, 2 Mar 2026 05:57:16 -0500 Subject: [PATCH 1/2] fix(api): use sys.executable for plugin action subprocess calls The execute_plugin_action endpoint hardcoded 'python3' when spawning plugin scripts via subprocess. This can fail if the system Python is named differently or if a virtualenv is active, since 'python3' may not point to the correct interpreter. Changes: - Replace 'python3' with sys.executable in the non-OAuth script execution branch (uses the same interpreter running the web service) - Remove redundant 'import sys' inside the oauth_flow conditional block (sys is already imported at module level; the local import shadows the top-level binding for the entire function scope, which would cause UnboundLocalError if sys were referenced in the else branch on Python 3.12+) Co-Authored-By: Claude Opus 4.6 --- web_interface/blueprints/api_v3.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/web_interface/blueprints/api_v3.py b/web_interface/blueprints/api_v3.py index c49afc246..9e27e4e9e 100644 --- a/web_interface/blueprints/api_v3.py +++ b/web_interface/blueprints/api_v3.py @@ -5251,7 +5251,6 @@ def execute_plugin_action(): # For OAuth flows, we might need to import the script as a module if action_def.get('oauth_flow'): # Import script as module to get auth URL - import sys import importlib.util spec = importlib.util.spec_from_file_location("plugin_action", script_file) @@ -5304,7 +5303,7 @@ def execute_plugin_action(): else: # Simple script execution result = subprocess.run( - ['python3', str(script_file)], + [sys.executable, str(script_file)], capture_output=True, text=True, timeout=60, From ad4a033019c1f4dfbac8ecc625ddbb710c5653e0 Mon Sep 17 00:00:00 2001 From: 5ymb01 <5ymb01@users.noreply.github.com> Date: Sun, 8 Mar 2026 15:30:01 -0400 Subject: [PATCH 2/2] fix(api): replace all remaining hardcoded python3 with sys.executable Fix 4 additional subprocess calls that still used 'python3' instead of sys.executable: parameterized action wrapper (line 5150), stdin-param wrapper (line 5211), no-param wrapper (line 5417), and OAuth auth script (line 5524). Ensures plugin actions work in virtualenvs and non-standard Python installations. Addresses CodeRabbit findings on PR #277. Co-Authored-By: 5ymb01 <5ymb01@users.noreply.github.com> Co-Authored-By: Claude Opus 4.6 --- web_interface/blueprints/api_v3.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/web_interface/blueprints/api_v3.py b/web_interface/blueprints/api_v3.py index 9e27e4e9e..7c9a8c45e 100644 --- a/web_interface/blueprints/api_v3.py +++ b/web_interface/blueprints/api_v3.py @@ -5147,7 +5147,7 @@ def execute_plugin_action(): try: result = subprocess.run( - ['python3', wrapper_path], + [sys.executable, wrapper_path], capture_output=True, text=True, timeout=120, @@ -5208,7 +5208,7 @@ def execute_plugin_action(): try: result = subprocess.run( - ['python3', wrapper_path], + [sys.executable, wrapper_path], capture_output=True, text=True, timeout=120, @@ -5414,7 +5414,7 @@ def authenticate_spotify(): try: result = subprocess.run( - ['python3', wrapper_path], + [sys.executable, wrapper_path], capture_output=True, text=True, timeout=120, @@ -5521,7 +5521,7 @@ def authenticate_ytm(): # Run the authentication script result = subprocess.run( - ['python3', str(auth_script)], + [sys.executable, str(auth_script)], capture_output=True, text=True, timeout=60,