Spaces:
Sleeping
Sleeping
| """ | |
| Script to run both the Streamlit app and FastAPI server together. | |
| This is used for deployment in environments like Hugging Face Spaces. | |
| """ | |
| import os | |
| import sys | |
| import subprocess | |
| import time | |
| import signal | |
| import logging | |
| from config import get_settings | |
| settings = get_settings() | |
| logging.basicConfig( | |
| level=logging.INFO, | |
| format="%(asctime)s - %(name)s - %(levelname)s - %(message)s", | |
| ) | |
| logger = logging.getLogger("run_combined") | |
| def run_streamlit(): | |
| """Run the Streamlit app""" | |
| streamlit_port = os.environ.get("STREAMLIT_SERVER_PORT", "7860") | |
| logger.info(f"Starting Streamlit app on port {streamlit_port}...") | |
| streamlit_process = subprocess.Popen( | |
| [sys.executable, "-m", "streamlit", "run", "app.py", | |
| f"--server.port={streamlit_port}", | |
| "--server.address=0.0.0.0", | |
| "--server.enableCORS=true", | |
| "--server.enableXsrfProtection=false"] | |
| ) | |
| return streamlit_process | |
| def run_api(): | |
| """Run the FastAPI server""" | |
| api_port = settings.API_PORT | |
| logger.info(f"Starting FastAPI server on port {api_port}...") | |
| api_process = subprocess.Popen( | |
| [sys.executable, "-m", "uvicorn", "api:app", | |
| "--host", "0.0.0.0", | |
| "--port", str(api_port), | |
| "--log-level", "info"] | |
| ) | |
| return api_process | |
| def handle_termination(api_process, streamlit_process): | |
| """Handle graceful termination""" | |
| def terminate_handler(signum, frame): | |
| logger.info("Received termination signal. Shutting down...") | |
| api_process.terminate() | |
| streamlit_process.terminate() | |
| sys.exit(0) | |
| signal.signal(signal.SIGINT, terminate_handler) | |
| signal.signal(signal.SIGTERM, terminate_handler) | |
| if __name__ == "__main__": | |
| # Start both services | |
| api_process = run_api() | |
| streamlit_process = run_streamlit() | |
| # Set up termination handler | |
| handle_termination(api_process, streamlit_process) | |
| logger.info("Both services started!") | |
| logger.info(f"FastAPI server running on http://localhost:{settings.API_PORT}") | |
| logger.info(f"Streamlit app running on http://localhost:{os.environ.get('STREAMLIT_SERVER_PORT', '7860')}") | |
| try: | |
| # Keep the main process running | |
| while True: | |
| # Check if processes are still running | |
| if api_process.poll() is not None: | |
| logger.error("API server stopped unexpectedly! Restarting...") | |
| api_process = run_api() | |
| if streamlit_process.poll() is not None: | |
| logger.error("Streamlit app stopped unexpectedly! Restarting...") | |
| streamlit_process = run_streamlit() | |
| time.sleep(5) | |
| except KeyboardInterrupt: | |
| logger.info("Stopping services...") | |
| api_process.terminate() | |
| streamlit_process.terminate() | |
| sys.exit(0) | |