feat(web): main.py web 支持 --ssl-certfile/--ssl-keyfile(uvicorn 原生 TLS,免 nginx)+ bump 0.26.8
两者同时给即在本端口跑 HTTPS,只给其一报错;都不给=明文(向后兼容)。 适配「只有 8765 对外」场景:zcbot 直接在 8765 上 HTTPS,不用 nginx/不挪端口。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
0cf6e3e61e
commit
23c5ab20e0
|
|
@ -1,3 +1,3 @@
|
|||
# zcbot 版本号单一事实源:web/app.py 的 FastAPI version、/healthz 返回、前端展示都引这里。
|
||||
# 改版本只动这一行。
|
||||
__version__ = "0.26.7"
|
||||
__version__ = "0.26.8"
|
||||
|
|
|
|||
22
main.py
22
main.py
|
|
@ -209,10 +209,24 @@ def user_role(email: str, role: str) -> None:
|
|||
help="监听端口")
|
||||
@click.option("--reload/--no-reload", default=False,
|
||||
help="dev:文件改动自动重启(uvicorn 工厂模式)")
|
||||
def web(host: str, port: int, reload: bool) -> None:
|
||||
"""启动 Web 服务(JSON API + dev SPA)。Auth 需 PLATFORM_KEY / JWT_SECRET env。"""
|
||||
@click.option("--ssl-certfile", default=None,
|
||||
help="TLS 证书链(fullchain.pem);与 --ssl-keyfile 同时给即在本端口跑 HTTPS")
|
||||
@click.option("--ssl-keyfile", default=None,
|
||||
help="TLS 私钥(privkey.pem)")
|
||||
def web(host: str, port: int, reload: bool,
|
||||
ssl_certfile: str | None, ssl_keyfile: str | None) -> None:
|
||||
"""启动 Web 服务(JSON API + dev SPA)。Auth 需 PLATFORM_KEY / JWT_SECRET env。
|
||||
|
||||
HTTPS:`--ssl-certfile <fullchain.pem> --ssl-keyfile <privkey.pem>`(uvicorn 原生 TLS,
|
||||
无需 nginx)。两者都不给 = 明文 HTTP(默认,向后兼容)。
|
||||
"""
|
||||
import uvicorn
|
||||
|
||||
# 两者都给才算启用 TLS;只给其一报错提醒(避免半配置悄悄退回 http)
|
||||
if bool(ssl_certfile) ^ bool(ssl_keyfile):
|
||||
raise click.UsageError("--ssl-certfile 与 --ssl-keyfile 必须同时提供")
|
||||
tls = {"ssl_certfile": ssl_certfile, "ssl_keyfile": ssl_keyfile} if ssl_certfile else {}
|
||||
|
||||
# timeout_graceful_shutdown=5:SIGTERM 后 uvicorn 至多等 5s 关掉在连的 HTTP 请求
|
||||
# (主要是长连 SSE GET,断开后客户端会重连,run 不受影响),再进 lifespan shutdown
|
||||
# 跑真正的 run drain(见 web/app.py finally + config/agent.yaml `shutdown` 段)。
|
||||
|
|
@ -221,11 +235,11 @@ def web(host: str, port: int, reload: bool) -> None:
|
|||
# reload 模式需要 import string + factory,uvicorn 才能监听文件
|
||||
uvicorn.run("web.app:create_app", host=host, port=port,
|
||||
reload=True, factory=True, log_level="info",
|
||||
timeout_graceful_shutdown=5)
|
||||
timeout_graceful_shutdown=5, **tls)
|
||||
else:
|
||||
from web.app import create_app
|
||||
uvicorn.run(create_app(), host=host, port=port, log_level="info",
|
||||
timeout_graceful_shutdown=5)
|
||||
timeout_graceful_shutdown=5, **tls)
|
||||
|
||||
|
||||
# ─────────────── Sandbox(Stage C 部署前置对账) ───────────────
|
||||
|
|
|
|||
Loading…
Reference in New Issue