Beaver Habit Tracker v0.10.0 API 使用详解
BeaverHabits v0.10.0 REST API 与 WebSocket 实时同步详解:JWT 认证、14 个端点全量实测回显、打卡查询过滤约定、错误码表与对接常见问题。
Beaver Habit Tracker v0.10.0 API 使用详解
目标:完整梳理 Beaver Habit Tracker(BeaverHabits)v0.10.0 的 REST API 与 WebSocket 实时同步接口——认证方式、全部端点、参数、请求示例与实测响应,帮助你用脚本或第三方客户端(如移动端、Home Assistant、自动化平台)对接自己的习惯数据。本文全部请求均在 v0.10.0 实例上用 curl 逐条实测,响应为真实回显(长响应标注节选)。版本查询日期 2026-10-22。
一、环境信息
| 项目 | 值 |
|---|---|
| 组件版本 | BeaverHabits v0.10.0(2026-07-30 发布,官方最新稳定版) |
| API 风格 | REST(JSON over HTTP),路由前缀 /api/v1;另含 1 个 WebSocket 端点 |
| API 文档 | 自带 Swagger UI:http://<服务器IP>:8080/docs(FastAPI 自动生成) |
| 认证 | JWT Bearer(登录获取)或 API Token(页面内生成,v0.9.0+) |
| 默认端口 | 8080 |
| 实测环境 | Ubuntu 22.04 + 官方镜像 daya0576/beaverhabits:0.10.0 部署实例(部署见 《Beaver Habit Tracker v0.10.0 Docker Compose 部署指南》) |
| 示例账号 | admin@example.com / q1w2e3r4 |
二、前置条件
- 一个可访问的 BeaverHabits v0.10.0 实例(本机或远程),本文以部署在服务器本机的
http://127.0.0.1:8080为基准地址(下文记作 BASE),远程调用把地址换成http://<服务器IP>:8080; - 一个已注册账号(注册方法见 4.1 节);
- 命令行工具 curl(或任何能发 HTTP 请求的客户端);
- 如需查看交互式文档,浏览器打开
/docs:
curl -s -o /dev/null -w "%{http_code}\n" http://127.0.0.1:8080/docs
实测回显:
200
三、API 总览
3.1 端点一览
| 方法 | 路径 | 作用 |
|---|---|---|
| POST | /auth/register | 注册账号 |
| POST | /auth/login | 登录,返回 JWT |
| GET | /users/me | 当前用户信息 |
| GET | /api/v1/habits | 习惯列表 |
| POST | /api/v1/habits | 创建习惯 |
| GET | /api/v1/habits/meta | 习惯排序元数据 |
| PUT | /api/v1/habits/meta | 修改习惯排序 |
| GET | /api/v1/habits/export | 导出全部习惯(含记录) |
| GET | /api/v1/habits/{habit_id} | 习惯详情(含打卡记录) |
| PUT | /api/v1/habits/{habit_id} | 更新习惯(名称/星标/状态/目标频率/标签) |
| DELETE | /api/v1/habits/{habit_id} | 删除习惯 |
| GET | /api/v1/habits/{habit_id}/completions | 查询打卡日期 |
| POST | /api/v1/habits/{habit_id}/completions | 打卡/取消打卡 |
| WS | /api/v1/sync/ws | WebSocket 实时同步(v0.10.0 新增) |
3.2 协议与认证约定
- 认证方式:除注册与登录外,全部端点要求
Authorization: Bearer <令牌>请求头。令牌有两种:/auth/login返回的 JWT(默认长期有效,见JWT_LIFETIME_SECONDS),或在 Web 界面 Menu → Tools → API Tokens 生成的永久 API Token(v0.9.0+)。REST 端点走 JWT;WebSocket 端点两者都接受(源码先查 JWT 再查 API Token); - 数据格式:请求与响应均为 JSON(登录除外,登录是表单编码);
- 日期约定:打卡接口默认日期格式
DD-MM-YYYY(可用date_fmt参数改);习惯详情与导出中的记录日期为YYYY-MM-DD; - 习惯 ID:6 位短 ID(如
ead5ef),创建成功时返回; - 限流约定:服务端无内建限流;生产实例为 gunicorn 单 worker(WebSocket 粘性要求),脚本批量调用注意控制并发,避免占满唯一 worker。
四、认证与首次调用
4.1 注册账号(已有账号跳过)
curl -s -X POST http://127.0.0.1:8080/auth/register \
-H "Content-Type: application/json" \
-d '{"email":"admin@example.com","password":"q1w2e3r4"}'
实测回显:
{"id":"66d57e38-2585-4dd6-a9a3-f222d5d5a1a5","email":"admin@example.com","is_active":true,"is_superuser":false,"is_verified":false}
4.2 登录获取 JWT
登录接口是表单编码(application/x-www-form-urlencoded),grant_type 固定 password:
curl -s -X POST http://127.0.0.1:8080/auth/login \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=password&username=admin@example.com&password=q1w2e3r4"
实测回显(token 为长 JWT,此处节选):
{"access_token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI2NmQ1N2UzOC0 ...(JWT 节选)","token_type":"bearer"}
4.3 带 JWT 首次调用
把返回的 access_token 放进 Authorization: Bearer 头调用任意端点。下文示例统一先用变量存放令牌:
TOKEN=$(curl -s -X POST http://127.0.0.1:8080/auth/login \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=password&username=admin@example.com&password=q1w2e3r4" \
| python3 -c "import sys,json;print(json.load(sys.stdin)['access_token'])")
curl -s http://127.0.0.1:8080/users/me -H "Authorization: Bearer $TOKEN"
实测回显:
{"id":"66d57e38-2585-4dd6-a9a3-f222d5d5a1a5","email":"admin@example.com","is_active":true,"is_superuser":false,"is_verified":false}
不带或带错令牌时返回 401:
curl -s http://127.0.0.1:8080/api/v1/habits -H "Authorization: Bearer invalid.token.here"
实测回显:
{"detail":"Not authenticated"}
五、各 API 域详解
5.1 习惯列表域
创建习惯 POST /api/v1/habits(参数:name,必填):
curl -s -X POST http://127.0.0.1:8080/api/v1/habits \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{"name":"Drink Water"}'
实测回显:
{"id":"ead5ef","name":"Drink Water"}
习惯列表 GET /api/v1/habits(可选参数:status,默认 active,取值 active/archive/soft_delete):
curl -s http://127.0.0.1:8080/api/v1/habits -H "Authorization: Bearer $TOKEN"
实测回显:
[{"id":"ead5ef","name":"Drink Water"}]
排序元数据 GET /api/v1/habits/meta 与 PUT /api/v1/habits/meta(参数:order,习惯 ID 数组,决定页面显示顺序):
curl -s -X PUT http://127.0.0.1:8080/api/v1/habits/meta \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{"order":["ead5ef"]}'
curl -s http://127.0.0.1:8080/api/v1/habits/meta -H "Authorization: Bearer $TOKEN"
实测回显(两次调用):
{"order":["ead5ef"]}
{"order":["ead5ef"]}
5.2 习惯详情域
详情 GET /api/v1/habits/{habit_id}(返回全部打卡记录):
curl -s http://127.0.0.1:8080/api/v1/habits/ead5ef -H "Authorization: Bearer $TOKEN"
实测回显(打卡两天后):
{"id":"ead5ef","name":"Drink Water","star":false,"records":[{"data":{"day":"2026-10-22","done":true,"timestamp":1792689300626}},{"data":{"day":"2026-10-21","done":true,"timestamp":1792689300641,"text":"5km"}}],"status":"active","period":null,"tags":[]}
记录(records)中每条 data 含 day(YYYY-MM-DD)、done、timestamp(毫秒),可选 text 为打卡备注。
更新习惯 PUT /api/v1/habits/{habit_id}(可更新字段:name、star、status、period、tags,均可选传):
curl -s -X PUT http://127.0.0.1:8080/api/v1/habits/ead5ef \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{"star":true}'
实测回显:
{"id":"ead5ef","name":"Drink Water","star":true,"records":[{"data":{"day":"2026-10-22","done":true,"timestamp":1792689300626}},{"data":{"day":"2026-10-21","done":true,"timestamp":1792689300641,"text":"5km"}}],"status":"active","period":null,"tags":[]}
period(目标频率)结构为 {"period_type":"D|W|M|Y","period_count":N,"target_count":M},例如「每周至少 3 次」即 period_type=W, period_count=1, target_count=3。status 可传 archive 归档习惯。
删除习惯 DELETE /api/v1/habits/{habit_id}(返回被删习惯对象;⚠️ 删除即生效,记录一并删除):
curl -s -X DELETE http://127.0.0.1:8080/api/v1/habits/65c250 -H "Authorization: Bearer $TOKEN"
实测回显(删除一条名为 Temp Del 的测试习惯):
{"id":"65c250","name":"Temp Del","star":false,"records":[],"status":"active","period":null,"tags":[]}
5.3 打卡记录域
打卡/取消打卡 POST /api/v1/habits/{habit_id}/completions。参数:done(布尔,必填)、date(字符串,必填,默认格式 DD-MM-YYYY)、text(备注,可选)、date_fmt(自定义日期格式,可选):
curl -s -X POST http://127.0.0.1:8080/api/v1/habits/ead5ef/completions \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{"done":true,"date":"22-10-2026"}'
实测回显:
{"day":"22-10-2026","done":true}
带备注打卡(另一天):
curl -s -X POST http://127.0.0.1:8080/api/v1/habits/ead5ef/completions \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{"done":true,"date":"21-10-2026","text":"5km"}'
实测回显:
{"day":"21-10-2026","done":true}
取消打卡传 "done":false(会追加一条 done=false 记录,覆盖当天完成状态)。
查询打卡日期 GET /api/v1/habits/{habit_id}/completions(返回已打卡日期数组):
curl -s "http://127.0.0.1:8080/api/v1/habits/ead5ef/completions" -H "Authorization: Bearer $TOKEN"
实测回显:
["21-10-2026","22-10-2026"]
过滤与排序(status/date_start/date_end/limit/sort/date_fmt,详见第六节):
curl -s "http://127.0.0.1:8080/api/v1/habits/ead5ef/completions?sort=desc&limit=1" -H "Authorization: Bearer $TOKEN"
实测回显:
["22-10-2026"]
5.4 数据导出域
GET /api/v1/habits/export 导出当前账号全部习惯与记录(原始字典透传,客户端字段无损往返),可用于备份或迁移到其他存储形态:
curl -s http://127.0.0.1:8080/api/v1/habits/export -H "Authorization: Bearer $TOKEN"
实测回显:
{"habits":[{"name":"Drink Water","records":[{"day":"2026-10-22","done":true,"timestamp":1792689300626},{"day":"2026-10-21","done":true,"timestamp":1792689300641,"text":"5km"}],"id":"ead5ef","tags":[],"star":true}],"order":["ead5ef"]}
⚠️ v0.10.0 没有 REST 导入端点;Web 界面的导入功能(设置页 Import)会把该格式的 JSON 合并回服务端,可用于跨存储迁移。
5.5 实时同步 WebSocket
/api/v1/sync/ws 是 v0.10.0 新增的 WebSocket 端点,用于多端实时同步打卡:客户端连上后发送 push_tick(打卡)或 push_habit_list(整表同步)消息,服务端持久化后回 *_ack 确认,并把变更广播给该账号的其他在线连接。
- 连接地址:
ws://<服务器IP>:8080/api/v1/sync/ws?token=<JWT 或 API Token>(认证走查询参数); push_tick消息字段:type、request_id(客户端生成,用于 ack 对应)、habit_id、day(格式固定YYYY-MM-DD)、done、text(可选);- 无效/缺失令牌时握手直接被拒绝(服务端以 1008 policy violation 关闭),客户端表现为连接升级失败。
实测(在实例上用 Python websockets 库连接并发送一次打卡):
import asyncio, json, urllib.request, urllib.parse
data = urllib.parse.urlencode({"grant_type":"password","username":"admin@example.com","password":"q1w2e3r4"}).encode()
req = urllib.request.Request("http://127.0.0.1:8080/auth/login", data=data, headers={"Content-Type":"application/x-www-form-urlencoded"})
token = json.load(urllib.request.urlopen(req))["access_token"]
import websockets
async def main():
uri = "ws://127.0.0.1:8080/api/v1/sync/ws?token=" + token
async with websockets.connect(uri) as ws:
await ws.send(json.dumps({"type":"push_tick","request_id":"r1","habit_id":"ead5ef","day":"2026-10-20","done":True}))
print("recv:", await ws.recv())
asyncio.run(main())
实测回显:
recv: {"type":"tick_ack","request_id":"r1","timestamp":1792689346203}
无令牌连接的实测结果:
closed: InvalidStatus None
六、分页/过滤/排序通用约定
BeaverHabits 的 REST API 没有分页:习惯列表一次返回全部;打卡日期查询按时间过滤后最多返回 limit 条(默认 10)。打卡查询(GET /api/v1/habits/{habit_id}/completions)支持的通用参数如下(全部实测有效):
| 参数 | 默认值 | 说明 |
|---|---|---|
status | 只返回完成(DONE) | 完成状态过滤,多个用逗号分隔(如 DONE,SKIP),非法值 400 |
date_fmt | %d-%m-%Y | 输入输出日期格式(strptime/strftime 格式串,如 %Y-%m-%d) |
date_start / date_end | 不限 | 起止日期(按 date_fmt 解析),start > end 时 400 |
limit | 10 | 返回条数上限,0 或空返回全部 |
sort | asc | asc 升序 / desc 降序,其他值 400 |
习惯列表的 status 参数(GET /api/v1/habits)与之不同:过滤的是习惯本身的状态(active/archive/soft_delete)。
七、常见问题
7.1 401 Not authenticated
令牌缺失、写错(没有 Bearer 前缀)或 JWT 已过期(设置了 JWT_LIFETIME_SECONDS 后)。重新登录获取令牌;脚本里建议把 4.3 节的取令牌逻辑封装成函数。
7.2 404 "The habit list data may be broken or missing"
新注册账号(还没有任何习惯清单文件)调用 GET /api/v1/habits 会返回该 404(实测见上),先 POST /api/v1/habits 创建第一个习惯即可。切换过 HABITS_STORAGE 的账号出现同样报错,说明当前存储下没有该账号的数据,处理见配置详解篇 7.4 节。
7.3 400 Invalid date format / Invalid sort value
打卡接口默认只认 DD-MM-YYYY(日-月-年)顺序,2026-10-22 会被判非法,需传 22-10-2026 或显式指定 date_fmt(如 %Y-%m-%d)。sort 只接受 asc/desc。
7.4 REST 端点能用 API Token 吗
REST 端点只认 JWT;API Token(页面 Menu → Tools → API Tokens 生成)目前用于 WebSocket 端点(?token= 同时接受 JWT 与 API Token)及配套的客户端生态。脚本对接 REST 建议用登录 JWT。
7.5 批量调用把服务打满了
生产实例是 gunicorn 单 worker(WebSocket 同步依赖单进程广播),大量并发请求会排队。脚本批量打卡请在请求间加间隔,或降低并发数。
7.6 想看在线文档但 /docs 打不开
/docs 由 FastAPI 自动挂载,v0.10.0 始终可用(实测 200)。若无法访问,确认地址端口与实例部署一致(容器部署映射的宿主端口可能不是 8080),且未被反向代理规则拦截。
八、参考链接
- API 源码(v0.10.0):https://github.com/daya0576/beaverhabits/blob/v0.10.0/beaverhabits/routes/api.py
- GitHub 仓库:https://github.com/daya0576/beaverhabits
- 在线 Swagger 文档:
http://<你的实例>:8080/docs - 组件介绍与选型:《Beaver Habit Tracker v0.10.0 介绍与选型指南》
- Docker Compose 部署:《Beaver Habit Tracker v0.10.0 Docker Compose 部署指南》
- 全部配置参数(JWT 期限、存储切换等):《Beaver Habit Tracker v0.10.0 配置参数详解》
- 源码安装与 systemd 托管:《Ubuntu 22.04 安装 Beaver Habit Tracker v0.10.0 指南》