File size: 5,409 Bytes
dff71a5
 
4a645e8
dff71a5
4a645e8
dff71a5
 
 
 
 
 
 
 
 
 
 
 
 
 
4a645e8
 
dff71a5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4a645e8
dff71a5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
#!/usr/bin/env python3
"""
Startup script to run all services on Hugging Face Spaces deployment.
This script launches:
1. Streamlit app on $PORT (main port, 7860 for HF Spaces)
2. MCP Stock Server on $PORT + 1
3. MCP News Server on $PORT + 2
"""

import os
import sys
import time
import signal
import subprocess
import multiprocessing
from pathlib import Path


def get_port():
    """Get the main port from environment (Hugging Face Spaces uses 7860)."""
    port = os.environ.get("PORT", "7860")
    return int(port)


def run_streamlit():
    """Run Streamlit app on main port."""
    port = get_port()
    cmd = [
        sys.executable,
        "-m",
        "streamlit",
        "run",
        "Home.py",
        "--server.port",
        str(port),
        "--server.address",
        "0.0.0.0",
        "--server.headless",
        "true",
        "--browser.gatherUsageStats",
        "false",
    ]
    print(f"πŸš€ Starting Streamlit on port {port}")
    subprocess.run(cmd, check=True)


def run_stock_server():
    """Run MCP Stock Server on port + 1."""
    port = get_port() + 1
    cmd = [sys.executable, "mcp_stock_server.py"]
    print(f"πŸ“Š Starting MCP Stock Server on port {port}")
    # Set the port environment variable for the stock server
    env = os.environ.copy()
    env["PORT"] = str(port)
    subprocess.run(cmd, env=env, check=True)


def run_news_server():
    """Run MCP News Server on port + 2."""
    port = get_port() + 2
    cmd = [sys.executable, "mcp_news_server.py"]
    print(f"πŸ“° Starting MCP News Server on port {port}")
    # Set the port environment variable for the news server
    env = os.environ.copy()
    env["PORT"] = str(port)
    subprocess.run(cmd, env=env, check=True)


def signal_handler(signum, frame):
    """Handle shutdown signals gracefully."""
    print("\nπŸ›‘ Received shutdown signal. Stopping all services...")
    sys.exit(0)


def main():
    """Main function to start all services."""
    # Set up signal handlers
    signal.signal(signal.SIGINT, signal_handler)
    signal.signal(signal.SIGTERM, signal_handler)

    print("πŸš€ Starting Financial Agent Services...")
    print(f"πŸ“‹ Configuration:")
    print(f"   - Main Port: {get_port()}")
    print(f"   - Stock Server Port: {get_port() + 1}")
    print(f"   - News Server Port: {get_port() + 2}")

    # Check if required files exist
    required_files = ["Home.py", "mcp_stock_server.py", "mcp_news_server.py"]
    for file in required_files:
        if not Path(file).exists():
            print(f"❌ Error: {file} not found!")
            sys.exit(1)

    # Update MCP server URLs in Home.py for Hugging Face Spaces deployment
    try:
        print("πŸ”„ Updating MCP server URLs...")
        subprocess.run([sys.executable, "update_mcp_urls.py"], check=True)
        print("βœ… MCP server URLs updated successfully!")
    except Exception as e:
        print(f"⚠️ Warning: Could not update MCP URLs: {e}")
        print("Continuing with default configuration...")

    # Start all services in separate processes
    processes = []

    try:
        # Start MCP servers first (they need to be ready before Streamlit)
        print("πŸ”„ Starting MCP servers...")

        # Start stock server
        stock_process = multiprocessing.Process(
            target=run_stock_server, name="stock-server"
        )
        stock_process.start()
        processes.append(stock_process)

        # Start news server
        news_process = multiprocessing.Process(
            target=run_news_server, name="news-server"
        )
        news_process.start()
        processes.append(news_process)

        # Wait a bit for MCP servers to start
        print("⏳ Waiting for MCP servers to initialize...")
        time.sleep(5)

        # Start Streamlit app
        print("πŸ”„ Starting Streamlit app...")
        streamlit_process = multiprocessing.Process(
            target=run_streamlit, name="streamlit"
        )
        streamlit_process.start()
        processes.append(streamlit_process)

        print("βœ… All services started successfully!")
        print(f"🌐 Streamlit app available at: http://localhost:{get_port()}")
        print(f"πŸ“Š Stock server available at: http://localhost:{get_port() + 1}")
        print(f"πŸ“° News server available at: http://localhost:{get_port() + 2}")

        # Optional: Run deployment test
        if os.environ.get("RUN_DEPLOYMENT_TEST", "false").lower() == "true":
            print("\nπŸ§ͺ Running deployment test...")
            try:
                subprocess.run([sys.executable, "test_deployment.py"], check=True)
                print("βœ… Deployment test passed!")
            except subprocess.CalledProcessError:
                print("⚠️ Deployment test failed, but services may still be working...")

        # Wait for all processes
        for process in processes:
            process.join()

    except KeyboardInterrupt:
        print("\nπŸ›‘ Shutting down services...")
    except Exception as e:
        print(f"❌ Error starting services: {e}")
    finally:
        # Terminate all processes
        for process in processes:
            if process.is_alive():
                process.terminate()
                process.join(timeout=5)
                if process.is_alive():
                    process.kill()
        print("βœ… All services stopped.")


if __name__ == "__main__":
    main()