File size: 2,862 Bytes
9995fd4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
"""
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)