| import os |
| import subprocess |
| import sys |
| import time |
| import webbrowser |
| import requests |
| import signal |
| import psutil |
|
|
| def main(): |
| """Run the Debluring Application by starting both API and Streamlit app""" |
| |
| os.chdir(os.path.dirname(os.path.abspath(__file__))) |
| |
| print("\n🚀 Starting Debluring Application...\n") |
| |
| |
| api_url = "http://localhost:8001" |
| streamlit_url = "http://localhost:8501" |
| |
| |
| def start_api_server(): |
| nonlocal api_process |
| |
| for proc in psutil.process_iter(['pid', 'name', 'cmdline']): |
| try: |
| if 'uvicorn' in str(proc.info['cmdline']).lower() and '8001' in str(proc.info['cmdline']): |
| print(f"Killing existing uvicorn process (PID: {proc.info['pid']})") |
| psutil.Process(proc.info['pid']).kill() |
| except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess): |
| pass |
| |
| print("Starting API server...") |
| return subprocess.Popen( |
| [sys.executable, "api.py"], |
| stdout=subprocess.PIPE, |
| stderr=subprocess.PIPE, |
| bufsize=1, |
| universal_newlines=True |
| ) |
| |
| |
| def check_api_health(timeout=2): |
| try: |
| response = requests.get(f"{api_url}/status", timeout=timeout) |
| return response.status_code == 200 |
| except: |
| return False |
| |
| |
| api_process = start_api_server() |
| |
| |
| print("Waiting for API to start", end="") |
| api_ready = False |
| for _ in range(15): |
| if check_api_health(): |
| api_ready = True |
| print("\n✅ API server is running") |
| break |
| print(".", end="", flush=True) |
| time.sleep(1) |
| |
| if not api_ready: |
| print("\n⚠️ API server might not be fully ready, but continuing anyway") |
| |
| |
| def start_streamlit_app(): |
| nonlocal streamlit_process |
| |
| for proc in psutil.process_iter(['pid', 'name', 'cmdline']): |
| try: |
| if 'streamlit' in str(proc.info['cmdline']).lower() and 'run' in str(proc.info['cmdline']): |
| print(f"Killing existing streamlit process (PID: {proc.info['pid']})") |
| psutil.Process(proc.info['pid']).kill() |
| except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess): |
| pass |
| |
| print("Starting Streamlit web interface...") |
| return subprocess.Popen( |
| [sys.executable, "-m", "streamlit", "run", "app.py"], |
| stdout=subprocess.PIPE, |
| stderr=subprocess.PIPE, |
| bufsize=1, |
| universal_newlines=True |
| ) |
| |
| |
| streamlit_process = start_streamlit_app() |
| |
| |
| time.sleep(3) |
| print("✅ Streamlit web interface started") |
| |
| |
| try: |
| print("Opening web interface in your browser...") |
| webbrowser.open(streamlit_url) |
| except Exception as e: |
| print(f"Failed to open browser. Please open this URL manually: {streamlit_url}") |
| |
| |
| print("\n📋 Application URLs:") |
| print(f" - Web Interface: {streamlit_url}") |
| print(f" - API: {api_url}") |
| |
| |
| def handle_exit(signum, frame): |
| print("\n👋 Shutting down gracefully...") |
| shutdown_services(api_process, streamlit_process) |
| sys.exit(0) |
| |
| signal.signal(signal.SIGINT, handle_exit) |
| |
| print("\n⌨️ Press Ctrl+C to stop the application...") |
| print("📊 Monitoring services for stability...\n") |
| |
| |
| request_count = 0 |
| last_check_time = time.time() |
| consecutive_failures = 0 |
| |
| try: |
| |
| while True: |
| |
| api_status = api_process.poll() |
| streamlit_status = streamlit_process.poll() |
| |
| if api_status is not None: |
| print(f"⚠️ API server stopped unexpectedly (exit code: {api_status})") |
| |
| api_process = start_api_server() |
| time.sleep(5) |
| |
| if streamlit_status is not None: |
| print(f"⚠️ Streamlit app stopped unexpectedly (exit code: {streamlit_status})") |
| |
| streamlit_process = start_streamlit_app() |
| time.sleep(5) |
| |
| |
| if time.time() - last_check_time > 10: |
| request_count += 1 |
| |
| if check_api_health(): |
| print(f"✅ Health check #{request_count}: API is responsive") |
| consecutive_failures = 0 |
| else: |
| consecutive_failures += 1 |
| print(f"⚠️ Health check #{request_count}: API not responding (failure #{consecutive_failures})") |
| |
| |
| if consecutive_failures >= 3: |
| print("❌ API has been unresponsive for too long. Restarting...") |
| |
| if api_process and api_process.poll() is None: |
| api_process.terminate() |
| time.sleep(1) |
| if api_process.poll() is None: |
| if sys.platform != 'win32': |
| os.kill(api_process.pid, signal.SIGKILL) |
| else: |
| subprocess.call(['taskkill', '/F', '/T', '/PID', str(api_process.pid)]) |
| |
| |
| api_process = start_api_server() |
| time.sleep(5) |
| consecutive_failures = 0 |
| |
| last_check_time = time.time() |
| |
| |
| try: |
| api_proc = psutil.Process(api_process.pid) |
| api_memory = api_proc.memory_info().rss / (1024 * 1024) |
| |
| |
| if api_memory > 500: |
| print(f"⚠️ API server using excessive memory: {api_memory:.2f} MB. Restarting...") |
| |
| if api_process and api_process.poll() is None: |
| api_process.terminate() |
| time.sleep(1) |
| api_process = start_api_server() |
| time.sleep(5) |
| except (psutil.NoSuchProcess, psutil.AccessDenied): |
| pass |
| |
| |
| time.sleep(2) |
| |
| except KeyboardInterrupt: |
| |
| print("\n👋 Shutting down...") |
| except Exception as e: |
| |
| print(f"\n❌ Error: {str(e)}") |
| finally: |
| shutdown_services(api_process, streamlit_process) |
|
|
| def shutdown_services(api_process, streamlit_process): |
| """Safely shut down all running services""" |
| |
| if api_process and api_process.poll() is None: |
| print("Stopping API server...") |
| try: |
| api_process.terminate() |
| |
| time.sleep(1) |
| |
| if api_process.poll() is None: |
| if sys.platform != 'win32': |
| os.kill(api_process.pid, signal.SIGKILL) |
| else: |
| subprocess.call(['taskkill', '/F', '/T', '/PID', str(api_process.pid)]) |
| except: |
| print("Could not terminate API server gracefully") |
| |
| if streamlit_process and streamlit_process.poll() is None: |
| print("Stopping Streamlit app...") |
| try: |
| streamlit_process.terminate() |
| |
| time.sleep(1) |
| |
| if streamlit_process.poll() is None: |
| if sys.platform != 'win32': |
| os.kill(streamlit_process.pid, signal.SIGKILL) |
| else: |
| subprocess.call(['taskkill', '/F', '/T', '/PID', str(streamlit_process.pid)]) |
| except: |
| print("Could not terminate Streamlit app gracefully") |
| |
| |
| for proc in psutil.process_iter(['pid', 'name', 'cmdline']): |
| try: |
| cmdline = str(proc.info['cmdline']).lower() |
| if ('uvicorn' in cmdline and '8001' in cmdline) or ('streamlit' in cmdline and 'run' in cmdline): |
| print(f"Killing leftover process: {proc.info['pid']}") |
| psutil.Process(proc.info['pid']).kill() |
| except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess): |
| pass |
| |
| print("\n✅ Application stopped") |
|
|
| if __name__ == "__main__": |
| main() |