4.5 KiB
Fish API
FastAPI 网关:分块接收 SVO2(FishMeasure)与 MP4(FishAction),在后台调用现有脚本;对外提供文档约定的 GET 轮询接口,并托管预览视频 URL。
依赖环境
- Python 3.11+(uv 可管理 3.13 等版本)
- FishMeasure:需与本机
FishMeasure/一致的环境(ZED SDK、pyzed、CUDA、YOLO/SAM 权重等) - FishAction:需可运行
FishAction/predict_video_x3d_3class.py(PyTorch、PyTorchVideo、checkpoint)
若 FishMeasure 与 FishAction 使用不同虚拟环境,可设置:
PYTHON_FISH_MEASURE— 运行predict_weigth_from_svo2.py的解释器路径PYTHON_FISH_ACTION— 运行predict_video_x3d_3class.py的解释器路径
单一 Conda 环境:若 FishMeasure 与 FishAction 已与网关停在同一个 env(例如仓库根目录 packaging/conda-fishserver.yaml 定义的 fishserver),则不要设置上述两个变量,子进程会使用当前 uvicorn 的 Python。可用 scripts/run_fishserver.sh 启动。
配置(环境变量)
| 变量 | 说明 | 默认 |
|---|---|---|
PUBLIC_BASE_URL |
返回 JSON 中 video_left / video_right 的前缀(勿带末尾 /) |
http://127.0.0.1:8000 |
INGEST_API_KEY |
非空时,/api/v1/ingest/* 需请求头 X-API-Key |
空(不校验) |
STREAM_TMP_DIR |
分块上传临时目录 | <repo>/fish_api/.data/ingest |
MEDIA_ROOT |
对外托管的 latest_left.mp4 / latest_right.mp4 |
<repo>/fish_api/.data/media |
FISH_MEASURE_ROOT |
FishMeasure 根目录 |
自动相对仓库 |
FISH_ACTION_ROOT |
FishAction 根目录 |
自动相对仓库 |
MEASURE_OUTPUT_ROOT |
传给 --save-output 的目录 |
FishMeasure/output_weight_estimator |
YOLO_MODEL / WEIGHT_CHECKPOINT / ACTION_CHECKPOINT |
模型路径 | 与仓库内脚本默认一致 |
SAM_DEVICE |
cuda 或 cpu |
cuda |
DEFAULT_FISH_SPECIES |
GET 中 result[].type |
大黄鱼 |
可在 fish_api/.env 中填写上述变量(pydantic-settings 会读取)。
安装与启动
cd fish_api
uv sync
# 可选:包含 httpx,便于本地用 FastAPI TestClient 做冒烟测试
# uv sync --group dev
uv run uvicorn app.main:app --host 0.0.0.0 --port 8000
OpenAPI:http://127.0.0.1:8000/docs
对外 GET(由其它系统轮询)
GET /api/v1/biomass/real/camera/— 双目 / 称重结果(最新一次成功快照)GET /api/v1/biomass/health/result/— 行为 / 健康(最新一次成功快照)
失败时返回 code: 500,msg 为错误信息,data 为空结构。
流式输入(分块上传)
POST /api/v1/ingest/svo/session或POST /api/v1/ingest/mp4/session→session_idPUT /api/v1/ingest/{svo|mp4}/session/{session_id}?offset=0(多次)- 追加语义:
offset必须等于当前已写入字节数(从 0 开始顺序上传)
- 追加语义:
POST /api/v1/ingest/{svo|mp4}/session/{session_id}/finalize→202 Accepted,后台开始跑对应算法
示例(小文件一次性,$API_KEY 可选):
BASE=http://127.0.0.1:8000
H=()
# H=(-H "X-API-Key: your-secret")
sid=$(curl -sS "${H[@]}" -X POST "$BASE/api/v1/ingest/svo/session" | jq -r .session_id)
curl -sS "${H[@]}" -T sample.svo2 -X PUT "$BASE/api/v1/ingest/svo/session/$sid?offset=0"
curl -sS "${H[@]}" -X POST "$BASE/api/v1/ingest/svo/session/$sid/finalize"
curl -sS "$BASE/api/v1/biomass/real/camera/"
MP4 将 svo 换成 mp4,本地文件换成 clip.mp4,轮询 GET /api/v1/biomass/health/result/。
说明:curl -T 发送 PUT 时 offset 为 0 且一次性传完整文件适合单块场景;多块时请自行递增 offset。
行为与健康映射
- X3D 输出
feeding/normal/scared→ 中文 吃饵 / 正常游行 / 惊吓 - 健康:
scared→ 不健康,其余 → 健康(启发式,可后续换专用模型)
视频 URL
FishMeasure 跑完后在输出目录查找 *preview*.mp4,复制到 MEDIA_ROOT/latest_left.mp4 与 latest_right.mp4(仅一个文件时左右 URL 可能相同)。确保 PUBLIC_BASE_URL 与前端/文档中的域名端口一致(例如 http://192.168.3.33:8888另起反向代理时,应把该值配成对外可达的 API 根)。
演进建议
- RTSP:用
ffmpeg切段写入 MP4 后调用现有finalize逻辑 - 任务状态:
finalize返回job_id,增加GET /jobs/{id}查询进度