resume-swallow 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- resume_swallow-0.1.0/PKG-INFO +25 -0
- resume_swallow-0.1.0/README.md +646 -0
- resume_swallow-0.1.0/pyproject.toml +39 -0
- resume_swallow-0.1.0/setup.cfg +4 -0
- resume_swallow-0.1.0/src/resume_swallow/__init__.py +1 -0
- resume_swallow-0.1.0/src/resume_swallow/cli.py +226 -0
- resume_swallow-0.1.0/src/resume_swallow/core/__init__.py +0 -0
- resume_swallow-0.1.0/src/resume_swallow/core/error_handler.py +66 -0
- resume_swallow-0.1.0/src/resume_swallow/core/pipeline.py +92 -0
- resume_swallow-0.1.0/src/resume_swallow/core/progress.py +64 -0
- resume_swallow-0.1.0/src/resume_swallow/core/scheduler.py +105 -0
- resume_swallow-0.1.0/src/resume_swallow/engine/__init__.py +0 -0
- resume_swallow-0.1.0/src/resume_swallow/engine/file_parser.py +250 -0
- resume_swallow-0.1.0/src/resume_swallow/engine/json_to_excel.py +223 -0
- resume_swallow-0.1.0/src/resume_swallow/engine/llm_formatter.py +197 -0
- resume_swallow-0.1.0/src/resume_swallow/gui/__init__.py +0 -0
- resume_swallow-0.1.0/src/resume_swallow/gui/main_window.py +410 -0
- resume_swallow-0.1.0/src/resume_swallow/gui/theme.py +115 -0
- resume_swallow-0.1.0/src/resume_swallow/infra/__init__.py +0 -0
- resume_swallow-0.1.0/src/resume_swallow/infra/api_client.py +114 -0
- resume_swallow-0.1.0/src/resume_swallow/infra/config.py +118 -0
- resume_swallow-0.1.0/src/resume_swallow/infra/file_io.py +62 -0
- resume_swallow-0.1.0/src/resume_swallow/infra/logger.py +55 -0
- resume_swallow-0.1.0/src/resume_swallow/main.py +4 -0
- resume_swallow-0.1.0/src/resume_swallow/prompts/__init__.py +0 -0
- resume_swallow-0.1.0/src/resume_swallow/prompts/format_prompt.md +90 -0
- resume_swallow-0.1.0/src/resume_swallow/web/__init__.py +0 -0
- resume_swallow-0.1.0/src/resume_swallow/web/app.py +37 -0
- resume_swallow-0.1.0/src/resume_swallow/web/exceptions.py +34 -0
- resume_swallow-0.1.0/src/resume_swallow/web/routes.py +113 -0
- resume_swallow-0.1.0/src/resume_swallow/web/state.py +213 -0
- resume_swallow-0.1.0/src/resume_swallow/web/templates/index.html +443 -0
- resume_swallow-0.1.0/src/resume_swallow.egg-info/PKG-INFO +25 -0
- resume_swallow-0.1.0/src/resume_swallow.egg-info/SOURCES.txt +43 -0
- resume_swallow-0.1.0/src/resume_swallow.egg-info/dependency_links.txt +1 -0
- resume_swallow-0.1.0/src/resume_swallow.egg-info/entry_points.txt +2 -0
- resume_swallow-0.1.0/src/resume_swallow.egg-info/requires.txt +22 -0
- resume_swallow-0.1.0/src/resume_swallow.egg-info/top_level.txt +1 -0
- resume_swallow-0.1.0/tests/test_cli.py +120 -0
- resume_swallow-0.1.0/tests/test_file_parser.py +97 -0
- resume_swallow-0.1.0/tests/test_infra.py +90 -0
- resume_swallow-0.1.0/tests/test_json_to_excel.py +242 -0
- resume_swallow-0.1.0/tests/test_llm_formatter.py +174 -0
- resume_swallow-0.1.0/tests/test_pipeline.py +165 -0
- resume_swallow-0.1.0/tests/test_web.py +238 -0
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: resume-swallow
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: 批量简历格式化工具 - 将各种格式简历转化为结构化Excel
|
|
5
|
+
Author-email: Chandler <275737875@qq.com>
|
|
6
|
+
Requires-Python: >=3.10
|
|
7
|
+
Requires-Dist: pdfplumber>=0.10.0
|
|
8
|
+
Requires-Dist: PyMuPDF>=1.23.0
|
|
9
|
+
Requires-Dist: python-docx>=1.0.0
|
|
10
|
+
Requires-Dist: beautifulsoup4>=4.12.0
|
|
11
|
+
Requires-Dist: chardet>=5.0.0
|
|
12
|
+
Requires-Dist: openpyxl>=3.1.0
|
|
13
|
+
Requires-Dist: requests>=2.31.0
|
|
14
|
+
Requires-Dist: pyyaml>=6.0
|
|
15
|
+
Requires-Dist: typer>=0.9.0
|
|
16
|
+
Requires-Dist: fastapi>=0.100.0
|
|
17
|
+
Requires-Dist: uvicorn>=0.23.0
|
|
18
|
+
Provides-Extra: ocr
|
|
19
|
+
Requires-Dist: pytesseract>=0.3.10; extra == "ocr"
|
|
20
|
+
Requires-Dist: Pillow>=10.0.0; extra == "ocr"
|
|
21
|
+
Provides-Extra: doc
|
|
22
|
+
Requires-Dist: pywin32>=306; extra == "doc"
|
|
23
|
+
Provides-Extra: dev
|
|
24
|
+
Requires-Dist: pytest>=7.0.0; extra == "dev"
|
|
25
|
+
Requires-Dist: httpx>=0.24.0; extra == "dev"
|
|
@@ -0,0 +1,646 @@
|
|
|
1
|
+
# Resume-Swallow
|
|
2
|
+
|
|
3
|
+
**批量简历格式化工具** — 将各种格式的简历文件批量转化为结构化 Excel,专为招聘 HR 设计。
|
|
4
|
+
|
|
5
|
+
[](https://www.python.org/downloads/)
|
|
6
|
+
[](#)
|
|
7
|
+
[](#)
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## 目录
|
|
12
|
+
|
|
13
|
+
- [简介](#简介)
|
|
14
|
+
- [功能特性](#功能特性)
|
|
15
|
+
- [核心流程](#核心流程)
|
|
16
|
+
- [安装](#安装)
|
|
17
|
+
- [快速开始](#快速开始)
|
|
18
|
+
- [方式一:Web 界面(推荐)](#方式一web-界面推荐)
|
|
19
|
+
- [方式二:GUI 图形界面](#方式二gui-图形界面)
|
|
20
|
+
- [方式三:CLI 命令行](#方式三cli-命令行)
|
|
21
|
+
- [配置说明](#配置说明)
|
|
22
|
+
- [CLI 命令详解](#cli-命令详解)
|
|
23
|
+
- [输出格式](#输出格式)
|
|
24
|
+
- [项目架构](#项目架构)
|
|
25
|
+
- [开发指南](#开发指南)
|
|
26
|
+
- [常见问题](#常见问题)
|
|
27
|
+
- [变更记录](#变更记录)
|
|
28
|
+
- [许可证](#许可证)
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## 简介
|
|
33
|
+
|
|
34
|
+
Resume-Swallow 是一个本地运行的批量简历处理工具,帮助招聘 HR 将杂乱的多格式简历文件(PDF、Word、TXT、HTML 等)统一提取为结构化信息,并汇总到一张 Excel 表格中。
|
|
35
|
+
|
|
36
|
+
**目标用户:** 招聘 HR、猎头、招聘团队管理者 — 需要批量处理大量简历并整理为结构化数据的人员。
|
|
37
|
+
|
|
38
|
+
**核心能力:** 多格式文件解析 → LLM 智能格式化 → 标准化 Excel 输出,一站式完成简历数据结构化。
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## 功能特性
|
|
43
|
+
|
|
44
|
+
- **多格式支持**:PDF / DOC / DOCX / TXT / MD / HTML
|
|
45
|
+
- **LLM 智能提取**:使用大语言模型将非结构化简历文本提取为结构化 JSON
|
|
46
|
+
- **批量处理**:一键处理整个文件夹,支持断点续传和强制覆盖
|
|
47
|
+
- **三种使用方式**:
|
|
48
|
+
- **Web 界面** — 浏览器中操作,支持远程访问,适合团队协作
|
|
49
|
+
- **GUI 桌面界面** — Tkinter 图形界面,适合本地单机使用
|
|
50
|
+
- **CLI 命令行** — 适合自动化脚本和批量任务
|
|
51
|
+
- **标准化 Excel 输出**:所有简历汇总到一张表格,可直接导入招聘系统
|
|
52
|
+
- **OCR 支持**:可选启用 OCR 处理图片型 PDF(扫描件)
|
|
53
|
+
- **兼容多种 LLM API**:支持 OpenAI、DeepSeek、通义千问等任何兼容 OpenAI API 格式的接口
|
|
54
|
+
- **首次使用向导**:API Key 为空时自动引导配置
|
|
55
|
+
- **本地运行**:数据不经过第三方服务器(仅 LLM API 调用)
|
|
56
|
+
- **健康检查接口**:Web 服务提供 `/health` 端点,便于监控和运维
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## 核心流程
|
|
61
|
+
|
|
62
|
+
```
|
|
63
|
+
简历文件 (PDF/DOC/DOCX/TXT/MD/HTML)
|
|
64
|
+
│
|
|
65
|
+
▼
|
|
66
|
+
TXT 文本提取 ← file_parser.py
|
|
67
|
+
│
|
|
68
|
+
▼
|
|
69
|
+
LLM 格式化 → JSON ← llm_formatter.py
|
|
70
|
+
│
|
|
71
|
+
▼
|
|
72
|
+
JSON → Excel ← json_to_excel.py
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
三步流水线:**文件解析 → LLM 格式化 → Excel 导出**。每一步都可以单独执行,也可以通过 `process` 命令一键完成。
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## 安装
|
|
80
|
+
|
|
81
|
+
### 前置要求
|
|
82
|
+
|
|
83
|
+
- Python 3.10 或更高版本
|
|
84
|
+
- 一个可用的 LLM API(如 OpenAI API 或兼容接口)
|
|
85
|
+
|
|
86
|
+
### 通过 pip 安装
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
pip install resume-swallow
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### 从源码安装
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
git clone https://github.com/your-org/resume-swallow.git
|
|
96
|
+
cd resume-swallow
|
|
97
|
+
pip install -e .
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### 可选依赖
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
# OCR 支持(处理图片型 PDF)
|
|
104
|
+
pip install resume-swallow[ocr]
|
|
105
|
+
|
|
106
|
+
# .doc 格式支持(Windows,需要 pywin32)
|
|
107
|
+
pip install resume-swallow[doc]
|
|
108
|
+
|
|
109
|
+
# 开发依赖(运行测试)
|
|
110
|
+
pip install resume-swallow[dev]
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
## 快速开始
|
|
116
|
+
|
|
117
|
+
### 方式一:Web 界面(推荐)
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
resume-swallow web
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
默认在 `http://127.0.0.1:8000` 启动 Web 服务。打开浏览器访问该地址即可使用。
|
|
124
|
+
|
|
125
|
+
**Web 界面功能:**
|
|
126
|
+
|
|
127
|
+
1. **首次使用**:如果 API Key 为空,会自动弹出配置向导对话框
|
|
128
|
+
2. **输入配置**:填写输入文件夹和输出文件夹路径
|
|
129
|
+
3. **API 配置**:填写 API Key(支持显示/隐藏切换)、API URL、Model、Timeout、SSL验证
|
|
130
|
+
4. **测试连接**:点击"测试连接"按钮验证 API 配置
|
|
131
|
+
5. **处理选项**:启用 OCR、断点续传、强制覆盖、高级设置
|
|
132
|
+
6. **高级设置**:工作/教育/项目经历条数、保存中间 TXT 文件
|
|
133
|
+
7. **开始处理**:点击"开始处理"按钮,进度条和日志实时更新
|
|
134
|
+
8. **停止处理**:处理过程中可点击"停止"按钮中断
|
|
135
|
+
|
|
136
|
+
**自定义监听地址和端口:**
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
resume-swallow web --host 0.0.0.0 --port 9000
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
`--host 0.0.0.0` 允许局域网内其他设备访问,适合团队协作场景。
|
|
143
|
+
|
|
144
|
+
### 方式二:GUI 图形界面
|
|
145
|
+
|
|
146
|
+
```bash
|
|
147
|
+
resume-swallow gui
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
打开桌面图形界面(Tkinter + ttk,Tailwind 风格主题),功能与 Web 界面完全一致。
|
|
151
|
+
|
|
152
|
+
### 方式三:CLI 命令行
|
|
153
|
+
|
|
154
|
+
#### 一键批量处理(最常用)
|
|
155
|
+
|
|
156
|
+
```bash
|
|
157
|
+
resume-swallow process ./resumes -k your-api-key
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
这会处理 `./resumes` 文件夹中的所有简历文件,自动完成"解析 → 格式化 → 导出 Excel"全流程。输出默认保存在 `./resumes_output/` 目录。
|
|
161
|
+
|
|
162
|
+
#### 分步执行
|
|
163
|
+
|
|
164
|
+
如果你只想执行某一步,可以使用单独的命令:
|
|
165
|
+
|
|
166
|
+
```bash
|
|
167
|
+
# 步骤1:仅格式化单个 TXT 文件为 JSON
|
|
168
|
+
resume-swallow format ./resumes/zhangsan.txt -k your-api-key
|
|
169
|
+
|
|
170
|
+
# 步骤2:仅将 JSON 文件夹导出为 Excel
|
|
171
|
+
resume-swallow export ./resumes_output/json
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
---
|
|
175
|
+
|
|
176
|
+
## 配置说明
|
|
177
|
+
|
|
178
|
+
配置文件位于 `~/.resume-swallow/config.yaml`(Windows 为 `%USERPROFILE%\.resume-swallow\config.yaml`)。
|
|
179
|
+
|
|
180
|
+
首次运行 `resume-swallow init` 会自动创建配置文件:
|
|
181
|
+
|
|
182
|
+
```bash
|
|
183
|
+
resume-swallow init
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
### 配置项详解
|
|
187
|
+
|
|
188
|
+
```yaml
|
|
189
|
+
llm:
|
|
190
|
+
api_key: "" # LLM API Key(必填)
|
|
191
|
+
api_url: "https://api.openai.com/v1" # API 地址(支持兼容接口)
|
|
192
|
+
model: "gpt-4" # 模型名称
|
|
193
|
+
timeout: 60 # 请求超时(秒)
|
|
194
|
+
verify_ssl: true # 是否验证 SSL 证书
|
|
195
|
+
temperature: 0.1 # 生成温度(越低越稳定)
|
|
196
|
+
|
|
197
|
+
output:
|
|
198
|
+
json_subdir: "json" # JSON 输出子目录名
|
|
199
|
+
excel_name: "resumes.xlsx" # Excel 文件名
|
|
200
|
+
save_intermediate_txt: false # 是否保存中间 TXT 文件
|
|
201
|
+
|
|
202
|
+
processing:
|
|
203
|
+
max_retries: 1 # 失败重试次数
|
|
204
|
+
force_overwrite: false # 是否强制覆盖已有输出
|
|
205
|
+
enable_ocr: false # 是否启用 OCR(图片型 PDF)
|
|
206
|
+
ocr_language: "chi_sim+eng" # OCR 语言
|
|
207
|
+
max_work_experience: 3 # 最多提取工作经历条数
|
|
208
|
+
max_education: 3 # 最多提取教育经历条数
|
|
209
|
+
max_project_experience: 3 # 最多提取项目经历条数
|
|
210
|
+
|
|
211
|
+
gui:
|
|
212
|
+
theme: "default" # GUI 主题
|
|
213
|
+
language: "zh_CN" # GUI 语言
|
|
214
|
+
show_advanced: false # 是否显示高级选项
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
### 使用兼容 API
|
|
218
|
+
|
|
219
|
+
Resume-Swallow 支持任何兼容 OpenAI API 格式的接口。只需修改 `api_url` 和 `model`:
|
|
220
|
+
|
|
221
|
+
```yaml
|
|
222
|
+
llm:
|
|
223
|
+
api_key: "your-key"
|
|
224
|
+
api_url: "https://your-api-endpoint.com/v1"
|
|
225
|
+
model: "your-model-name"
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
命令行临时覆盖:
|
|
229
|
+
|
|
230
|
+
```bash
|
|
231
|
+
resume-swallow process ./resumes -k your-key -u https://your-api.com/v1 -m your-model
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
---
|
|
235
|
+
|
|
236
|
+
## CLI 命令详解
|
|
237
|
+
|
|
238
|
+
### `process` — 批量处理简历文件夹
|
|
239
|
+
|
|
240
|
+
一键完成"解析 → 格式化 → 导出 Excel"全流程。
|
|
241
|
+
|
|
242
|
+
```bash
|
|
243
|
+
resume-swallow process <输入文件夹> [选项]
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
| 选项 | 简写 | 说明 |
|
|
247
|
+
|------|------|------|
|
|
248
|
+
| `--output` | `-o` | 输出文件夹路径(默认:输入文件夹同级 `_output` 目录) |
|
|
249
|
+
| `--api-key` | `-k` | API Key(覆盖配置文件) |
|
|
250
|
+
| `--api-url` | `-u` | API URL(覆盖配置文件) |
|
|
251
|
+
| `--model` | `-m` | LLM 模型名称(覆盖配置文件) |
|
|
252
|
+
| `--timeout` | `-t` | 请求超时秒数 |
|
|
253
|
+
| `--resume` | `-r` | 断点续传(跳过已处理的文件) |
|
|
254
|
+
| `--force` | `-f` | 强制覆盖已有输出文件 |
|
|
255
|
+
| `--enable-ocr` | | 启用 OCR(处理图片型 PDF) |
|
|
256
|
+
| `--max-retries` | | 最大重试次数 |
|
|
257
|
+
| `--verbose` | | 详细日志输出 |
|
|
258
|
+
|
|
259
|
+
**示例:**
|
|
260
|
+
|
|
261
|
+
```bash
|
|
262
|
+
# 基本用法
|
|
263
|
+
resume-swallow process ./resumes -k sk-xxx
|
|
264
|
+
|
|
265
|
+
# 断点续传 + 详细日志
|
|
266
|
+
resume-swallow process ./resumes -k sk-xxx --resume --verbose
|
|
267
|
+
|
|
268
|
+
# 自定义输出目录 + 强制覆盖
|
|
269
|
+
resume-swallow process ./resumes -k sk-xxx -o ./output --force
|
|
270
|
+
|
|
271
|
+
# 使用兼容 API
|
|
272
|
+
resume-swallow process ./resumes -k sk-xxx -u https://api.deepseek.com/v1 -m deepseek-chat
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
### `format` — 仅 TXT → JSON 格式化
|
|
276
|
+
|
|
277
|
+
将单个 TXT 文件通过 LLM 格式化为结构化 JSON。
|
|
278
|
+
|
|
279
|
+
```bash
|
|
280
|
+
resume-swallow format <输入TXT文件> [选项]
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
| 选项 | 简写 | 说明 |
|
|
284
|
+
|------|------|------|
|
|
285
|
+
| `--output` | `-o` | 输出 JSON 文件路径 |
|
|
286
|
+
| `--api-key` | `-k` | API Key |
|
|
287
|
+
| `--api-url` | `-u` | API URL |
|
|
288
|
+
| `--model` | `-m` | LLM 模型名称 |
|
|
289
|
+
| `--max-retries` | | 最大重试次数 |
|
|
290
|
+
|
|
291
|
+
### `export` — 仅 JSON → Excel 转换
|
|
292
|
+
|
|
293
|
+
将一个目录下的所有 JSON 文件合并导出为一张 Excel 表格。
|
|
294
|
+
|
|
295
|
+
```bash
|
|
296
|
+
resume-swallow export <JSON目录> [选项]
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
| 选项 | 简写 | 说明 |
|
|
300
|
+
|------|------|------|
|
|
301
|
+
| `--output` | `-o` | 输出 Excel 文件路径 |
|
|
302
|
+
|
|
303
|
+
### `init` — 初始化配置文件
|
|
304
|
+
|
|
305
|
+
```bash
|
|
306
|
+
resume-swallow init
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
在 `~/.resume-swallow/config.yaml` 创建默认配置文件。
|
|
310
|
+
|
|
311
|
+
### `gui` — 启动桌面图形界面
|
|
312
|
+
|
|
313
|
+
```bash
|
|
314
|
+
resume-swallow gui
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
启动 Tkinter 桌面 GUI(ttk + Tailwind 风格自定义主题)。
|
|
318
|
+
|
|
319
|
+
### `web` — 启动 Web 界面
|
|
320
|
+
|
|
321
|
+
```bash
|
|
322
|
+
resume-swallow web [选项]
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
| 选项 | 简写 | 说明 |
|
|
326
|
+
|------|------|------|
|
|
327
|
+
| `--host` | `-h` | 监听地址(默认:127.0.0.1) |
|
|
328
|
+
| `--port` | `-p` | 监听端口(默认:8000) |
|
|
329
|
+
|
|
330
|
+
**示例:**
|
|
331
|
+
|
|
332
|
+
```bash
|
|
333
|
+
# 默认本地访问
|
|
334
|
+
resume-swallow web
|
|
335
|
+
|
|
336
|
+
# 允许局域网访问 + 自定义端口
|
|
337
|
+
resume-swallow web --host 0.0.0.0 --port 9000
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
Web 界面使用 FastAPI 后端 + TailwindCSS/Alpine.js 前端,功能与 GUI 完全对齐。提供以下 REST API:
|
|
341
|
+
|
|
342
|
+
| 端点 | 方法 | 说明 |
|
|
343
|
+
|------|------|------|
|
|
344
|
+
| `/` | GET | Web 页面 |
|
|
345
|
+
| `/health` | GET | 健康检查 |
|
|
346
|
+
| `/api/config` | GET | 获取当前配置 |
|
|
347
|
+
| `/api/config` | POST | 更新配置 |
|
|
348
|
+
| `/api/test-api` | POST | 测试 API 连接 |
|
|
349
|
+
| `/api/process/start` | POST | 启动批量处理 |
|
|
350
|
+
| `/api/process/stop` | POST | 停止处理 |
|
|
351
|
+
| `/api/process/status` | GET | 获取处理状态和进度 |
|
|
352
|
+
|
|
353
|
+
### `test-api` — 测试 API 连接
|
|
354
|
+
|
|
355
|
+
```bash
|
|
356
|
+
resume-swallow test-api -k your-api-key
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
验证 API Key 和 URL 是否可用,避免处理大批量文件后才发现配置错误。
|
|
360
|
+
|
|
361
|
+
### `--version` — 查看版本
|
|
362
|
+
|
|
363
|
+
```bash
|
|
364
|
+
resume-swallow --version
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
---
|
|
368
|
+
|
|
369
|
+
## 输出格式
|
|
370
|
+
|
|
371
|
+
### JSON 结构
|
|
372
|
+
|
|
373
|
+
每份简历格式化为以下 JSON 结构:
|
|
374
|
+
|
|
375
|
+
```json
|
|
376
|
+
{
|
|
377
|
+
"basic_info": {
|
|
378
|
+
"recruitment_category": "社招",
|
|
379
|
+
"name": "张三",
|
|
380
|
+
"gender": "男",
|
|
381
|
+
"location": "北京市",
|
|
382
|
+
"country_code": "+86",
|
|
383
|
+
"phone": "13800138000",
|
|
384
|
+
"wechat": "zhangsan_wx",
|
|
385
|
+
"email": "zhangsan@example.com",
|
|
386
|
+
"birth_year": "1990",
|
|
387
|
+
"resume_source": "脉脉",
|
|
388
|
+
"nationality": "",
|
|
389
|
+
"qq": "",
|
|
390
|
+
"other_phone": "",
|
|
391
|
+
"resume_code": ""
|
|
392
|
+
},
|
|
393
|
+
"work_experience": [
|
|
394
|
+
{
|
|
395
|
+
"company": "XX科技有限公司",
|
|
396
|
+
"position": "高级后端工程师",
|
|
397
|
+
"career_field": "互联网/技术",
|
|
398
|
+
"department": "",
|
|
399
|
+
"start_date": "2021-03",
|
|
400
|
+
"end_date": "至今",
|
|
401
|
+
"description": ""
|
|
402
|
+
}
|
|
403
|
+
],
|
|
404
|
+
"education": [
|
|
405
|
+
{
|
|
406
|
+
"start_date": "2015-09",
|
|
407
|
+
"end_date": "2019-06",
|
|
408
|
+
"school": "北京大学",
|
|
409
|
+
"major": "计算机科学与技术",
|
|
410
|
+
"degree_level": "本科",
|
|
411
|
+
"degree": "",
|
|
412
|
+
"research_field": "",
|
|
413
|
+
"tag_3x": "",
|
|
414
|
+
"is_unified_recruitment": "是"
|
|
415
|
+
}
|
|
416
|
+
],
|
|
417
|
+
"project_experience": [],
|
|
418
|
+
"personal_tags": ["高端"],
|
|
419
|
+
"job_intention": {
|
|
420
|
+
"intended_location": "北京市",
|
|
421
|
+
"expected_salary": "30-50K",
|
|
422
|
+
"staffing": "",
|
|
423
|
+
"work_type": ""
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
```
|
|
427
|
+
|
|
428
|
+
### Excel 表格
|
|
429
|
+
|
|
430
|
+
所有简历的 JSON 数据汇总到一张 Excel 表格,每个字段一列:
|
|
431
|
+
|
|
432
|
+
- 基础信息:姓名、性别、所在地、电话、邮箱、微信等
|
|
433
|
+
- 工作经历:最多 3 段(可配置),每段含公司、职位、时间、描述
|
|
434
|
+
- 教育经历:最多 3 段(可配置),每段含学校、专业、学历、时间
|
|
435
|
+
- 项目经历:最多 3 段(可配置),每段含项目名、职位、时间、职责
|
|
436
|
+
- 个人标签:高端、稀缺、OD、五星/天才少年、应届生
|
|
437
|
+
- 求职意向:期望地点、期望薪资
|
|
438
|
+
|
|
439
|
+
---
|
|
440
|
+
|
|
441
|
+
## 项目架构
|
|
442
|
+
|
|
443
|
+
```
|
|
444
|
+
resume-swallow/
|
|
445
|
+
├── src/resume_swallow/
|
|
446
|
+
│ ├── cli.py # Typer CLI 入口(7个子命令)
|
|
447
|
+
│ ├── main.py # 模块入口点
|
|
448
|
+
│ ├── __init__.py # 版本号定义
|
|
449
|
+
│ ├── core/ # 业务编排层
|
|
450
|
+
│ │ ├── scheduler.py # 批量调度器
|
|
451
|
+
│ │ ├── pipeline.py # 单文件流水线
|
|
452
|
+
│ │ ├── error_handler.py# 错误处理
|
|
453
|
+
│ │ └── progress.py # 进度跟踪
|
|
454
|
+
│ ├── engine/ # 处理引擎层
|
|
455
|
+
│ │ ├── file_parser.py # 多格式文件 → TXT
|
|
456
|
+
│ │ ├── llm_formatter.py# TXT → JSON(LLM)
|
|
457
|
+
│ │ └── json_to_excel.py# JSON → Excel
|
|
458
|
+
│ ├── infra/ # 基础设施层
|
|
459
|
+
│ │ ├── config.py # 配置管理
|
|
460
|
+
│ │ ├── logger.py # 日志
|
|
461
|
+
│ │ ├── api_client.py # LLM API 客户端
|
|
462
|
+
│ │ └── file_io.py # 文件读写
|
|
463
|
+
│ ├── gui/ # GUI 层
|
|
464
|
+
│ │ ├── main_window.py # 主窗口(ttk + 自定义 Style)
|
|
465
|
+
│ │ └── theme.py # Tailwind 风格主题
|
|
466
|
+
│ ├── web/ # Web 层
|
|
467
|
+
│ │ ├── app.py # FastAPI 应用定义
|
|
468
|
+
│ │ ├── routes.py # REST API 端点
|
|
469
|
+
│ │ ├── state.py # 状态管理(线程安全)
|
|
470
|
+
│ │ ├── exceptions.py # 异常处理
|
|
471
|
+
│ │ └── templates/
|
|
472
|
+
│ │ └── index.html # 前端页面(TailwindCSS + Alpine.js)
|
|
473
|
+
│ └── prompts/
|
|
474
|
+
│ └── format_prompt.md# 内置 LLM Prompt 模板
|
|
475
|
+
├── config/
|
|
476
|
+
│ └── default_config.yaml # 默认配置
|
|
477
|
+
├── tests/ # 单元测试(109个)
|
|
478
|
+
│ ├── test_cli.py # CLI 命令测试
|
|
479
|
+
│ ├── test_file_parser.py # 文件解析测试
|
|
480
|
+
│ ├── test_infra.py # 基础设施测试
|
|
481
|
+
│ ├── test_json_to_excel.py# Excel 导出测试
|
|
482
|
+
│ ├── test_llm_formatter.py# LLM 格式化测试
|
|
483
|
+
│ ├── test_pipeline.py # 流水线测试
|
|
484
|
+
│ └── test_web.py # Web API 测试
|
|
485
|
+
├── docs/ # 设计文档
|
|
486
|
+
├── pyproject.toml # 打包配置
|
|
487
|
+
├── requirements.txt # 依赖列表
|
|
488
|
+
└── CHANGELOG.md # 变更记录
|
|
489
|
+
```
|
|
490
|
+
|
|
491
|
+
四层架构:**GUI/Web → Core → Engine → Infra**,每层只依赖下层,职责清晰。
|
|
492
|
+
|
|
493
|
+
- **GUI/Web 层**:用户交互(桌面 GUI 和 Web 界面)
|
|
494
|
+
- **Core 层**:业务编排(批量调度、流水线、进度、错误处理)
|
|
495
|
+
- **Engine 层**:处理引擎(文件解析、LLM 格式化、Excel 导出)
|
|
496
|
+
- **Infra 层**:基础设施(配置、日志、API 客户端、文件 IO)
|
|
497
|
+
|
|
498
|
+
---
|
|
499
|
+
|
|
500
|
+
## 开发指南
|
|
501
|
+
|
|
502
|
+
### 环境搭建
|
|
503
|
+
|
|
504
|
+
```bash
|
|
505
|
+
git clone https://github.com/your-org/resume-swallow.git
|
|
506
|
+
cd resume-swallow
|
|
507
|
+
pip install -e ".[dev]"
|
|
508
|
+
```
|
|
509
|
+
|
|
510
|
+
### 运行测试
|
|
511
|
+
|
|
512
|
+
```bash
|
|
513
|
+
pytest
|
|
514
|
+
```
|
|
515
|
+
|
|
516
|
+
109 个测试覆盖 CLI 命令、文件解析、LLM 格式化、JSON 导出、流水线、基础设施、Web API 等模块。
|
|
517
|
+
|
|
518
|
+
### 代码结构约定
|
|
519
|
+
|
|
520
|
+
- **新增 CLI 命令**:在 `cli.py` 中添加 `@app.command()` 函数
|
|
521
|
+
- **新增文件格式支持**:在 `engine/file_parser.py` 中扩展 `SUPPORTED_FORMATS`
|
|
522
|
+
- **修改 LLM Prompt**:编辑 `src/resume_swallow/prompts/format_prompt.md`
|
|
523
|
+
- **修改输出字段**:同步修改 Prompt 模板和 `engine/json_to_excel.py`
|
|
524
|
+
- **新增 Web API 端点**:在 `web/routes.py` 中添加路由函数
|
|
525
|
+
- **修改前端页面**:编辑 `web/templates/index.html`(TailwindCSS + Alpine.js)
|
|
526
|
+
|
|
527
|
+
### 提交规范
|
|
528
|
+
|
|
529
|
+
- 提交前确保所有测试通过:`pytest`
|
|
530
|
+
- 提交信息格式:`<type>: <description>`(如 `feat: 新增 web 子命令`、`fix: 修复 GUI 方法名错误`)
|
|
531
|
+
- 类型:`feat`(新功能)、`fix`(修复)、`refactor`(重构)、`test`(测试)、`docs`(文档)
|
|
532
|
+
|
|
533
|
+
### 技术栈
|
|
534
|
+
|
|
535
|
+
| 层 | 技术 |
|
|
536
|
+
|------|------|
|
|
537
|
+
| CLI | Typer |
|
|
538
|
+
| GUI | Tkinter + ttk(自定义 Tailwind 风格 Style) |
|
|
539
|
+
| Web 后端 | FastAPI + uvicorn |
|
|
540
|
+
| Web 前端 | TailwindCSS + Alpine.js |
|
|
541
|
+
| 文件解析 | pdfplumber、PyMuPDF、python-docx、beautifulsoup4 |
|
|
542
|
+
| Excel | openpyxl |
|
|
543
|
+
| LLM | requests(兼容 OpenAI API 格式) |
|
|
544
|
+
| 配置 | YAML(pyyaml) |
|
|
545
|
+
| 测试 | pytest + httpx(Web API 测试) |
|
|
546
|
+
|
|
547
|
+
---
|
|
548
|
+
|
|
549
|
+
## 常见问题
|
|
550
|
+
|
|
551
|
+
### Q: 处理 PDF 时报错"无法提取文本"
|
|
552
|
+
|
|
553
|
+
部分 PDF 是扫描图片而非文本型 PDF。使用 `--enable-ocr` 选项启用 OCR 支持(需安装 `resume-swallow[ocr]`):
|
|
554
|
+
|
|
555
|
+
```bash
|
|
556
|
+
resume-swallow process ./resumes -k sk-xxx --enable-ocr
|
|
557
|
+
```
|
|
558
|
+
|
|
559
|
+
### Q: LLM API 调用失败
|
|
560
|
+
|
|
561
|
+
先用 `test-api` 命令验证连接:
|
|
562
|
+
|
|
563
|
+
```bash
|
|
564
|
+
resume-swallow test-api -k sk-xxx -u https://api.openai.com/v1
|
|
565
|
+
```
|
|
566
|
+
|
|
567
|
+
常见原因:API Key 错误、API URL 不正确、网络超时(尝试增加 `--timeout`)。
|
|
568
|
+
|
|
569
|
+
### Q: 处理大量文件时中途失败
|
|
570
|
+
|
|
571
|
+
使用 `--resume` 选项断点续传,已成功处理的文件会被跳过:
|
|
572
|
+
|
|
573
|
+
```bash
|
|
574
|
+
resume-swallow process ./resumes -k sk-xxx --resume
|
|
575
|
+
```
|
|
576
|
+
|
|
577
|
+
### Q: 如何使用国产 LLM API
|
|
578
|
+
|
|
579
|
+
修改 `api_url` 和 `model` 即可,只要接口兼容 OpenAI API 格式:
|
|
580
|
+
|
|
581
|
+
```bash
|
|
582
|
+
# DeepSeek
|
|
583
|
+
resume-swallow process ./resumes -k sk-xxx -u https://api.deepseek.com/v1 -m deepseek-chat
|
|
584
|
+
|
|
585
|
+
# 通义千问
|
|
586
|
+
resume-swallow process ./resumes -k sk-xxx -u https://dashscope.aliyuncs.com/compatible-mode/v1 -m qwen-plus
|
|
587
|
+
```
|
|
588
|
+
|
|
589
|
+
### Q: .doc 格式文件无法解析
|
|
590
|
+
|
|
591
|
+
`.doc`(旧版 Word 格式)需要 Windows 环境和 pywin32。安装:
|
|
592
|
+
|
|
593
|
+
```bash
|
|
594
|
+
pip install resume-swallow[doc]
|
|
595
|
+
```
|
|
596
|
+
|
|
597
|
+
### Q: Web 服务无法远程访问
|
|
598
|
+
|
|
599
|
+
默认监听 `127.0.0.1`(仅本地)。使用 `--host 0.0.0.0` 允许局域网访问:
|
|
600
|
+
|
|
601
|
+
```bash
|
|
602
|
+
resume-swallow web --host 0.0.0.0
|
|
603
|
+
```
|
|
604
|
+
|
|
605
|
+
注意:确保防火墙允许对应端口访问。
|
|
606
|
+
|
|
607
|
+
### Q: Web 服务的健康检查端点是什么
|
|
608
|
+
|
|
609
|
+
```bash
|
|
610
|
+
curl http://127.0.0.1:8000/health
|
|
611
|
+
# 返回: {"status": "ok", "version": "0.2.0"}
|
|
612
|
+
```
|
|
613
|
+
|
|
614
|
+
可用于容器编排、负载均衡等场景的健康探测。
|
|
615
|
+
|
|
616
|
+
---
|
|
617
|
+
|
|
618
|
+
## 变更记录
|
|
619
|
+
|
|
620
|
+
详见 [CHANGELOG.md](CHANGELOG.md)。
|
|
621
|
+
|
|
622
|
+
---
|
|
623
|
+
|
|
624
|
+
## 许可证
|
|
625
|
+
|
|
626
|
+
MIT License
|
|
627
|
+
|
|
628
|
+
Copyright (c) 2026 Resume-Swallow Contributors
|
|
629
|
+
|
|
630
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
631
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
632
|
+
in the Software without restriction, including without limitation the rights
|
|
633
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
634
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
635
|
+
furnished to do so, subject to the following conditions:
|
|
636
|
+
|
|
637
|
+
The above copyright notice and this permission notice shall be included in all
|
|
638
|
+
copies or substantial portions of the Software.
|
|
639
|
+
|
|
640
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
641
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
642
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
643
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
644
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
645
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
646
|
+
SOFTWARE.
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61.0"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "resume-swallow"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "批量简历格式化工具 - 将各种格式简历转化为结构化Excel"
|
|
9
|
+
authors = [
|
|
10
|
+
{name = "Chandler", email = "275737875@qq.com"},
|
|
11
|
+
]
|
|
12
|
+
requires-python = ">=3.10"
|
|
13
|
+
dependencies = [
|
|
14
|
+
"pdfplumber>=0.10.0",
|
|
15
|
+
"PyMuPDF>=1.23.0",
|
|
16
|
+
"python-docx>=1.0.0",
|
|
17
|
+
"beautifulsoup4>=4.12.0",
|
|
18
|
+
"chardet>=5.0.0",
|
|
19
|
+
"openpyxl>=3.1.0",
|
|
20
|
+
"requests>=2.31.0",
|
|
21
|
+
"pyyaml>=6.0",
|
|
22
|
+
"typer>=0.9.0",
|
|
23
|
+
"fastapi>=0.100.0",
|
|
24
|
+
"uvicorn>=0.23.0",
|
|
25
|
+
]
|
|
26
|
+
|
|
27
|
+
[project.optional-dependencies]
|
|
28
|
+
ocr = ["pytesseract>=0.3.10", "Pillow>=10.0.0"]
|
|
29
|
+
doc = ["pywin32>=306"]
|
|
30
|
+
dev = ["pytest>=7.0.0", "httpx>=0.24.0"]
|
|
31
|
+
|
|
32
|
+
[project.scripts]
|
|
33
|
+
resume-swallow = "resume_swallow.cli:app"
|
|
34
|
+
|
|
35
|
+
[tool.setuptools.package-data]
|
|
36
|
+
resume_swallow = ["prompts/*.md", "web/templates/*.html"]
|
|
37
|
+
|
|
38
|
+
[tool.setuptools.packages.find]
|
|
39
|
+
where = ["src"]
|