Doonook Chinese Calendar
黄历与星座运势 FastAPI 包。0.1.4 星座运势使用本地星历、规则引擎和 Qwen 生成;黄历、农历和节假日逻辑保持原实现。
星座生成流程
GET /api/v1/calendar/astro/{astroid}?date=YYYY-MM-DD 的响应仍是原始
AstroFortuneSchema,没有新增 envelope;包含 today、tomorrow、week、month、year。
已核对黄历通 Android/iOS 的字段模型。
- 查
astro_fortunes中对应星座/日期的记录;有记录就直接返回,包括历史供应商记录。 - 缺失时在 PostgreSQL 获取该星座/日期的事务锁,再次检查缓存。
- 本地Skyfield/JPL星历计算七个天体位置、相位和太阳整宫,按版本化规则生成评分与因素,
再调用
.env配置的本地 Qwen/v1/chat/completions撰写文案。 - 校验完整 JSON、所有必填字段与字符串类型;日期、星座编号/名称由服务端填写。
- 校验成功后保存,后续请求复用。模型超时、截断或格式错误返回 503,不保存空数据, 不静默切换回第三方供应商。等待锁也有超时,取消和失败会释放事务。
模型收到与校验器一致的JSON Schema;当前MLX环境未启用约束解码,结构保证由服务端校验实现。 完整字段映射与中/本地后端路由边界见数据库契约。
计算方法、评分规则、授权和部署见星历生成链路。
五个现有JSON列内部保存 _basis 审计依据,公共响应仍沿用原字段。
没有数据库表列变更。旧记录不会被覆盖;同星座/日期的旧重复记录优先取最早记录。
同星期/月/年的文案仍按原表结构存于每日记录,不保证跨日期文本逐字一致。
配置 Qwen
星座运势已移除 Jisu / Juhe 调用和供应商切换,不再需要 ASTRO_PROVIDER。
URL、API Key、模型名均无代码默认值;缺少任一配置时,未缓存请求返回 503,已有缓存仍可读取。
实际配置写入 API / CLI 进程工作目录下的 .env,模板见 .env.example:
QWEN_BASE_URL=填写本地模型的Nginx地址并以/v1结尾
QWEN_LAN_API_KEY=填写Nginx的Bearer密钥
QWEN_MODEL=填写Ollama模型名称
QWEN_TIMEOUT_SECONDS=120
TIMEZONE=Asia/Shanghai
ASTRO_EPHEMERIS_PATH=
本机项目 .env 已填入现有部署值,权限为 600;.env 和 .env.* 均被 Git 忽略,
只提交无地址/密钥的 .env.example。配置不随 Python wheel 分发,也不返回给客户端。
Key 使用 SecretStr,普通配置对象展示会遮蔽它。环境变量优先于 .env;修改文件后重启进程生效。
包安装到主后端后,读取的是主后端进程工作目录的 .env,不会自动读取本源码目录的文件。
容器可通过 --env-file /安全路径/.env 注入;不要把 .env 复制进镜像或静态资源目录。
数据库沿用部署的 POSTGRES_*,部署时将 Qwen 四项加入现有宿主 .env。
ASTRO_EPHEMERIS_PATH 留空即可使用随pip包安装的星历文件,仅在替换数据文件时填写。
局域网服务器另有私有配置 ~/.config/qwen-lan/.env,用于独立模型验证;
从该目录运行时自动加载,手动测试也可通过 TEST_QWEN_ENV_FILE 指定绝对路径。
Qwen 只接收星座和日期,不发送用户身份或生日。Nginx 保留已有来源白名单和 Bearer 鉴权,
因此当前配置用于获准的本地服务器调用 Mac;在 Mac 源码目录执行网络调用不等于已获白名单许可。
Ollama 本身不要求 API key,这里的 key 是 Nginx 的访问凭证。
JISU_API_KEY 仅保留给独立的黄历日期接口;该接口未改为模型生成。
复用 doonook_temp 的 .env 与中国主库
无需修改 POSTGRES_HOST,也不需要单独给包复制一份 .env。在 doonook_temp
目录启动宿主时,包直接读取同一份 .env;容器部署继续由宿主的 env_file 注入。
本包沿用 doonook_common 的节点角色与主库地址规则,保留现有同步 SQLAlchemy 会话:
| 部署节点 | DOONOOK_NODE_ROLE | POSTGRES_HOST | REMOTE_WRITER_HOST | 本包数据库连接 |
|---|---|---|---|---|
| 中国 primary | primary | 中国节点本地 PG | 不使用 | POSTGRES_HOST |
| 本地 replica | replica | 本地只读副本,保持原值 | 中国主库的 WireGuard 地址 | REMOTE_WRITER_HOST |
本地服务器的宿主 .env 使用:
DOONOOK_NODE_ROLE=replica
REMOTE_WRITER_HOST=填写中国主库的WireGuard地址
# POSTGRES_HOST 保持原值;POSTGRES_USER/PASSWORD/PORT/DB 沿用宿主配置
# QWEN_BASE_URL / QWEN_LAN_API_KEY / QWEN_MODEL 同样放在这份 .env
副本角色缺少 REMOTE_WRITER_HOST 时配置加载失败,不会退回本地副本。
不要把中国 primary 的部署文件原样当成本地 replica 的文件;Mac 开发环境的节点角色也不代表服务器配置。
环境变量优先于文件,修改部署配置后需重启。
/astro/{astroid} 与 /daily 虽是 GET,均可能写数据库缓存,所以显式使用包内
get_db_writer。查询、锁、生成后的写入与回读始终连接同一主库,避免副本延迟造成重复生成。
warm-astro 和默认迁移地址也指向 writer。包内保留 get_db / SessionLocal 兼容别名,
均指向 writer;不引入按 GET 自动分配 reader 的规则。其他宿主模块的读写路由不受影响。
本次是复用宿主配置规则,没有把 doonook_common 的异步 AsyncSession 直接传入同步服务。
响应与表结构不变,无需客户端改动;依然需要在实际宿主安装更新后的 wheel 才能生效。
共享公开星座内容不新增 App 专属业务配置或跨 App 数据。
延迟与提前生成
实测一份完整五期运势首次约 30 秒,缓存查询约 6.6 毫秒。 现有 iOS 请求超时为 20 秒;因此正式切换前需要提前生成当天数据, 并在部署运行环境安排后续日期的预生成。缓存缺失路径可能超过现有客户端超时。 本次没有自动安装定时任务,也没有修改客户端超时。
doonook-calendar warm-astro --date 2026-09-17
# 只生成指定星座;可重复传入 --sign
doonook-calendar warm-astro --date 2026-09-18 --sign 1 --sign 2
不指定日期时,每次执行按 TIMEZONE 计算当天日期。12 个星座顺序处理,
与单并发 Qwen 服务匹配;失败以非零退出码结束,已完成记录保留,重试会跳过缓存。
历史缓存未清理;如需替换旧供应商内容,应另行制定有范围的刷新策略。
安装与宿主接入
本包通过PyPI发布、pip安装:pip install --upgrade doonook-chinese-calendar==0.1.4。
Skyfield依赖由pip安装,JPL星历随wheel/sdist内置,无需单独部署星历或为它编译C程序。
构建/发布时执行 python scripts/check_distribution.py 检查数据完整性与私有配置排除。
源码:pip install -e .。本地构建的 wheel:
dist/doonook_chinese_calendar-0.1.4-py3-none-any.whl。
doonook_temp 的运行依赖和 Dockerfile.base 仍固定 0.1.3。
正式接入需在明确的部署目标中统一升级依赖、安装 0.1.4、
重建基础镜像,注入上面的环境变量,预生成数据后验证现有 /calendar/astro 接口。
发布流程由匹配包版本的 v* 标签触发,或从 GitHub Actions 手动执行;先检查分发包,再上传 PyPI。
Apple Silicon / Linux ARM 上,现有依赖 sxtwl==2.0.7 的 PyPI sdist 缺少 C++ 源文件。
本次从官方 yuangu/sxtwl_cpp 提交
7598b0601a76cfdaa9266257b1b5690720c1e2ce 的 python/ 目录构建,
Linux ARM wheel 在隔离 Docker Python 3.11 环境生成,没有在服务器安装编译器。
目标系统须验证 ABI;本次 Linux ARM wheel 仅在 Ubuntu 25.04 / Python 3.11.16 验证。
在 Mac 上启动接口测试
独立入口 run_local.py 会启动完整日历路由与 Swagger。
它使用临时 SQLite 覆盖路由数据库依赖,退出后删除;不会连接 .env 中的业务 PostgreSQL。
该模式验证真实 Qwen → HTTP 接口 → JSON 校验 → 缓存,不验证 PostgreSQL writer 路由或跨进程并发锁。
本机已准备 /tmp/qwen-calendar-venv 和被 Git 忽略的 .env.local,从本项目目录启动:
/tmp/qwen-calendar-venv/bin/python run_local.py --env-file .env.local --port 8008
打开 http://127.0.0.1:8008/docs,选择 GET /api/v1/calendar/astro/{astroid},
点击 Try it out,填星座编号1–12和可选日期(YYYY-MM-DD),再 Execute。命令行也可测试:
curl --max-time 150 'http://127.0.0.1:8008/api/v1/calendar/astro/1?date=2026-09-17'
.env.local 的 URL 指向 Mac 本机 Ollama 回环接口;不经过仅允许局域网服务器访问的 Nginx。
其中 QWEN_LAN_API_KEY=local-test 仅满足客户端必填校验,Ollama 不校验这个占位值。
该文件只用于本机调试,不要拿它替换服务器的 Nginx 地址/真实密钥配置。
脚本仅读取选定文件中的模型及日历 API 配置,数据库设置强制替换为隔离测试会话。
测试文件的 JISU_API_KEY 留空;本轮联调的是星座接口,第三方黄历接口需单独有效配置。
热模型生成通常需20–30秒,冷启动可能更久;同日期同星座再次请求命中缓存。
模型输出未通过校验时返回503且不写入,可再次Execute;不同日期/星座会重新生成。
终端 Ctrl+C 停止,重启后临时缓存清空。脚本只监听127.0.0.1,默认单进程。
测试环境位于 /tmp,被清理后需重建 Python 3.11+ 环境,安装本包和 uvicorn;
ARM 的 sxtwl 安装限制见上方安装说明。
验证
测试显式覆盖数据库配置,禁止使用开发者 .env 中的业务数据库:
pytest -q tests
# PostgreSQL 并发测试需一次性独立测试库;测试会创建并删除 astro_fortunes
TEST_CALENDAR_DATABASE_URL=postgresql://test:test@127.0.0.1:独立测试端口/calendar_test pytest -q tests
tests/smoke_qwen_lan.py 是手动真实模型测试,使用临时 SQLite,不访问业务数据库;
设置 TEST_QWEN_ENV_FILE 指向私有 .env 后执行。生成示例存于执行用户的
~/.config/qwen-lan/sample-fortune.json。
可通过 TEST_CALENDAR_DATABASE_URL 指向本机空的独立 qwen_contract_test PostgreSQL库,
脚本会执行原始迁移、写入模型数据并验证断开模型后的跨session缓存读取;拒绝已有表的库。
实施记录见 .codex/task-log.md,当前上线边界见 .codex/context.md。
Metadata
Release files for doonook-chinese-calendar 0.1.4
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| doonook_chinese_calendar-0.1.4.tar.gz | 31.1 MB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| doonook_chinese_calendar-0.1.4-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 62.2 MB
Release files / doonook_chinese_calendar-0.1.4.tar.gz
| Download URL | doonook_chinese_calendar-0.1.4.tar.gz |
|---|---|
| Size | 31.1 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
81083e6dde77acec12485df55b8943688b3bb08b2ed41ce734de819dd98c0b8d
|
|
BLAKE2b-256 checksum How to use checksums |
be3030e151413e4842c00ef7eb20e7e5513acc5e21da20ae387f7d61949b029a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
poetry/2.4.3 CPython/3.11.16 Linux/6.17.0-1022-azure
|
Release files / doonook_chinese_calendar-0.1.4-py3-none-any.whl
| Download URL | doonook_chinese_calendar-0.1.4-py3-none-any.whl |
|---|---|
| Size | 31.1 MB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
e1a49228477e9159ac73e3a48f7247bd0bcfc422046b48f88336f631ce9745ce
|
|
BLAKE2b-256 checksum How to use checksums |
8fca425845f7858d2c8590a31085e50efbddf324c980b5cec46905b7fb22d6f9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
poetry/2.4.3 CPython/3.11.16 Linux/6.17.0-1022-azure
|