run_web.py 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. import os
  2. import sys
  3. import webbrowser
  4. from waitress import serve
  5. def _load_dotenv_if_exists():
  6. try:
  7. from dotenv import load_dotenv
  8. except Exception:
  9. return
  10. exe_dir = os.path.dirname(os.path.abspath(sys.argv[0]))
  11. for name in ("config.env",):
  12. env_path = os.path.join(exe_dir, name)
  13. if os.path.exists(env_path):
  14. load_dotenv(env_path, override=True)
  15. break
  16. def main():
  17. _load_dotenv_if_exists()
  18. # 注意:必须在加载 config.env 之后再导入 app.py
  19. # 否则 app.py 顶层读取环境变量(DB/AI 等)时拿不到最新配置
  20. import app as webapp
  21. host = os.getenv("WEB_HOST", "127.0.0.1")
  22. port = int(os.getenv("WEB_PORT", "5000"))
  23. # 打开浏览器(只在本机访问时打开)
  24. if host in ("127.0.0.1", "localhost"):
  25. try:
  26. webbrowser.open(f"http://127.0.0.1:{port}", new=1)
  27. except Exception:
  28. pass
  29. # 正式服务(比 Flask debug 更稳定)
  30. try:
  31. serve(webapp.app, host=host, port=port, threads=8)
  32. except KeyboardInterrupt:
  33. print("\n服务已停止")
  34. except OSError as e:
  35. if "Address already in use" in str(e) or "只允许使用一次" in str(e):
  36. print(f"端口 {port} 已被占用,请修改 config.env 中的 WEB_PORT")
  37. else:
  38. print(f"服务启动失败: {e}")
  39. import traceback
  40. traceback.print_exc()
  41. except Exception as e:
  42. print(f"服务启动失败: {e}")
  43. import traceback
  44. traceback.print_exc()
  45. except KeyboardInterrupt:
  46. print("\n\n服务已停止")
  47. except OSError as e:
  48. if "Address already in use" in str(e) or "只允许使用一次" in str(e):
  49. print(f"\n\n✗ 端口 {port} 已被占用!")
  50. print(f" 请检查是否有其他程序在使用该端口")
  51. print(f" 或修改 config.env 中的 WEB_PORT 为其他端口(如 8080)")
  52. else:
  53. print(f"\n\n✗ 服务启动失败: {e}")
  54. import traceback
  55. traceback.print_exc()
  56. except Exception as e:
  57. print(f"\n\n✗ 服务启动失败: {e}")
  58. import traceback
  59. traceback.print_exc()
  60. if __name__ == "__main__":
  61. main()