apiserver
apiserver/ 提供微信小程序用的远端渲染接口:
- 小程序只上传参数(字体 ID、文字、字号、颜色等)
- 服务端读取字体清单 + 字体目录,生成 SVG/PNG 后返回
1. 启动前准备(必须)
在仓库根目录执行:
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
快速验证:
/path/to/font2svg/.venv/bin/python -V
/path/to/font2svg/.venv/bin/python -c "import fontTools, uharfbuzz; print('ok')"
2. 启动(前台调试)
在仓库根目录执行:
/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
请求示例:
{
"fontId": "0001",
"text": "星程字体转换",
"fontSize": 120,
"fillColor": "#000000",
"letterSpacing": 0,
"maxCharsPerLine": 45
}
POST /api/render-png
请求体与 /api/render-svg 相同,成功时直接返回 image/png 二进制。
小程序应使用 wx.request({ responseType: 'arraybuffer' }) 接收。
成功响应:
{
"ok": true,
"data": {
"fontId": "0001",
"fontName": "AlimamaDaoLiTi",
"width": 956.2,
"height": 144.3,
"svg": "<?xml ...>"
}
}
4. Nginx 反向代理
在 fonts.biboer.cn 的 server 块中增加:
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;
}
然后执行:
sudo nginx -t && sudo systemctl reload nginx
5. systemd(Linux,可选)
仓库内提供示例:apiserver/font2svg-api.service.example,可复制到:
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。
- 复制并按本机路径修改(重点改 Python 路径和项目路径):
cp apiserver/font2svg-api.launchd.plist.example ~/Library/LaunchAgents/cn.biboer.font2svg-api.plist
- 校验与权限修正:
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
- 加载并启动(不要使用
sudo):
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
- 查看状态与日志:
launchctl print gui/$(id -u)/cn.biboer.font2svg-api
tail -f /tmp/font2svg-api.log
- 停止并卸载:
launchctl bootout gui/$(id -u) ~/Library/LaunchAgents/cn.biboer.font2svg-api.plist
常见错误排查:
Bootstrap failed: 5: Input/output error- 通常是
plist路径/权限问题,或使用了sudo launchctl。
- 通常是
Missing executable detectedplist中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转换)。