Files
TJWaterServerBinary/scripts/run_server.py
T

84 lines
2.1 KiB
Python

import asyncio
import atexit
import os
import signal
import subprocess
import sys
from urllib.parse import urlparse
import uvicorn
# 将项目根目录添加到 python 路径
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "..")))
_SIDECAR_PROCESS: subprocess.Popen | None = None
def _parse_sidecar_target() -> tuple[str, int]:
sidecar_url = os.getenv("COPILOT_SIDECAR_URL", "http://127.0.0.1:8787").strip()
parsed = urlparse(sidecar_url)
host = parsed.hostname or "127.0.0.1"
port = parsed.port or 8787
return host, port
def _stop_sidecar() -> None:
global _SIDECAR_PROCESS
proc = _SIDECAR_PROCESS
if proc is None:
return
if proc.poll() is None:
proc.terminate()
try:
proc.wait(timeout=5)
except subprocess.TimeoutExpired:
proc.kill()
proc.wait(timeout=3)
_SIDECAR_PROCESS = None
def _start_sidecar_if_needed() -> None:
global _SIDECAR_PROCESS
sidecar_dir = os.path.abspath(
os.path.join(os.path.dirname(__file__), "..", "copilot-sidecar")
)
host, port = _parse_sidecar_target()
cmd = [
sys.executable,
"-m",
"uvicorn",
"server:app",
"--host",
host,
"--port",
str(port),
"--log-level",
os.getenv("COPILOT_SIDECAR_LOG_LEVEL", "warning"),
]
_SIDECAR_PROCESS = subprocess.Popen(cmd, cwd=sidecar_dir)
print(f"[run_server] sidecar started at {host}:{port}.")
if __name__ == "__main__":
# Windows 设置事件循环策略
if sys.platform == "win32":
asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
atexit.register(_stop_sidecar)
signal.signal(signal.SIGTERM, lambda *_: _stop_sidecar())
signal.signal(signal.SIGINT, lambda *_: _stop_sidecar())
_start_sidecar_if_needed()
try:
# 用 uvicorn.run 支持 workers 参数
uvicorn.run(
"app.main:app",
host="0.0.0.0",
port=8000,
# workers=2, # 这里可以设置多进程
loop="asyncio",
)
finally:
_stop_sidecar()