mirror of
https://ghfast.top/https://github.com/aeroxw/easy_tdx_max.git
synced 2026-09-12 14:34:18 +08:00
fix(packaging): v1.19.5 PyPI wheel 含前端 dist(pip install 后不再 404)
根因:PyPI wheel 只有 Python 包,不含前端 dist。_resolve_web_dist_dir 三级探测(env/_MEIPASS/仓库根)在 PyPI 安装环境下全失败返回 None, StaticFiles 不挂载,GET / 返回 404。 修复: - pyproject.toml hatchling force-include 把 web-ui/dist 映射到包内 easy_tdx/web/dist - publish.yml 在 python -m build 前先 npm ci && npm run build - _resolve_web_dist_dir 新增第 4 级探测:包内 easy_tdx/web/dist 验证:本地构建 wheel 含 4 个前端文件,模拟 PyPI 安装后第 4 级探测 成功找到 dist。907 测试全过。
This commit is contained in:
@@ -20,6 +20,20 @@ jobs:
|
||||
with:
|
||||
python-version: "3.13"
|
||||
|
||||
# 构建前端 → web-ui/dist/,hatchling force-include 把它打进 wheel
|
||||
# 的 easy_tdx/web/dist/,让 pip install easy-tdx[web] 开箱即用 UI。
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: "20"
|
||||
cache: "npm"
|
||||
cache-dependency-path: web-ui/package-lock.json
|
||||
|
||||
- name: Build frontend
|
||||
run: |
|
||||
npm ci
|
||||
npm run build
|
||||
working-directory: web-ui
|
||||
|
||||
- run: pip install build
|
||||
|
||||
- run: python -m build
|
||||
|
||||
@@ -2,6 +2,15 @@
|
||||
|
||||
本文件记录 easy-tdx 的版本变更。格式遵循 [Keep a Changelog](https://keepachangelog.com/zh-CN/)。
|
||||
|
||||
## [1.19.5] — 2026-07-07
|
||||
|
||||
**修复 PyPI 安装后 `localhost:8000` 返回 404** —— `pip install easy-tdx[web]` 后启动 `easy-tdx serve`,浏览器打开 `localhost:8000` 直接 404。根因:PyPI wheel 不含前端 dist(只有 Python 包),`_resolve_web_dist_dir()` 三级探测全失败返回 None,StaticFiles 不挂载。v1.19.2 的 MIME 修复、v1.19.3 的 SPA fallback 都只对 EXE 打包态生效——PyPI 安装态连 dist 都没有,更谈不上 MIME 或 SPA。
|
||||
|
||||
### 修复
|
||||
|
||||
- **前端 dist 打进 wheel**(`pyproject.toml` + `.github/workflows/publish.yml`)—— hatchling 配置 `force-include` 把 `web-ui/dist` 映射到包内 `easy_tdx/web/dist`;`publish.yml` 在 `python -m build` 前先 `npm ci && npm run build` 构建前端。PyPI 用户 `pip install easy-tdx[web]` 后开箱即用 UI,无需 clone 仓库或手动构建前端。
|
||||
- **`_resolve_web_dist_dir()` 第 4 级探测**(`src/easy_tdx/web/app.py`)—— 新增"包内 `easy_tdx/web/dist`"分支,在环境变量 / _MEIPASS / 仓库根三级都失败后,回退到 PyPI 安装的包内 dist。
|
||||
|
||||
## [1.19.4] — 2026-07-07
|
||||
|
||||
**修复取不到行情数据的根因:MAC 客户端污染标准协议的 best_host** —— v1.19.3 在实际机器上"所有股票都取不到数据"(K 线响应偏移 2 剩余 0)。根因是 `mac/client.py` 的 `MacClient.from_best_host()` 和 `AsyncMacClient.from_best_host()` 调用了 `save_best_host(best)`——把选中的 **MAC 协议服务器**(如 `121.36.248.138`)写进了全局 `best_host` 字段,但这个字段是**标准 TDX 协议**用的。之后标准 `AsyncTdxClient` 用 `get_best_host()` 读到这个 MAC host,用标准协议请求 MAC 服务器,返回空 body。web app 启动时 lifespan 会启动 MAC 客户端,这就是污染时机。
|
||||
|
||||
+9
-1
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
||||
|
||||
[project]
|
||||
name = "easy-tdx"
|
||||
version = "1.19.4"
|
||||
version = "1.19.5"
|
||||
description = "通达信 TCP 协议行情数据客户端,支持在线行情、离线数据读取与写入同步"
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.10"
|
||||
@@ -23,6 +23,14 @@ packaging = ["pystray>=0.19", "Pillow>=10.0"]
|
||||
|
||||
[tool.hatch.build.targets.wheel]
|
||||
packages = ["src/easy_tdx"]
|
||||
# 前端 dist 作为数据文件打进 wheel,让 PyPI 安装的用户也能开箱即用 web UI。
|
||||
# 前端必须先构建到 web-ui/dist/(release.yml / publish.yml 都会先 npm run build)。
|
||||
# 映射到包内 easy_tdx/web/dist/,运行时由 _resolve_web_dist_dir 第 4 级探测。
|
||||
artifacts = [
|
||||
"src/easy_tdx/web/dist",
|
||||
]
|
||||
[tool.hatch.build.targets.wheel.force-include]
|
||||
"web-ui/dist" = "easy_tdx/web/dist"
|
||||
|
||||
[tool.mypy]
|
||||
strict = true
|
||||
|
||||
+10
-2
@@ -21,8 +21,8 @@ logger = logging.getLogger(__name__)
|
||||
def _resolve_web_dist_dir() -> Path | None:
|
||||
"""定位前端构建产物目录(Vite build 输出的 ``web-ui/dist``)。
|
||||
|
||||
依次探测三处,命中即返回,全部缺失时返回 ``None``(开发期未构建前端
|
||||
时正常,路由层照常工作,仅前端页面 404):
|
||||
依次探测四处,命中即返回,全部缺失时返回 ``None``(仅 API 可用,
|
||||
前端页面 404):
|
||||
|
||||
1. ``EASY_TDX_WEB_DIST`` 环境变量——部署/调试时显式指定。
|
||||
2. PyInstaller 运行态:``sys._MEIPASS / "web_dist"``——单 EXE 解压
|
||||
@@ -30,6 +30,9 @@ def _resolve_web_dist_dir() -> Path | None:
|
||||
此分支自动跳过。
|
||||
3. 开发态:仓库根目录的 ``web-ui/dist``——支持 ``pip install -e .``
|
||||
后直接 ``easy-tdx serve`` 调试,无需打包。
|
||||
4. PyPI wheel 安装态:包内 ``easy_tdx/web/dist``——hatchling 把
|
||||
编译好的 dist 作为数据文件打进 wheel(v1.19.5 起含),让
|
||||
``pip install easy-tdx[web]`` 后开箱即用 web UI。
|
||||
"""
|
||||
env_dir = os.environ.get("EASY_TDX_WEB_DIST")
|
||||
if env_dir:
|
||||
@@ -50,6 +53,11 @@ def _resolve_web_dist_dir() -> Path | None:
|
||||
if p.is_dir():
|
||||
return p
|
||||
|
||||
# PyPI 安装态:包内的 web/dist(wheel 打包时 force-include 进来)
|
||||
pkg_dist = Path(__file__).resolve().parent / "dist"
|
||||
if pkg_dist.is_dir():
|
||||
return pkg_dist
|
||||
|
||||
return None
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user