181 lines
4.6 KiB
Markdown
181 lines
4.6 KiB
Markdown
# apiserver
|
||
|
||
`apiserver/` 提供微信小程序用的远端渲染接口:
|
||
- 小程序只上传参数(字体 ID、文字、字号、颜色等)
|
||
- 服务端读取字体清单 + 字体目录,生成 SVG/PNG 后返回
|
||
|
||
## 1. 启动前准备(必须)
|
||
|
||
在仓库根目录执行:
|
||
|
||
```bash
|
||
cd /path/to/font2svg
|
||
|
||
# 1) 创建并激活虚拟环境(launchd 默认使用这个解释器)
|
||
python3 -m venv .venv
|
||
source .venv/bin/activate
|
||
|
||
# 2) 安装 Python 依赖
|
||
python -m pip install -U pip
|
||
python -m pip install -r requirements.txt
|
||
|
||
# 3) 若需要 PNG 接口,再安装 Node 依赖
|
||
npm install
|
||
```
|
||
|
||
快速验证:
|
||
|
||
```bash
|
||
/path/to/font2svg/.venv/bin/python -V
|
||
/path/to/font2svg/.venv/bin/python -c "import fontTools, uharfbuzz; print('ok')"
|
||
```
|
||
|
||
## 2. 启动(前台调试,生产见以下5. systemd、 6. launchd macOS。)
|
||
|
||
在仓库根目录执行:
|
||
|
||
```bash
|
||
/path/to/font2svg/.venv/bin/python apiserver/server.py \
|
||
--host 0.0.0.0 \
|
||
--port 9300 \
|
||
--static-root /path/to/font2svg
|
||
```
|
||
|
||
其中 `--static-root` 目录必须包含:
|
||
|
||
- `fonts/`(统一字体目录)
|
||
- `miniprogram/assets/fonts.json`(小程序清单)
|
||
|
||
如果不传 `--manifest`,默认优先读取 `<static-root>/miniprogram/assets/fonts.json`,不存在时回退到 `<static-root>/fonts.json`。
|
||
|
||
## 3. API
|
||
|
||
### GET `/healthz`
|
||
|
||
返回服务健康状态和已加载字体数量。
|
||
|
||
### POST `/api/render-svg`
|
||
|
||
请求示例:
|
||
|
||
```json
|
||
{
|
||
"fontId": "0001",
|
||
"text": "星程字体转换",
|
||
"fontSize": 120,
|
||
"fillColor": "#000000",
|
||
"letterSpacing": 0,
|
||
"maxCharsPerLine": 45
|
||
}
|
||
```
|
||
|
||
### POST `/api/render-png`
|
||
|
||
请求体与 `/api/render-svg` 相同,成功时直接返回 `image/png` 二进制。
|
||
小程序应使用 `wx.request({ responseType: 'arraybuffer' })` 接收。
|
||
|
||
成功响应:
|
||
|
||
```json
|
||
{
|
||
"ok": true,
|
||
"data": {
|
||
"fontId": "0001",
|
||
"fontName": "AlimamaDaoLiTi",
|
||
"width": 956.2,
|
||
"height": 144.3,
|
||
"svg": "<?xml ...>"
|
||
}
|
||
}
|
||
```
|
||
|
||
## 4. Nginx 反向代理
|
||
|
||
在 `fonts.biboer.cn` 的 server 块中增加:
|
||
|
||
```nginx
|
||
location /api/ {
|
||
proxy_pass http://127.0.0.1:9300;
|
||
proxy_http_version 1.1;
|
||
proxy_set_header Host $host;
|
||
proxy_set_header X-Real-IP $remote_addr;
|
||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||
proxy_set_header X-Forwarded-Proto $scheme;
|
||
proxy_connect_timeout 5s;
|
||
proxy_send_timeout 60s;
|
||
proxy_read_timeout 60s;
|
||
}
|
||
```
|
||
|
||
然后执行:
|
||
|
||
```bash
|
||
sudo nginx -t && sudo systemctl reload nginx
|
||
```
|
||
|
||
## 5. systemd(Linux,可选)
|
||
|
||
仓库内提供示例:`apiserver/font2svg-api.service.example`,可复制到:
|
||
|
||
```bash
|
||
sudo cp apiserver/font2svg-api.service.example /etc/systemd/system/font2svg-api.service
|
||
sudo systemctl daemon-reload
|
||
sudo systemctl enable --now font2svg-api
|
||
sudo systemctl status font2svg-api
|
||
```
|
||
|
||
## 6. launchd(macOS,可选)
|
||
|
||
仓库内提供示例:`apiserver/font2svg-api.launchd.plist.example`。
|
||
|
||
1. 复制并按本机路径修改(重点改 Python 路径和项目路径):
|
||
|
||
```bash
|
||
cp apiserver/font2svg-api.launchd.plist.example ~/Library/LaunchAgents/cn.biboer.font2svg-api.plist
|
||
```
|
||
|
||
2. 校验与权限修正:
|
||
|
||
```bash
|
||
plutil -lint ~/Library/LaunchAgents/cn.biboer.font2svg-api.plist
|
||
chown $(id -un):staff ~/Library/LaunchAgents/cn.biboer.font2svg-api.plist
|
||
chmod 644 ~/Library/LaunchAgents/cn.biboer.font2svg-api.plist
|
||
```
|
||
|
||
3. 加载并启动(不要使用 `sudo`):
|
||
|
||
```bash
|
||
launchctl bootout gui/$(id -u) ~/Library/LaunchAgents/cn.biboer.font2svg-api.plist 2>/dev/null || true
|
||
launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/cn.biboer.font2svg-api.plist
|
||
launchctl enable gui/$(id -u)/cn.biboer.font2svg-api
|
||
launchctl kickstart -k gui/$(id -u)/cn.biboer.font2svg-api
|
||
```
|
||
|
||
4. 查看状态与日志:
|
||
|
||
```bash
|
||
launchctl print gui/$(id -u)/cn.biboer.font2svg-api
|
||
tail -f /tmp/font2svg-api.log
|
||
```
|
||
|
||
5. 停止并卸载:
|
||
|
||
```bash
|
||
launchctl bootout gui/$(id -u) ~/Library/LaunchAgents/cn.biboer.font2svg-api.plist
|
||
```
|
||
|
||
常见错误排查:
|
||
|
||
- `Bootstrap failed: 5: Input/output error`
|
||
- 通常是 `plist` 路径/权限问题,或使用了 `sudo launchctl`。
|
||
- `Missing executable detected`
|
||
- `plist` 中 `ProgramArguments` 第一个路径不可执行(常见是 `.venv` 未创建)。
|
||
- 先执行“启动前准备(必须)”创建 `.venv`,再重载 launchd。
|
||
|
||
## 7. 约束
|
||
|
||
- 字体解析完全基于字体清单(默认 `miniprogram/assets/fonts.json`),字体文件统一从 `<static-root>/fonts/` 读取,`fontId` 必须存在。
|
||
- 服务端启用 CORS,允许小程序访问。
|
||
- 不依赖 Flask/FastAPI,使用 Python 标准库 HTTP 服务。
|
||
- `/api/render-png` 依赖 `node + sharp`(使用 `apiserver/svg_to_png.js` 转换)。
|