-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcli.py
More file actions
156 lines (136 loc) Β· 5.3 KB
/
cli.py
File metadata and controls
156 lines (136 loc) Β· 5.3 KB
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
import subprocess
import sys
import time
import signal
import os
FRONTEND_DIR = "frontend"
BACKEND_DIR = "backend"
BACKEND_RUN_CMD = ["uvicorn", "app.main:app", "--port", "8001"]
FRONTEND_RUN_CMD = ["npm", "run", "dev"]
BACKEND_INSTALL_CMD = ["pip", "install", "-r", "requirements.txt"]
FRONTEND_INSTALL_CMD = ["npm", "install"]
INSTALL_QWEN3_0_6B_CMD = ["ollama", "pull", "qwen3:0.6b"]
INSTALL_QWEN3_1_7B_CMD = ["ollama", "pull", "qwen3:1.7b"]
def install():
print("Installing backend dependencies...")
backend_install_proc = subprocess.Popen(
BACKEND_INSTALL_CMD,
cwd=BACKEND_DIR,
shell=True,
)
backend_install_proc.wait() # Wait for backend installation to complete
print("Installing frontend dependencies...")
frontend_install_proc = subprocess.Popen(
FRONTEND_INSTALL_CMD,
cwd=FRONTEND_DIR,
shell=True,
)
frontend_install_proc.wait() # Wait for frontend installation to complete
print("Installing Ollama models...")
ollama_install_proc_1 = subprocess.Popen(
INSTALL_QWEN3_0_6B_CMD,
shell=True,
)
ollama_install_proc_1.wait() # Wait for first model to complete
ollama_install_proc_2 = subprocess.Popen(
INSTALL_QWEN3_1_7B_CMD,
shell=True,
)
ollama_install_proc_2.wait() # Wait for second model to complete
print("All installations completed successfully!")
def launch():
backend_proc = None
frontend_proc = None
try:
# Start backend in the background
print("Starting backend server...")
# Create process in new process group for easier termination
if os.name == 'nt': # Windows
backend_proc = subprocess.Popen(
BACKEND_RUN_CMD,
cwd=BACKEND_DIR,
shell=True,
creationflags=subprocess.CREATE_NEW_PROCESS_GROUP
)
else: # Unix/Linux/Mac
backend_proc = subprocess.Popen(
BACKEND_RUN_CMD,
cwd=BACKEND_DIR,
shell=True,
preexec_fn=os.setsid
)
# Give backend time to start and check if it's still running
time.sleep(10)
if backend_proc.poll() is not None:
print("β Backend failed to start!")
return
print("β
Backend server started successfully")
# Start frontend
print("Starting frontend development server...")
# Create process in new process group for easier termination
if os.name == 'nt': # Windows
frontend_proc = subprocess.Popen(
FRONTEND_RUN_CMD,
cwd=FRONTEND_DIR,
shell=True,
creationflags=subprocess.CREATE_NEW_PROCESS_GROUP
)
else: # Unix/Linux/Mac
frontend_proc = subprocess.Popen(
FRONTEND_RUN_CMD,
cwd=FRONTEND_DIR,
shell=True,
preexec_fn=os.setsid
)
# Give frontend time to start and check if it's still running
time.sleep(10)
if frontend_proc.poll() is not None:
print("β Frontend failed to start!")
return
print("β
Frontend development server started successfully")
print("\nπ Both servers are running!")
print(" Backend: http://localhost:8001")
print(" Frontend: http://localhost:3000")
print("\nPress Ctrl+C to stop both servers...")
# Monitor processes and wait for interruption
while True:
time.sleep(1)
# Check if either process has died
if backend_proc.poll() is not None:
print("\nβ Backend process died unexpectedly!")
break
if frontend_proc.poll() is not None:
print("\nβ Frontend process died unexpectedly!")
break
except KeyboardInterrupt:
print("\nπ Shutting down servers...")
except Exception as e:
print(f"\nβ Error: {e}")
finally:
# Clean shutdown with process tree termination
for name, proc in [("Backend", backend_proc), ("Frontend", frontend_proc)]:
if proc and proc.poll() is None:
print(f" Stopping {name.lower()}...")
# On Windows, terminate the entire process tree
if os.name == 'nt': # Windows
subprocess.run(['taskkill', '/F', '/T', '/PID', str(proc.pid)],
capture_output=True, check=False)
print(f" β
{name} process tree stopped")
else: # Unix/Linux/Mac
# Send SIGTERM to process group
os.killpg(os.getpgid(proc.pid), signal.SIGTERM)
proc.wait(timeout=3)
print(f" β
{name} stopped")
print("π All servers stopped. Goodbye!")
sys.exit(0)
if __name__ == "__main__":
if len(sys.argv) > 1:
match sys.argv[1]:
case "start":
launch()
case "install":
install()
case _:
print("Usage: python cli.py (start | install)")
else:
print("Usage: python cli.py (start | install)")