Files
operating-room-monitor-server/scripts/demo_client/README.md
Kevin 42720f81cf feat: demo CORS, demo client, openpyxl catalog load
- Load consumable catalog XLSX with openpyxl and drop the pandas dependency.
- Add optional demo CORS settings and FastAPI CORSMiddleware for browser clients.
- Add scripts/demo_client static page and local server for API smoke tests.

Made-with: Cursor
2026-04-22 17:00:56 +08:00

65 lines
2.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Demo Client
一个浏览器里的单页 demo用于手动触发 `app/api.py` 里的 5 个 `/client/*` 接口,覆盖开始/结束手术、查询结果、拉取待确认耗材,以及**本地麦克风录 WAV 并上传**语音确认接口。
## 结构
```
scripts/demo_client/
server.py # 基于 stdlib 的静态服务器;额外暴露 /labels.json
index.html # 单文件页面(原生 JS零构建依赖
```
## 运行方式
```bash
# 1) 启动后端(默认 38080。CORS 中间件在 settings.demo_cors_enabled=True 时自动挂载。
uv run python main.py
# 2) 启动 demo 客户端静态服务(默认 127.0.0.1:38081
python scripts/demo_client/server.py
# 或指定端口:
python scripts/demo_client/server.py -p 9000 --host 0.0.0.0
# 3) 浏览器访问:
open http://localhost:38081/
```
页面顶部的「服务端 Base URL」默认是 `http://localhost:38080`;如果后端部署在其他主机/端口,直接改这里即可。
## 页面包含什么
- `GET /health` 连通性检查
- §4.1 `POST /client/surgeries/start` — 含 `surgery_id` 校验、`camera_ids` 多值输入、`candidate_consumables` 标签编辑器(初始值从 `/labels.json` 载入,可增删)
- §4.2 `POST /client/surgeries/end`
- §4.3 `GET /client/surgeries/{id}/result` — 以表格渲染 `details``summary`
- §4.4 `GET /client/surgeries/{id}/pending-confirmation` — 支持手动拉取与 2s 自动轮询
- §4.5 `POST .../resolve` — 本地麦克风录音 → 16 kHz 单声道 WAV → `multipart/form-data` 上传
右侧「响应日志」按时间倒序展示每次请求的 method/url/status/body便于联调截图。
## 关于 `/labels.json`
`server.py` 在进程启动时读 `app/resources/consumable_classifier_labels.yaml``names` 映射并返回 `{"labels": [...]}`。优先用 `PyYAML`(主项目依赖已间接引入),缺失时回退到手写的最小 YAML 解析器(仅兼容该文件的已知形状)。
## 关于麦克风
浏览器的 `getUserMedia` 仅在**安全上下文**可用,对 demo 实际意味着:
- **可以用**`http://localhost``http://127.0.0.1``https://...`
- **不能用**:直接 `file://` 双击打开 `index.html`,或通过非本机 `http://` 访问 —— 所以这里用了独立的静态 HTTP 服务器而不是 `file://`
页面采用:
1. `navigator.mediaDevices.getUserMedia` 拿到单声道音轨
2. `AudioContext` + `ScriptProcessorNode` 捕获 Float32 原始 PCM输入采样率取决于系统如 48 kHz
3. 前端把样本线性降采样到 16 kHz、转 Int16 并拼 RIFF/WAVE 头
4. 产出 `Blob("audio/wav")` 后可以「下载 wav调试」或直接「上传并确认」
## 关闭 CORS生产环境
`app/config.py` 新增:
- `DEMO_CORS_ENABLED`(默认 `True`,生产请在 `.env` 里置 `false`
- `DEMO_CORS_ORIGINS`(默认 `*`,可写 `http://my-host:38081,https://or-demo.example.com`