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 返回、前端展示都引这里。
|
# 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="监听端口")
|
help="监听端口")
|
||||||
@click.option("--reload/--no-reload", default=False,
|
@click.option("--reload/--no-reload", default=False,
|
||||||
help="dev:文件改动自动重启(uvicorn 工厂模式)")
|
help="dev:文件改动自动重启(uvicorn 工厂模式)")
|
||||||
def web(host: str, port: int, reload: bool) -> None:
|
@click.option("--ssl-certfile", default=None,
|
||||||
"""启动 Web 服务(JSON API + dev SPA)。Auth 需 PLATFORM_KEY / JWT_SECRET env。"""
|
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
|
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 请求
|
# timeout_graceful_shutdown=5:SIGTERM 后 uvicorn 至多等 5s 关掉在连的 HTTP 请求
|
||||||
# (主要是长连 SSE GET,断开后客户端会重连,run 不受影响),再进 lifespan shutdown
|
# (主要是长连 SSE GET,断开后客户端会重连,run 不受影响),再进 lifespan shutdown
|
||||||
# 跑真正的 run drain(见 web/app.py finally + config/agent.yaml `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 才能监听文件
|
# reload 模式需要 import string + factory,uvicorn 才能监听文件
|
||||||
uvicorn.run("web.app:create_app", host=host, port=port,
|
uvicorn.run("web.app:create_app", host=host, port=port,
|
||||||
reload=True, factory=True, log_level="info",
|
reload=True, factory=True, log_level="info",
|
||||||
timeout_graceful_shutdown=5)
|
timeout_graceful_shutdown=5, **tls)
|
||||||
else:
|
else:
|
||||||
from web.app import create_app
|
from web.app import create_app
|
||||||
uvicorn.run(create_app(), host=host, port=port, log_level="info",
|
uvicorn.run(create_app(), host=host, port=port, log_level="info",
|
||||||
timeout_graceful_shutdown=5)
|
timeout_graceful_shutdown=5, **tls)
|
||||||
|
|
||||||
|
|
||||||
# ─────────────── Sandbox(Stage C 部署前置对账) ───────────────
|
# ─────────────── Sandbox(Stage C 部署前置对账) ───────────────
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue