# subset-font-python **Repository Path**: jayday/subset-font-python ## Basic Information - **Project Name**: subset-font-python - **Description**: 提供api 子集化 字体文件,解决pdf 嵌入字体导致过大的问题 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-01-15 - **Last Updated**: 2026-01-15 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 字体子集化 API 服务 从服务器本地字体文件生成只包含指定字符的子集字体的 FastAPI 服务。 ## 功能特性 - 支持多种字体格式:TTF、OTF、WOFF、WOFF2 - 自动包含数字(0-9)和英文字母(a-z, A-Z) - 并发处理控制,防止服务器过载 - 自动清理临时文件 - RESTful API 设计 - 完善的安全防护(路径遍历攻击防护) ## 环境要求 - Python 3.8+ - 操作系统:Linux / macOS / Windows ## 快速开始 ### 1. 安装依赖 ```bash pip install -r requirements.txt ``` ### 2. 准备字体文件 将字体文件放入 `font` 目录: ```bash mkdir -p font # 将你的字体文件复制到 font 目录 # 例如:cp /path/to/SourceHanSansCN-Regular.ttf font/ ``` ### 3. 启动服务 **开发模式(自动重载):** ```bash python run.py ``` **生产模式:** ```bash uvicorn app.main:app --host 0.0.0.0 --port 8087 --workers 4 ``` 服务启动后访问: - API 文档:http://localhost:8087/docs - 健康检查:http://localhost:8087/health ## 生产环境部署 ### 方式一:直接使用 uvicorn ```bash # 安装依赖 pip install -r requirements.txt # 启动服务(4个 worker 进程) uvicorn app.main:app --host 0.0.0.0 --port 8087 --workers 4 --log-level info ``` **推荐 uvicorn 参数:** | 参数 | 说明 | 推荐值 | |------|------|--------| | `--host` | 监听地址 | `0.0.0.0` | | `--port` | 监听端口 | `8087` | | `--workers` | Worker 进程数 | `CPU核心数 * 2 + 1` | | `--log-level` | 日志级别 | `info` 或 `warning` | | `--access-log` | 访问日志 | 开启 | | `--loop` | 事件循环类型 | `uvloop`(Linux) | ### 方式二:使用 Systemd(Linux) 创建服务文件 `/etc/systemd/system/font-subset.service`: ```ini [Unit] Description=字体子集化 API 服务 After=network.target [Service] Type=notify User=www-data Group=www-data WorkingDirectory=/opt/subset-font-py Environment="PATH=/opt/subset-font-py/venv/bin" ExecStart=/opt/subset-font-py/venv/bin/uvicorn app.main:app --host 0.0.0.0 --port 8087 --workers 4 --log-level info ExecReload=/bin/kill -HUP $MAINPID Restart=always RestartSec=10 [Install] WantedBy=multi-user.target ``` 启动服务: ```bash # 重载配置 sudo systemctl daemon-reload # 启动服务 sudo systemctl start font-subset # 开机自启 sudo systemctl enable font-subset # 查看状态 sudo systemctl status font-subset ``` ### 方式三:使用 Docker 创建 `Dockerfile`: ```dockerfile FROM python:3.11-slim WORKDIR /app # 安装系统依赖 RUN apt-get update && apt-get install -y \ && rm -rf /var/lib/apt/lists/* # 复制依赖文件并安装 COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt # 复制应用代码 COPY app ./app COPY run.py . # 创建必要目录 RUN mkdir -p font temp # 暴露端口 EXPOSE 8087 # 启动命令 CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8087", "--workers", "4"] ``` 创建 `docker-compose.yml`: ```yaml version: '3.8' services: font-subset: build: . container_name: font-subset-api ports: - "8087:8087" volumes: - ./font:/app/font - ./temp:/app/temp restart: unless-stopped healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8087/health"] interval: 30s timeout: 10s retries: 3 ``` 构建并运行: ```bash # 构建镜像 docker-compose build # 启动服务 docker-compose up -d # 查看日志 docker-compose logs -f ``` ### 方式四:使用 Gunicorn + Uvicorn 对于更高性能的需求,可以使用 Gunicorn 作为进程管理器: ```bash # 安装 gunicorn pip install gunicorn # 启动服务 gunicorn app.main:app \ --workers 4 \ --worker-class uvicorn.workers.UvicornWorker \ --bind 0.0.0.0:8087 \ --log-level info \ --access-logfile - \ --error-logfile - ``` ### 配置 Nginx 反向代理 如果使用 Nginx 作为反向代理,配置示例: ```nginx upstream font_subset_backend { server 127.0.0.1:8087; } server { listen 80; server_name your-domain.com; # 可选:配置请求体大小限制(根据需要调整) client_max_body_size 10M; location / { proxy_pass http://font_subset_backend; 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 60s; proxy_send_timeout 60s; proxy_read_timeout 60s; } # 可选:启用缓存 location /api/font/subset { proxy_pass http://font_subset_backend; # 不缓存子集化请求 add_header Cache-Control "no-cache, no-store"; } } ``` ## API 使用说明 ### 获取可用字体列表 ```bash GET /api/font/list ``` 响应示例: ```json { "fonts": ["SourceHanSansCN-Regular", "NotoSansSC-Regular"], "count": 2 } ``` ### 生成字体子集 ```bash POST /api/font/subset Content-Type: application/json { "font_name": "SourceHanSansCN-Regular", "text": "你好世界" } ``` **参数说明:** | 参数 | 类型 | 必填 | 说明 | |------|------|------|------| | `font_name` | string | 否 | 字体名称(不含扩展名),默认使用配置的默认字体 | | `text` | string | 是 | 需要保留的字符(最大 10000 字符) | **响应:** TTF 格式的字体文件 ## 配置说明 项目支持通过环境变量进行配置,创建 `.env` 文件: ```bash # API 配置 API_TITLE=字体子集化 API API_VERSION=1.0.0 # 子集化配置 MAX_TEXT_LENGTH=10000 MAX_WORKERS=4 # 默认字体 DEFAULT_FONT_NAME=SourceHanSansCN-Regular ``` ## 目录结构 ``` subset-font-py/ ├── app/ │ ├── api/ # API 路由 │ │ └── font_subset.py │ ├── core/ # 核心配置 │ │ └── config.py │ ├── services/ # 业务服务 │ │ └── font_service.py │ └── main.py # FastAPI 应用入口 ├── font/ # 字体文件存放目录 ├── temp/ # 临时文件目录 ├── run.py # 启动脚本 ├── requirements.txt # Python 依赖 └── README.md # 本文档 ``` ## 安全注意事项 1. **CORS 配置**:生产环境请修改 `app/main.py` 中的 `allow_origins`,限制具体域名 2. **路径遍历防护**:已内置路径遍历攻击防护 3. **请求限制**:已配置最大字符数限制(默认 10000) 4. **并发控制**:已配置最大并发处理数(默认 4) 5. **定期清理**:建议设置 cron 任务定期清理 `temp` 目录 ## 常见问题 ### 1. 字体文件无法加载 检查字体文件是否存在于 `font` 目录,文件名是否正确。 ### 2. 临时文件占用空间 可以安全删除 `temp` 目录中的文件,或设置定期清理任务: ```bash # 添加到 crontab(每天凌晨 3 点清理) 0 3 * * * find /opt/subset-font-py/temp -type f -mtime +1 -delete ``` ### 3. 性能优化建议 - 使用 uvloop(Linux):`pip install uvloop` - 增加 worker 数量:`--workers $(($(nproc) * 2 + 1))` - 启用 HTTP/2:使用支持 HTTP/2 的服务器 ## 许可证 MIT License