-
Notifications
You must be signed in to change notification settings - Fork 44
Expand file tree
/
Copy pathstart_dev.py
More file actions
120 lines (102 loc) · 3.92 KB
/
start_dev.py
File metadata and controls
120 lines (102 loc) · 3.92 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
#!/usr/bin/env python3
"""
CountBot 应用启动脚本
开发模式启动,支持热重载
支持本地网络 IP 监控,类似 Vue3 启动模式
"""
import os
import sys
from pathlib import Path
from backend.utils.network import get_local_ips
from backend.utils.runtime_env import (
apply_bind_env,
is_public_bind_host,
resolve_bind_address,
)
# Windows 平台强制 UTF-8 编码,避免 GBK 编码错误
if sys.platform == "win32":
# Python 3.7+ 支持
os.environ["PYTHONIOENCODING"] = "utf-8"
# 设置控制台代码页为 UTF-8
try:
import ctypes
kernel32 = ctypes.windll.kernel32
kernel32.SetConsoleCP(65001)
kernel32.SetConsoleOutputCP(65001)
except Exception:
pass
# 添加项目根目录到 Python 路径
project_root = Path(__file__).parent
sys.path.insert(0, str(project_root))
def main():
"""
启动应用(开发模式)
功能:
- 启动 FastAPI 应用服务器(开发模式)
- 启用热重载,文件更改自动重启
- 显示本地和网络访问地址
- 监控 backend 目录的文件变化
"""
import uvicorn
from loguru import logger
from backend.utils.logger import build_uvicorn_log_config
# 读取配置
host, port = resolve_bind_address()
apply_bind_env(host, port)
# 获取本地 IP 地址
local_ips = get_local_ips()
# 打印启动信息
logger.info("=" * 60)
logger.info("CountBot 开发模式启动中...")
logger.info("=" * 60)
try:
# 启动服务器前显示"服务器启动完成"消息和访问地址
logger.info("服务器启动完成!")
logger.info("=" * 60)
# 显示本地访问地址
logger.info(f"Local: http://localhost:{port}")
# 显示网络访问地址(如果监听了所有接口或用户明确设置了 0.0.0.0)
if is_public_bind_host(host):
if local_ips:
for ip in local_ips:
logger.info(f"Network: http://{ip}:{port}")
else:
logger.info("Network: (无法检测到本地 IP 地址)")
logger.info(f"提示: 请检查网络连接或手动访问 http://<your-ip>:{port}")
else:
# 即使监听 127.0.0.1,也显示可用的网络 IP 供参考
if local_ips:
logger.info(f"Network: http://{host}:{port}")
logger.info("提示: 如需从其他设备访问,请设置 COUNTBOT_HOST=0.0.0.0")
logger.info(f"可用网络 IP: {', '.join(local_ips)}")
else:
logger.info(f"Network: http://{host}:{port}")
logger.info("提示: 如需从其他设备访问,请设置 COUNTBOT_HOST=0.0.0.0")
logger.info("-" * 60)
logger.info("热重载已启用 - 文件更改将自动重启")
logger.info("按下 Ctrl+C 停止服务器")
logger.info("=" * 60)
# 在 Windows 开发模式下,uvicorn 的 reload 会切到 SelectorEventLoop,
# 这会让 asyncio.create_subprocess_shell 无法使用。
run_kwargs = dict(
app="backend.app:app",
host=host,
port=port,
reload=True, # 开发模式启用热重载
reload_dirs=["backend"], # 监控 backend 目录
log_level="debug", # 开发模式使用 debug 日志级别
log_config=build_uvicorn_log_config(),
)
if sys.platform == "win32":
run_kwargs["loop"] = "none"
# 启动服务器(开发模式)
uvicorn.run(**run_kwargs)
except KeyboardInterrupt:
logger.info("Received keyboard interrupt")
except Exception as e:
logger.error(f"Server error: {e}")
raise
finally:
logger.info("Application shutdown complete")
if __name__ == "__main__":
main()