Edwin Salguero
feat(ui): add robust multi-interface UI system (Streamlit, Dash, Jupyter, WebSocket) with launcher, docs, and integration tests [skip ci]
9f44dc9
#!/usr/bin/env python3 | |
""" | |
UI Launcher for Algorithmic Trading System | |
Provides multiple UI options: | |
- Streamlit: Quick prototyping and data science workflows | |
- Dash: Enterprise-grade interactive dashboards | |
- Jupyter: Notebook-based interfaces | |
- WebSocket: Real-time trading interfaces | |
""" | |
import argparse | |
import sys | |
import os | |
import subprocess | |
import webbrowser | |
import time | |
import threading | |
from typing import Optional | |
def check_dependencies(): | |
"""Check if required UI dependencies are installed""" | |
required_packages = [ | |
'streamlit', | |
'dash', | |
'plotly', | |
'ipywidgets' | |
] | |
missing_packages = [] | |
for package in required_packages: | |
try: | |
__import__(package) | |
except ImportError: | |
missing_packages.append(package) | |
if missing_packages: | |
print(f"β Missing required packages: {', '.join(missing_packages)}") | |
print("Please install them using: pip install -r requirements.txt") | |
return False | |
return True | |
def launch_streamlit(): | |
"""Launch Streamlit application""" | |
print("π Launching Streamlit UI...") | |
# Create streamlit app file if it doesn't exist | |
streamlit_app_path = "ui/streamlit_app.py" | |
if not os.path.exists(streamlit_app_path): | |
print(f"β Streamlit app not found at {streamlit_app_path}") | |
return False | |
try: | |
# Launch Streamlit | |
cmd = [ | |
sys.executable, "-m", "streamlit", "run", | |
streamlit_app_path, | |
"--server.port", "8501", | |
"--server.address", "0.0.0.0", | |
"--browser.gatherUsageStats", "false" | |
] | |
print(f"Running: {' '.join(cmd)}") | |
subprocess.run(cmd) | |
return True | |
except Exception as e: | |
print(f"β Error launching Streamlit: {e}") | |
return False | |
def launch_dash(): | |
"""Launch Dash application""" | |
print("π Launching Dash UI...") | |
# Create dash app file if it doesn't exist | |
dash_app_path = "ui/dash_app.py" | |
if not os.path.exists(dash_app_path): | |
print(f"β Dash app not found at {dash_app_path}") | |
return False | |
try: | |
# Launch Dash | |
cmd = [ | |
sys.executable, dash_app_path | |
] | |
print(f"Running: {' '.join(cmd)}") | |
subprocess.run(cmd) | |
return True | |
except Exception as e: | |
print(f"β Error launching Dash: {e}") | |
return False | |
def launch_jupyter(): | |
"""Launch Jupyter interface""" | |
print("π Launching Jupyter UI...") | |
try: | |
# Launch Jupyter Lab | |
cmd = [ | |
sys.executable, "-m", "jupyter", "lab", | |
"--port", "8888", | |
"--ip", "0.0.0.0", | |
"--no-browser" | |
] | |
print(f"Running: {' '.join(cmd)}") | |
subprocess.run(cmd) | |
return True | |
except Exception as e: | |
print(f"β Error launching Jupyter: {e}") | |
return False | |
def launch_websocket_server(): | |
"""Launch WebSocket server""" | |
print("π Launching WebSocket Server...") | |
try: | |
from ui.websocket_server import create_websocket_server | |
server = create_websocket_server(host="0.0.0.0", port=8765) | |
server_thread = server.run_server() | |
print("β WebSocket server started on ws://0.0.0.0:8765") | |
print("Press Ctrl+C to stop the server") | |
# Keep the main thread alive | |
try: | |
while True: | |
time.sleep(1) | |
except KeyboardInterrupt: | |
print("\nπ Stopping WebSocket server...") | |
return True | |
except Exception as e: | |
print(f"β Error launching WebSocket server: {e}") | |
return False | |
def open_browser(url: str, delay: int = 2): | |
"""Open browser after delay""" | |
def open_url(): | |
time.sleep(delay) | |
try: | |
webbrowser.open(url) | |
print(f"π Opened browser to: {url}") | |
except Exception as e: | |
print(f"β οΈ Could not open browser: {e}") | |
browser_thread = threading.Thread(target=open_url) | |
browser_thread.daemon = True | |
browser_thread.start() | |
def main(): | |
"""Main launcher function""" | |
parser = argparse.ArgumentParser( | |
description="UI Launcher for Algorithmic Trading System", | |
formatter_class=argparse.RawDescriptionHelpFormatter, | |
epilog=""" | |
Examples: | |
python ui_launcher.py streamlit # Launch Streamlit UI | |
python ui_launcher.py dash # Launch Dash UI | |
python ui_launcher.py jupyter # Launch Jupyter Lab | |
python ui_launcher.py websocket # Launch WebSocket server | |
python ui_launcher.py all # Launch all UIs | |
""" | |
) | |
parser.add_argument( | |
"ui_type", | |
choices=["streamlit", "dash", "jupyter", "websocket", "all"], | |
help="Type of UI to launch" | |
) | |
parser.add_argument( | |
"--no-browser", | |
action="store_true", | |
help="Don't automatically open browser" | |
) | |
parser.add_argument( | |
"--port", | |
type=int, | |
help="Custom port number (overrides default)" | |
) | |
args = parser.parse_args() | |
# Check dependencies | |
if not check_dependencies(): | |
sys.exit(1) | |
print("π€ Algorithmic Trading System - UI Launcher") | |
print("=" * 50) | |
success = False | |
if args.ui_type == "streamlit": | |
success = launch_streamlit() | |
if success and not args.no_browser: | |
open_browser("http://localhost:8501") | |
elif args.ui_type == "dash": | |
success = launch_dash() | |
if success and not args.no_browser: | |
open_browser("http://localhost:8050") | |
elif args.ui_type == "jupyter": | |
success = launch_jupyter() | |
if success and not args.no_browser: | |
open_browser("http://localhost:8888") | |
elif args.ui_type == "websocket": | |
success = launch_websocket_server() | |
elif args.ui_type == "all": | |
print("π Launching all UI interfaces...") | |
# Launch WebSocket server in background | |
websocket_thread = threading.Thread(target=launch_websocket_server) | |
websocket_thread.daemon = True | |
websocket_thread.start() | |
# Launch Streamlit | |
streamlit_thread = threading.Thread(target=launch_streamlit) | |
streamlit_thread.daemon = True | |
streamlit_thread.start() | |
# Launch Dash | |
dash_thread = threading.Thread(target=launch_dash) | |
dash_thread.daemon = True | |
dash_thread.start() | |
# Launch Jupyter | |
jupyter_thread = threading.Thread(target=launch_jupyter) | |
jupyter_thread.daemon = True | |
jupyter_thread.start() | |
if not args.no_browser: | |
open_browser("http://localhost:8501", 3) # Streamlit | |
open_browser("http://localhost:8050", 5) # Dash | |
open_browser("http://localhost:8888", 7) # Jupyter | |
print("β All UIs launched!") | |
print("π Streamlit: http://localhost:8501") | |
print("π Dash: http://localhost:8050") | |
print("π Jupyter: http://localhost:8888") | |
print("π WebSocket: ws://localhost:8765") | |
# Keep main thread alive | |
try: | |
while True: | |
time.sleep(1) | |
except KeyboardInterrupt: | |
print("\nπ Stopping all UIs...") | |
success = True | |
if success: | |
print("β UI launched successfully!") | |
else: | |
print("β Failed to launch UI") | |
sys.exit(1) | |
if __name__ == "__main__": | |
main() |