feat: Add --gradio-ui option to launch.py#90
Conversation
This commit introduces a new `--gradio-ui` command-line option to the main `launch.py` script. This option allows you to directly launch the Gradio-based scientific UI (`server/python_backend/gradio_app.py`) for testing, AI model interaction, and UI component exploration. Changes include: - Added `--gradio-ui` argument to `launch.py`. - Implemented logic in `run_application` within `launch.py` to execute `gradio_app.py` when `--gradio-ui` is specified. - Modified `server/python_backend/gradio_app.py` to accept `--host`, `--port`, `--debug`, and `--share` command-line arguments, allowing its server parameters to be controlled by `launch.py`. - Updated `README.md` to document the new `--gradio-ui` feature and its usage. This addresses the issue where the local non-Docker Python-only scientific deployment using Gradio had "disappeared" by providing a clear, integrated way to launch it.
Reviewer's GuideThis PR adds a new Sequence diagram for launching Gradio UI via --gradio-ui flagsequenceDiagram
actor User
participant LaunchPy as launch.py
participant GradioApp as gradio_app.py
User->>LaunchPy: Run with --gradio-ui [and options]
LaunchPy->>LaunchPy: Parse arguments
LaunchPy->>LaunchPy: Detect --gradio-ui flag
LaunchPy->>GradioApp: Spawn subprocess with --host, --port, --debug, --share
GradioApp->>GradioApp: Parse CLI arguments
GradioApp->>GradioApp: Launch Gradio UI with specified options
GradioApp-->>User: Gradio UI available at host:port
Note over GradioApp,User: If --share, Gradio provides .gradio.live URL
User->>LaunchPy: Ctrl+C to stop
LaunchPy->>GradioApp: Terminate subprocess
GradioApp-->>LaunchPy: Exit
LaunchPy-->>User: Exit
Class diagram for argument parsing and Gradio UI launchclassDiagram
class LaunchArguments {
+bool gradio_ui
+str host
+int port
+bool debug
+bool share
}
class LaunchPy {
+run_application(args)
+parse_arguments()
}
class GradioApp {
+main()
+parse_args()
+iface.launch(server_name, server_port, debug, share)
}
LaunchPy --|> LaunchArguments : uses
LaunchPy ..> GradioApp : spawns subprocess with args
GradioApp --|> LaunchArguments : parses
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
|
Caution Review failedThe pull request is closed. WalkthroughA new launcher flag ( Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant Launcher (launch.py)
participant Gradio Script (gradio_app.py)
participant Gradio UI
User->>Launcher (launch.py): Run with --gradio-ui [and options]
Launcher (launch.py)->>Gradio Script (gradio_app.py): Start subprocess with CLI args
Gradio Script (gradio_app.py)->>Gradio UI: Launch with specified host/port/debug/share
Gradio UI-->>User: Exposes web interface at configured URL
Possibly related PRs
Poem
📜 Recent review detailsConfiguration used: CodeRabbit UI 📒 Files selected for processing (3)
✨ Finishing Touches
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Hey @MasumRab - I've reviewed your changes - here's some feedback:
Blocking issues:
- Detected subprocess function 'Popen' without a static string. If this data can be controlled by a malicious actor, it may be an instance of command injection. Audit the use of this call to ensure it is not controllable by an external resource. You may consider using 'shlex.escape()'. (link)
General comments:
- Extract the Gradio launch logic into a separate helper (e.g. launch_gradio_ui) instead of inlining it inside run_application to improve readability and maintainability.
- Introduce dedicated CLI flags for Gradio UI (e.g. --gradio-host/--gradio-port) rather than reusing --host/--port to avoid collisions with the main backend settings.
- Use subprocess.run for synchronous execution to simplify exit‐code handling and double‐check that the global
processeslist is properly initialized and scoped.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- Extract the Gradio launch logic into a separate helper (e.g. launch_gradio_ui) instead of inlining it inside run_application to improve readability and maintainability.
- Introduce dedicated CLI flags for Gradio UI (e.g. --gradio-host/--gradio-port) rather than reusing --host/--port to avoid collisions with the main backend settings.
- Use subprocess.run for synchronous execution to simplify exit‐code handling and double‐check that the global `processes` list is properly initialized and scoped.
## Individual Comments
### Comment 1
<location> `launch.py:841` </location>
<code_context>
+ # so passing args.host to gradio_app.py correctly handles this.
+
+ env = os.environ.copy()
+ env["PYTHONPATH"] = str(ROOT_DIR)
+ # Add any other necessary environment variables if gradio_app.py needs them.
+ # For example, if Gradio needs to know the API URL for some features:
</code_context>
<issue_to_address>
Overwriting PYTHONPATH may unintentionally remove existing entries.
Prepend or append ROOT_DIR to the existing PYTHONPATH to avoid breaking setups that rely on its current value.
</issue_to_address>
### Comment 2
<location> `launch.py:822` </location>
<code_context>
logger.warning(f"Specified env file {args.env_file} not found at {env_file_path}")
- if args.api_only:
+ if args.gradio_ui:
+ logger.info("Running Gradio UI for scientific/testing purposes...")
+ gradio_script_path = ROOT_DIR / "server" / "python_backend" / "gradio_app.py"
</code_context>
<issue_to_address>
Consider extracting the Gradio UI launch logic into a separate helper function to keep run_application() concise.
```suggestion
# Extract the Gradio‐UI block into its own helper to keep run_application() shallow
# e.g. somewhere near start_backend()/start_frontend():
def start_gradio_ui(args, python_executable):
gradio_script = ROOT_DIR / "server" / "python_backend" / "gradio_app.py"
if not gradio_script.exists():
logger.error(f"Gradio script not found at: {gradio_script}")
return 1
cmd = [
python_executable,
str(gradio_script),
"--host", args.host,
"--port", str(args.port),
]
if args.share:
cmd.append("--share")
if args.debug:
cmd.append("--debug")
env = os.environ.copy()
env["PYTHONPATH"] = str(ROOT_DIR)
# add more env vars here if needed, e.g. API_URL
try:
logger.info(f"Running Gradio UI command: {' '.join(cmd)}")
proc = subprocess.Popen(cmd, env=env)
logger.info(f"Gradio UI started (PID {proc.pid}). Access at http://{args.host or '127.0.0.1'}:{args.port}")
proc.wait()
if proc.returncode != 0:
logger.warning(f"Gradio exited with code {proc.returncode}")
return 0
except FileNotFoundError:
logger.error("Python executable or Gradio not found. Install gradio in your env.")
return 1
except Exception as e:
logger.error(f"Failed to start Gradio UI: {e}")
return 1
# Then simplify run_application():
...
if args.gradio_ui:
return start_gradio_ui(args, python_executable)
elif args.api_only:
...
```
</issue_to_address>
## Security Issues
### Issue 1
<location> `launch.py:848` </location>
<issue_to_address>
**security (dangerous-subprocess-use-audit):** Detected subprocess function 'Popen' without a static string. If this data can be controlled by a malicious actor, it may be an instance of command injection. Audit the use of this call to ensure it is not controllable by an external resource. You may consider using 'shlex.escape()'.
*Source: opengrep*
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
| # so passing args.host to gradio_app.py correctly handles this. | ||
|
|
||
| env = os.environ.copy() | ||
| env["PYTHONPATH"] = str(ROOT_DIR) |
There was a problem hiding this comment.
issue (bug_risk): Overwriting PYTHONPATH may unintentionally remove existing entries.
Prepend or append ROOT_DIR to the existing PYTHONPATH to avoid breaking setups that rely on its current value.
| logger.warning(f"Specified env file {args.env_file} not found at {env_file_path}") | ||
|
|
||
| if args.api_only: | ||
| if args.gradio_ui: |
There was a problem hiding this comment.
issue (complexity): Consider extracting the Gradio UI launch logic into a separate helper function to keep run_application() concise.
| if args.gradio_ui: | |
| # Extract the Gradio‐UI block into its own helper to keep run_application() shallow | |
| # e.g. somewhere near start_backend()/start_frontend(): | |
| def start_gradio_ui(args, python_executable): | |
| gradio_script = ROOT_DIR / "server" / "python_backend" / "gradio_app.py" | |
| if not gradio_script.exists(): | |
| logger.error(f"Gradio script not found at: {gradio_script}") | |
| return 1 | |
| cmd = [ | |
| python_executable, | |
| str(gradio_script), | |
| "--host", args.host, | |
| "--port", str(args.port), | |
| ] | |
| if args.share: | |
| cmd.append("--share") | |
| if args.debug: | |
| cmd.append("--debug") | |
| env = os.environ.copy() | |
| env["PYTHONPATH"] = str(ROOT_DIR) | |
| # add more env vars here if needed, e.g. API_URL | |
| try: | |
| logger.info(f"Running Gradio UI command: {' '.join(cmd)}") | |
| proc = subprocess.Popen(cmd, env=env) | |
| logger.info(f"Gradio UI started (PID {proc.pid}). Access at http://{args.host or '127.0.0.1'}:{args.port}") | |
| proc.wait() | |
| if proc.returncode != 0: | |
| logger.warning(f"Gradio exited with code {proc.returncode}") | |
| return 0 | |
| except FileNotFoundError: | |
| logger.error("Python executable or Gradio not found. Install gradio in your env.") | |
| return 1 | |
| except Exception as e: | |
| logger.error(f"Failed to start Gradio UI: {e}") | |
| return 1 | |
| # Then simplify run_application(): | |
| ... | |
| if args.gradio_ui: | |
| return start_gradio_ui(args, python_executable) | |
| elif args.api_only: | |
| ... |
|
|
||
| try: | ||
| logger.info(f"Running Gradio UI command: {' '.join(cmd)}") | ||
| gradio_process = subprocess.Popen(cmd, env=env) |
There was a problem hiding this comment.
security (dangerous-subprocess-use-audit): Detected subprocess function 'Popen' without a static string. If this data can be controlled by a malicious actor, it may be an instance of command injection. Audit the use of this call to ensure it is not controllable by an external resource. You may consider using 'shlex.escape()'.
Source: opengrep
feat: Add --gradio-ui option to launch.py
feat: Add --gradio-ui option to launch.py
This commit introduces a new
--gradio-uicommand-line option to the mainlaunch.pyscript. This option allows you to directly launch the Gradio-based scientific UI (server/python_backend/gradio_app.py) for testing, AI model interaction, and UI component exploration.Changes include:
--gradio-uiargument tolaunch.py.run_applicationwithinlaunch.pyto executegradio_app.pywhen--gradio-uiis specified.server/python_backend/gradio_app.pyto accept--host,--port,--debug, and--sharecommand-line arguments, allowing its server parameters to be controlled bylaunch.py.README.mdto document the new--gradio-uifeature and its usage.This addresses the issue where the local non-Docker Python-only scientific deployment using Gradio had "disappeared" by providing a clear, integrated way to launch it.
Summary by Sourcery
Add a new --gradio-ui mode to the launcher that starts the standalone Gradio-based scientific UI with configurable server options and document its usage in the README
New Features:
Enhancements:
Documentation:
Summary by CodeRabbit
New Features
Documentation