Spaces:
Running
Running
""" | |
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) | |