multi-ocr-py 0.2.1__tar.gz → 0.2.3__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.
Files changed (41) hide show
  1. multi_ocr_py-0.2.3/PKG-INFO +265 -0
  2. multi_ocr_py-0.2.3/README.md +239 -0
  3. {multi_ocr_py-0.2.1 → multi_ocr_py-0.2.3}/release.sh +2 -2
  4. {multi_ocr_py-0.2.1 → multi_ocr_py-0.2.3}/src/multi_ocr/__init__.py +1 -1
  5. {multi_ocr_py-0.2.1 → multi_ocr_py-0.2.3}/src/multi_ocr/cli.py +23 -32
  6. {multi_ocr_py-0.2.1 → multi_ocr_py-0.2.3}/uv.lock +0 -1
  7. multi_ocr_py-0.2.1/PKG-INFO +0 -129
  8. multi_ocr_py-0.2.1/README.md +0 -103
  9. {multi_ocr_py-0.2.1 → multi_ocr_py-0.2.3}/.gitignore +0 -0
  10. {multi_ocr_py-0.2.1 → multi_ocr_py-0.2.3}/.python-version +0 -0
  11. {multi_ocr_py-0.2.1 → multi_ocr_py-0.2.3}/LICENSE +0 -0
  12. {multi_ocr_py-0.2.1 → multi_ocr_py-0.2.3}/docs/liteparse/Markdown-Output.md +0 -0
  13. {multi_ocr_py-0.2.1 → multi_ocr_py-0.2.3}/docs/liteparse/library-use.md +0 -0
  14. {multi_ocr_py-0.2.1 → multi_ocr_py-0.2.3}/docs/liteparse/ocr-config.md +0 -0
  15. {multi_ocr_py-0.2.1 → multi_ocr_py-0.2.3}/docs/superpowers/specs/2026-07-15-batch-pdf-concurrency-design.md +0 -0
  16. {multi_ocr_py-0.2.1 → multi_ocr_py-0.2.3}/docs/superpowers/specs/2026-07-15-batch-processing-design.md +0 -0
  17. {multi_ocr_py-0.2.1 → multi_ocr_py-0.2.3}/docs/superpowers/specs/2026-07-15-cli-args-design.md +0 -0
  18. {multi_ocr_py-0.2.1 → multi_ocr_py-0.2.3}/docs/superpowers/specs/2026-07-15-concurrency-design.md +0 -0
  19. {multi_ocr_py-0.2.1 → multi_ocr_py-0.2.3}/docs/superpowers/specs/2026-07-15-engine-refactor-design.md +0 -0
  20. {multi_ocr_py-0.2.1 → multi_ocr_py-0.2.3}/docs/superpowers/specs/2026-07-15-liteparse-engine-design.md +0 -0
  21. {multi_ocr_py-0.2.1 → multi_ocr_py-0.2.3}/docs/superpowers/specs/2026-07-15-model-shorthand-design.md +0 -0
  22. {multi_ocr_py-0.2.1 → multi_ocr_py-0.2.3}/docs/superpowers/specs/2026-07-15-multi-ocr-design.md +0 -0
  23. {multi_ocr_py-0.2.1 → multi_ocr_py-0.2.3}/docs/superpowers/specs/2026-07-15-ollama-engine-design.md +0 -0
  24. {multi_ocr_py-0.2.1 → multi_ocr_py-0.2.3}/docs/superpowers/specs/2026-07-15-pdf-progress-design.md +0 -0
  25. {multi_ocr_py-0.2.1 → multi_ocr_py-0.2.3}/docs/superpowers/specs/2026-07-16-src-package-restructure-design.md +0 -0
  26. {multi_ocr_py-0.2.1 → multi_ocr_py-0.2.3}/pyproject.toml +0 -0
  27. {multi_ocr_py-0.2.1 → multi_ocr_py-0.2.3}/src/multi_ocr/batch.py +0 -0
  28. {multi_ocr_py-0.2.1 → multi_ocr_py-0.2.3}/src/multi_ocr/engines/__init__.py +0 -0
  29. {multi_ocr_py-0.2.1 → multi_ocr_py-0.2.3}/src/multi_ocr/engines/base.py +0 -0
  30. {multi_ocr_py-0.2.1 → multi_ocr_py-0.2.3}/src/multi_ocr/engines/liteparse.py +0 -0
  31. {multi_ocr_py-0.2.1 → multi_ocr_py-0.2.3}/src/multi_ocr/engines/ollama.py +0 -0
  32. {multi_ocr_py-0.2.1 → multi_ocr_py-0.2.3}/src/multi_ocr/engines/siliconflow.py +0 -0
  33. {multi_ocr_py-0.2.1 → multi_ocr_py-0.2.3}/src/multi_ocr/pdf_utils.py +0 -0
  34. {multi_ocr_py-0.2.1 → multi_ocr_py-0.2.3}/src/multi_ocr/single.py +0 -0
  35. {multi_ocr_py-0.2.1 → multi_ocr_py-0.2.3}/tests/1.jpg +0 -0
  36. {multi_ocr_py-0.2.1 → multi_ocr_py-0.2.3}/tests/2.pdf +0 -0
  37. {multi_ocr_py-0.2.1 → multi_ocr_py-0.2.3}/tests/conftest.py +0 -0
  38. {multi_ocr_py-0.2.1 → multi_ocr_py-0.2.3}/tests/test_batch.py +0 -0
  39. {multi_ocr_py-0.2.1 → multi_ocr_py-0.2.3}/tests/test_engines.py +0 -0
  40. {multi_ocr_py-0.2.1 → multi_ocr_py-0.2.3}/tests/test_pdf_utils.py +0 -0
  41. {multi_ocr_py-0.2.1 → multi_ocr_py-0.2.3}/tests/test_single.py +0 -0
@@ -0,0 +1,265 @@
1
+ Metadata-Version: 2.4
2
+ Name: multi-ocr-py
3
+ Version: 0.2.3
4
+ Summary: 多引擎 OCR 工具包:将 PDF 和图片转换为 Markdown,支持 CLI 全局安装和 SDK 依赖两种使用方式
5
+ Project-URL: Repository, https://github.com/BlackBoxRecorder/multi-ocr
6
+ Author-email: Yinnan <im.yinnan@outlook.com>
7
+ License-Expression: MIT
8
+ License-File: LICENSE
9
+ Keywords: cli,markdown,ocr,pdf,vision-language-model
10
+ Classifier: Development Status :: 3 - Alpha
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: License :: OSI Approved :: MIT License
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3.11
15
+ Classifier: Programming Language :: Python :: 3.12
16
+ Classifier: Programming Language :: Python :: 3.13
17
+ Classifier: Topic :: Scientific/Engineering :: Image Recognition
18
+ Classifier: Topic :: Text Processing :: Markup :: Markdown
19
+ Requires-Python: >=3.11
20
+ Requires-Dist: liteparse
21
+ Requires-Dist: ollama
22
+ Requires-Dist: openai>=2.45.0
23
+ Requires-Dist: pymupdf>=1.28.0
24
+ Requires-Dist: tqdm>=4.67.0
25
+ Description-Content-Type: text/markdown
26
+
27
+ # multi-ocr-py
28
+
29
+ 多引擎 OCR 工具包,将 PDF 和图片转换为 Markdown 文档。
30
+
31
+ - **CLI 工具**:全局安装后一行命令完成 OCR
32
+ - **SDK 依赖**:作为 Python 库集成到你的项目中
33
+
34
+ ## 支持的引擎
35
+
36
+ | 引擎 | 说明 | 类型 | 场景 | 费用 |
37
+ |---|---|---|---|---|
38
+ | SiliconFlow + DeepSeek-OCR | 云端 OCR,精度高 | API | 图片+PDF | 免费 |
39
+ | SiliconFlow + PaddleOCR-VL-1.5 | 云端 OCR,轻量快速 | API | 图片+PDF | 免费 |
40
+ | LiteParse | 本地 PDF 解析,无需联网 | 本地 | PDF | 免费 |
41
+ | Ollama + DeepSeek-OCR | 本地部署 OCR | 本地 | 图片+PDF | 免费 |
42
+
43
+
44
+ > SiliconFlow 目前提供显示免费的 DeepSeek-OCR、PaddleOCR-VL-1.5 模型调用
45
+
46
+
47
+ > 本地运行 Ollama + DeepSeek-OCR 参考:https://ollama.com/library/deepseek-ocr
48
+ > 实测笔记本使用 NVIDIA RTX3060(6GB) 显卡即可流畅使用 Ollama + DeepSeek-OCR
49
+
50
+
51
+ ## 安装
52
+
53
+ ### CLI 全局安装
54
+
55
+ ```bash
56
+ uv tool install multi-ocr-py
57
+ # 或
58
+ pip install multi-ocr-py
59
+ ```
60
+
61
+ ### SDK 依赖安装
62
+
63
+ ```bash
64
+ pip install multi-ocr-py
65
+ # 或
66
+ uv add multi-ocr-py
67
+ ```
68
+
69
+ ## CLI 使用
70
+
71
+ ```bash
72
+ # 单文件 OCR
73
+ multi-ocr document.pdf
74
+
75
+ # 指定引擎和页码范围
76
+ multi-ocr document.pdf --model liteparse --pages 1-5
77
+
78
+ # 批量处理目录,4个并发
79
+ multi-ocr ./scans/ --model deepseek -j 4
80
+
81
+ # 查看帮助
82
+ multi-ocr -h
83
+ ```
84
+
85
+ **可以使用 `--model` 参数指定模型:**
86
+
87
+ ```bash
88
+ # SiliconFlow + DeepSeek-OCR
89
+ multi-ocr document.pdf --model deepseek
90
+
91
+ # SiliconFlow + PaddleOCR-VL-1.5
92
+ multi-ocr document.pdf --model paddle
93
+
94
+ # LiteParse
95
+ multi-ocr document.pdf --model liteparse
96
+
97
+ # Ollama + DeepSeek-OCR
98
+ multi-ocr document.pdf --model ollama
99
+
100
+ ```
101
+
102
+
103
+ ### 环境变量配置
104
+
105
+ 使用前需要配置以下环境变量:
106
+
107
+ | 引擎 | 环境变量 | 必需 | 说明 |
108
+ |---|---|---|---|
109
+ | SiliconFlow | `SILICONFLOW_API_KEY` | ✅ | API Key |
110
+ | Ollama | `OLLAMA_BASE_URL` | ❌ | 服务地址,默认 http://127.0.0.1:11434 |
111
+
112
+ ```bash
113
+ # 设置 SiliconFlow API Key
114
+ export SILICONFLOW_API_KEY="your-api-key"
115
+
116
+ # 可选:设置 Ollama 服务地址
117
+ export OLLAMA_BASE_URL="http://192.168.1.100:11434"
118
+ ```
119
+
120
+
121
+ ## SDK 使用
122
+
123
+ ### 快速开始
124
+
125
+ ```python
126
+ from pathlib import Path
127
+ from multi_ocr import get_engine, ocr_file, ocr_directory
128
+
129
+ # 创建引擎(provider 可选: siliconflow / liteparse / ollama)
130
+ engine = get_engine(
131
+ provider="siliconflow",
132
+ model="deepseek-ai/DeepSeek-OCR",
133
+ api_key="your-api-key",
134
+ )
135
+
136
+ # 识别单张图片
137
+ text = engine.parse_image(Path("scan.jpg"))
138
+
139
+ # 识别 PDF 单文件,指定页码范围
140
+ result = ocr_file(Path("document.pdf"), engine, pages="1-3")
141
+
142
+ # 批量处理目录(图片或 PDF)
143
+ ocr_directory(Path("./scans/"), engine, concurrency=4)
144
+ ```
145
+
146
+ ### API 参考
147
+
148
+ #### `get_engine(provider, model, api_key, base_url=None)` → `OCREngine`
149
+
150
+ 创建 OCR 引擎实例。
151
+
152
+ | 参数 | 类型 | 说明 |
153
+ |---|---|---|
154
+ | `provider` | `str` | 引擎提供商:`"siliconflow"` / `"liteparse"` / `"ollama"` |
155
+ | `model` | `str` | 模型名称,如 `"deepseek-ai/DeepSeek-OCR"` |
156
+ | `api_key` | `str` | API 密钥(本地引擎可传空字符串) |
157
+ | `base_url` | `str \| None` | 自定义 API 地址(仅 ollama 引擎使用) |
158
+
159
+ ```python
160
+ # SiliconFlow + DeepSeek-OCR
161
+ engine = get_engine("siliconflow", "deepseek-ai/DeepSeek-OCR", api_key="sk-xxx")
162
+
163
+ # LiteParse(本地,无需 API Key)
164
+ engine = get_engine("liteparse", "", api_key="")
165
+
166
+ # Ollama + DeepSeek-OCR(本地)
167
+ engine = get_engine("ollama", "deepseek-ocr:latest", api_key="", base_url="http://127.0.0.1:11434")
168
+ ```
169
+
170
+ #### `engine.parse_image(image_path)` → `str`
171
+
172
+ 对单张图片进行 OCR,返回 Markdown 文本。
173
+
174
+ | 参数 | 类型 | 说明 |
175
+ |---|---|---|
176
+ | `image_path` | `Path` | 图片文件路径(支持 .png / .jpg / .jpeg) |
177
+
178
+ ```python
179
+ from pathlib import Path
180
+ text = engine.parse_image(Path("photo.jpg"))
181
+ ```
182
+
183
+ #### `engine.parse_pdf(pdf_path, pages=None, concurrency=1)` → `str`
184
+
185
+ 解析 PDF 文件,返回 Markdown 文本。默认实现会拆页后调用 `parse_image()`,子类可覆盖(如 LiteParse 原生解析)。
186
+
187
+ | 参数 | 类型 | 说明 |
188
+ |---|---|---|
189
+ | `pdf_path` | `Path` | PDF 文件路径 |
190
+ | `pages` | `str \| None` | 页码范围,如 `"1-3,5"`,`None` 表示全部 |
191
+ | `concurrency` | `int` | 并发数,默认 1(串行),>1 时使用线程池 |
192
+
193
+ ```python
194
+ from pathlib import Path
195
+ # 解析全部页面
196
+ result = engine.parse_pdf(Path("doc.pdf"))
197
+
198
+ # 解析指定页面,4 并发
199
+ result = engine.parse_pdf(Path("doc.pdf"), pages="1-5", concurrency=4)
200
+ ```
201
+
202
+ #### `ocr_file(input_path, engine, pages=None, concurrency=1)` → `str`
203
+
204
+ 对单个文件执行 OCR 并保存为 `.md` 文件。自动判断图片/PDF。
205
+
206
+ | 参数 | 类型 | 说明 |
207
+ |---|---|---|
208
+ | `input_path` | `Path` | 输入文件路径(PDF 或图片) |
209
+ | `engine` | `OCREngine` | OCR 引擎实例 |
210
+ | `pages` | `str \| None` | 页码范围(仅 PDF 有效) |
211
+ | `concurrency` | `int` | 并发数,默认 1 |
212
+
213
+ ```python
214
+ from pathlib import Path
215
+ from multi_ocr import ocr_file
216
+
217
+ # 自动输出到同目录下的 .md 文件
218
+ result = ocr_file(Path("document.pdf"), engine, pages="1-3")
219
+ # → 已保存: document.md
220
+ ```
221
+
222
+ #### `ocr_directory(input_dir, engine, concurrency=1)` → `None`
223
+
224
+ 批量处理目录下的图片或 PDF 文件。目录下只能有一种类型(全图片或全 PDF)。
225
+
226
+ | 参数 | 类型 | 说明 |
227
+ |---|---|---|
228
+ | `input_dir` | `Path` | 输入目录路径 |
229
+ | `engine` | `OCREngine` | OCR 引擎实例 |
230
+ | `concurrency` | `int` | 并发数,默认 1 |
231
+
232
+ ```python
233
+ from pathlib import Path
234
+ from multi_ocr import ocr_directory
235
+
236
+ # 图片批量 → 输出 scans.md
237
+ ocr_directory(Path("./scans/"), engine, concurrency=4)
238
+
239
+ # PDF 批量 → 每个 PDF 各自输出 .md
240
+ ocr_directory(Path("./pdfs/"), engine)
241
+ ```
242
+
243
+ ### 自定义引擎
244
+
245
+ 继承 `OCREngine` 实现自定义 OCR 引擎:
246
+
247
+ ```python
248
+ from pathlib import Path
249
+ from multi_ocr import OCREngine
250
+
251
+ class MyEngine(OCREngine):
252
+ def parse_image(self, image_path: Path) -> str:
253
+ # 你的 OCR 逻辑
254
+ return "recognized text"
255
+
256
+ # parse_pdf 可选覆盖,默认实现会拆页后调用 parse_image()
257
+ ```
258
+
259
+ ## 要求
260
+
261
+ - Python >= 3.11
262
+
263
+ ## 协议
264
+
265
+ MIT License
@@ -0,0 +1,239 @@
1
+ # multi-ocr-py
2
+
3
+ 多引擎 OCR 工具包,将 PDF 和图片转换为 Markdown 文档。
4
+
5
+ - **CLI 工具**:全局安装后一行命令完成 OCR
6
+ - **SDK 依赖**:作为 Python 库集成到你的项目中
7
+
8
+ ## 支持的引擎
9
+
10
+ | 引擎 | 说明 | 类型 | 场景 | 费用 |
11
+ |---|---|---|---|---|
12
+ | SiliconFlow + DeepSeek-OCR | 云端 OCR,精度高 | API | 图片+PDF | 免费 |
13
+ | SiliconFlow + PaddleOCR-VL-1.5 | 云端 OCR,轻量快速 | API | 图片+PDF | 免费 |
14
+ | LiteParse | 本地 PDF 解析,无需联网 | 本地 | PDF | 免费 |
15
+ | Ollama + DeepSeek-OCR | 本地部署 OCR | 本地 | 图片+PDF | 免费 |
16
+
17
+
18
+ > SiliconFlow 目前提供显示免费的 DeepSeek-OCR、PaddleOCR-VL-1.5 模型调用
19
+
20
+
21
+ > 本地运行 Ollama + DeepSeek-OCR 参考:https://ollama.com/library/deepseek-ocr
22
+ > 实测笔记本使用 NVIDIA RTX3060(6GB) 显卡即可流畅使用 Ollama + DeepSeek-OCR
23
+
24
+
25
+ ## 安装
26
+
27
+ ### CLI 全局安装
28
+
29
+ ```bash
30
+ uv tool install multi-ocr-py
31
+ # 或
32
+ pip install multi-ocr-py
33
+ ```
34
+
35
+ ### SDK 依赖安装
36
+
37
+ ```bash
38
+ pip install multi-ocr-py
39
+ # 或
40
+ uv add multi-ocr-py
41
+ ```
42
+
43
+ ## CLI 使用
44
+
45
+ ```bash
46
+ # 单文件 OCR
47
+ multi-ocr document.pdf
48
+
49
+ # 指定引擎和页码范围
50
+ multi-ocr document.pdf --model liteparse --pages 1-5
51
+
52
+ # 批量处理目录,4个并发
53
+ multi-ocr ./scans/ --model deepseek -j 4
54
+
55
+ # 查看帮助
56
+ multi-ocr -h
57
+ ```
58
+
59
+ **可以使用 `--model` 参数指定模型:**
60
+
61
+ ```bash
62
+ # SiliconFlow + DeepSeek-OCR
63
+ multi-ocr document.pdf --model deepseek
64
+
65
+ # SiliconFlow + PaddleOCR-VL-1.5
66
+ multi-ocr document.pdf --model paddle
67
+
68
+ # LiteParse
69
+ multi-ocr document.pdf --model liteparse
70
+
71
+ # Ollama + DeepSeek-OCR
72
+ multi-ocr document.pdf --model ollama
73
+
74
+ ```
75
+
76
+
77
+ ### 环境变量配置
78
+
79
+ 使用前需要配置以下环境变量:
80
+
81
+ | 引擎 | 环境变量 | 必需 | 说明 |
82
+ |---|---|---|---|
83
+ | SiliconFlow | `SILICONFLOW_API_KEY` | ✅ | API Key |
84
+ | Ollama | `OLLAMA_BASE_URL` | ❌ | 服务地址,默认 http://127.0.0.1:11434 |
85
+
86
+ ```bash
87
+ # 设置 SiliconFlow API Key
88
+ export SILICONFLOW_API_KEY="your-api-key"
89
+
90
+ # 可选:设置 Ollama 服务地址
91
+ export OLLAMA_BASE_URL="http://192.168.1.100:11434"
92
+ ```
93
+
94
+
95
+ ## SDK 使用
96
+
97
+ ### 快速开始
98
+
99
+ ```python
100
+ from pathlib import Path
101
+ from multi_ocr import get_engine, ocr_file, ocr_directory
102
+
103
+ # 创建引擎(provider 可选: siliconflow / liteparse / ollama)
104
+ engine = get_engine(
105
+ provider="siliconflow",
106
+ model="deepseek-ai/DeepSeek-OCR",
107
+ api_key="your-api-key",
108
+ )
109
+
110
+ # 识别单张图片
111
+ text = engine.parse_image(Path("scan.jpg"))
112
+
113
+ # 识别 PDF 单文件,指定页码范围
114
+ result = ocr_file(Path("document.pdf"), engine, pages="1-3")
115
+
116
+ # 批量处理目录(图片或 PDF)
117
+ ocr_directory(Path("./scans/"), engine, concurrency=4)
118
+ ```
119
+
120
+ ### API 参考
121
+
122
+ #### `get_engine(provider, model, api_key, base_url=None)` → `OCREngine`
123
+
124
+ 创建 OCR 引擎实例。
125
+
126
+ | 参数 | 类型 | 说明 |
127
+ |---|---|---|
128
+ | `provider` | `str` | 引擎提供商:`"siliconflow"` / `"liteparse"` / `"ollama"` |
129
+ | `model` | `str` | 模型名称,如 `"deepseek-ai/DeepSeek-OCR"` |
130
+ | `api_key` | `str` | API 密钥(本地引擎可传空字符串) |
131
+ | `base_url` | `str \| None` | 自定义 API 地址(仅 ollama 引擎使用) |
132
+
133
+ ```python
134
+ # SiliconFlow + DeepSeek-OCR
135
+ engine = get_engine("siliconflow", "deepseek-ai/DeepSeek-OCR", api_key="sk-xxx")
136
+
137
+ # LiteParse(本地,无需 API Key)
138
+ engine = get_engine("liteparse", "", api_key="")
139
+
140
+ # Ollama + DeepSeek-OCR(本地)
141
+ engine = get_engine("ollama", "deepseek-ocr:latest", api_key="", base_url="http://127.0.0.1:11434")
142
+ ```
143
+
144
+ #### `engine.parse_image(image_path)` → `str`
145
+
146
+ 对单张图片进行 OCR,返回 Markdown 文本。
147
+
148
+ | 参数 | 类型 | 说明 |
149
+ |---|---|---|
150
+ | `image_path` | `Path` | 图片文件路径(支持 .png / .jpg / .jpeg) |
151
+
152
+ ```python
153
+ from pathlib import Path
154
+ text = engine.parse_image(Path("photo.jpg"))
155
+ ```
156
+
157
+ #### `engine.parse_pdf(pdf_path, pages=None, concurrency=1)` → `str`
158
+
159
+ 解析 PDF 文件,返回 Markdown 文本。默认实现会拆页后调用 `parse_image()`,子类可覆盖(如 LiteParse 原生解析)。
160
+
161
+ | 参数 | 类型 | 说明 |
162
+ |---|---|---|
163
+ | `pdf_path` | `Path` | PDF 文件路径 |
164
+ | `pages` | `str \| None` | 页码范围,如 `"1-3,5"`,`None` 表示全部 |
165
+ | `concurrency` | `int` | 并发数,默认 1(串行),>1 时使用线程池 |
166
+
167
+ ```python
168
+ from pathlib import Path
169
+ # 解析全部页面
170
+ result = engine.parse_pdf(Path("doc.pdf"))
171
+
172
+ # 解析指定页面,4 并发
173
+ result = engine.parse_pdf(Path("doc.pdf"), pages="1-5", concurrency=4)
174
+ ```
175
+
176
+ #### `ocr_file(input_path, engine, pages=None, concurrency=1)` → `str`
177
+
178
+ 对单个文件执行 OCR 并保存为 `.md` 文件。自动判断图片/PDF。
179
+
180
+ | 参数 | 类型 | 说明 |
181
+ |---|---|---|
182
+ | `input_path` | `Path` | 输入文件路径(PDF 或图片) |
183
+ | `engine` | `OCREngine` | OCR 引擎实例 |
184
+ | `pages` | `str \| None` | 页码范围(仅 PDF 有效) |
185
+ | `concurrency` | `int` | 并发数,默认 1 |
186
+
187
+ ```python
188
+ from pathlib import Path
189
+ from multi_ocr import ocr_file
190
+
191
+ # 自动输出到同目录下的 .md 文件
192
+ result = ocr_file(Path("document.pdf"), engine, pages="1-3")
193
+ # → 已保存: document.md
194
+ ```
195
+
196
+ #### `ocr_directory(input_dir, engine, concurrency=1)` → `None`
197
+
198
+ 批量处理目录下的图片或 PDF 文件。目录下只能有一种类型(全图片或全 PDF)。
199
+
200
+ | 参数 | 类型 | 说明 |
201
+ |---|---|---|
202
+ | `input_dir` | `Path` | 输入目录路径 |
203
+ | `engine` | `OCREngine` | OCR 引擎实例 |
204
+ | `concurrency` | `int` | 并发数,默认 1 |
205
+
206
+ ```python
207
+ from pathlib import Path
208
+ from multi_ocr import ocr_directory
209
+
210
+ # 图片批量 → 输出 scans.md
211
+ ocr_directory(Path("./scans/"), engine, concurrency=4)
212
+
213
+ # PDF 批量 → 每个 PDF 各自输出 .md
214
+ ocr_directory(Path("./pdfs/"), engine)
215
+ ```
216
+
217
+ ### 自定义引擎
218
+
219
+ 继承 `OCREngine` 实现自定义 OCR 引擎:
220
+
221
+ ```python
222
+ from pathlib import Path
223
+ from multi_ocr import OCREngine
224
+
225
+ class MyEngine(OCREngine):
226
+ def parse_image(self, image_path: Path) -> str:
227
+ # 你的 OCR 逻辑
228
+ return "recognized text"
229
+
230
+ # parse_pdf 可选覆盖,默认实现会拆页后调用 parse_image()
231
+ ```
232
+
233
+ ## 要求
234
+
235
+ - Python >= 3.11
236
+
237
+ ## 协议
238
+
239
+ MIT License
@@ -21,9 +21,9 @@ echo " 新版本: $NEW_VERSION"
21
21
  echo "==> 构建包"
22
22
  hatch build
23
23
 
24
- # 4. 发布到 PyPI
24
+ # 4. 发布到 PyPI(使用 UV_PUBLISH_TOKEN / UV_PUBLISH_PASSWORD)
25
25
  echo "==> 发布到 PyPI"
26
- hatch publish
26
+ uv publish
27
27
 
28
28
  # 5. Git 提交 + Tag
29
29
  echo "==> Git 提交 & 打标签"
@@ -24,4 +24,4 @@ __all__ = [
24
24
  "ocr_directory",
25
25
  ]
26
26
 
27
- __version__ = "0.2.1"
27
+ __version__ = "0.2.3"
@@ -6,11 +6,15 @@
6
6
  - Ollama(本地 DeepSeek-OCR)
7
7
 
8
8
  用法:
9
- python main.py <path> [--model MODEL] [--pages PAGES] [--api-key KEY] [--ollama-url URL]
9
+ multi-ocr <path> [--model MODEL] [--pages PAGES]
10
10
 
11
11
  <path> 可以是文件或目录:
12
12
  - 文件:单文件模式,自动判断图片/PDF
13
13
  - 目录:批量模式,目录下只能有一种类型的文件(全图片或全 PDF)
14
+
15
+ 环境变量:
16
+ SILICONFLOW_API_KEY - SiliconFlow 引擎需要的 API Key
17
+ OLLAMA_BASE_URL - Ollama 服务地址(默认 http://127.0.0.1:11434)
14
18
  """
15
19
 
16
20
  import argparse
@@ -22,22 +26,22 @@ from multi_ocr.engines import get_engine
22
26
  from multi_ocr.single import ocr_file
23
27
  from multi_ocr.batch import ocr_directory
24
28
 
25
- DEFAULT_MODEL = "silicon-deepseek-ocr"
29
+ DEFAULT_MODEL = "liteparse"
26
30
 
27
31
  # --model 缩写 → (provider, model_name, description)
28
32
  MODEL_MAP: dict[str, tuple[str, str, str]] = {
29
- "silicon-deepseek-ocr": (
33
+ "deepseek": (
30
34
  "siliconflow",
31
35
  "deepseek-ai/DeepSeek-OCR",
32
36
  "SiliconFlow + DeepSeek-OCR",
33
37
  ),
34
- "silicon-paddle-ocr": (
38
+ "paddle": (
35
39
  "siliconflow",
36
40
  "PaddlePaddle/PaddleOCR-VL-1.5",
37
41
  "SiliconFlow + PaddleOCR-VL-1.5",
38
42
  ),
39
43
  "liteparse": ("liteparse", "", "LiteParse (本地 PDF 解析)"),
40
- "ollama-deepseek-ocr": (
44
+ "ollama": (
41
45
  "ollama",
42
46
  "deepseek-ocr:latest",
43
47
  "Ollama + DeepSeek-OCR",
@@ -51,12 +55,10 @@ _PROVIDER_ENV: dict[str, str] = {
51
55
  }
52
56
 
53
57
 
54
- def _get_api_key(provider: str, cli_key: str | None) -> str | None:
55
- """获取 API Key:命令行 > provider 专用环境变量。
58
+ def _get_api_key(provider: str) -> str | None:
59
+ """获取 API Key:读取 provider 专用环境变量。
56
60
  Ollama / LiteParse 无需 API Key,返回空字符串。
57
61
  """
58
- if cli_key:
59
- return cli_key
60
62
  if provider in ("liteparse", "ollama"):
61
63
  return "" # 本地引擎,无需 API Key
62
64
  env_var = _PROVIDER_ENV[provider]
@@ -71,22 +73,16 @@ def _build_model_help() -> str:
71
73
  return "\n".join(lines)
72
74
 
73
75
 
74
- def _build_api_key_help() -> str:
75
- """动态生成 --api-key 参数的帮助文本。"""
76
- lines = ["API Key(根据 --model 自动读取对应环境变量):"]
77
- for provider, env_var in _PROVIDER_ENV.items():
78
- lines.append(f" {provider} 模型 → {env_var}")
79
- return "\n".join(lines)
80
-
81
-
82
76
  def main() -> None:
83
77
  parser = argparse.ArgumentParser(
84
- description="将 PDF 或图片转换为文字。默认使用 SiliconFlow + DeepSeek-OCR。",
78
+ description="将 PDF 或图片转换为文字。默认使用 liteparse。",
85
79
  formatter_class=argparse.RawTextHelpFormatter,
86
80
  )
87
81
  parser.add_argument(
88
82
  "input",
83
+ nargs="?",
89
84
  type=Path,
85
+ default=None,
90
86
  help="输入文件路径(PDF 或图片)或目录路径(批量处理)",
91
87
  )
92
88
  parser.add_argument(
@@ -99,16 +95,6 @@ def main() -> None:
99
95
  default=None,
100
96
  help="页码范围,如 1-3,5(仅对单文件 PDF 有效)",
101
97
  )
102
- parser.add_argument(
103
- "--api-key",
104
- default=None,
105
- help=_build_api_key_help(),
106
- )
107
- parser.add_argument(
108
- "--ollama-url",
109
- default=None,
110
- help="Ollama 服务地址(默认读取 OLLAMA_BASE_URL 环境变量,都没有则用 http://127.0.0.1:11434)",
111
- )
112
98
  parser.add_argument(
113
99
  "-j",
114
100
  "--concurrency",
@@ -118,6 +104,11 @@ def main() -> None:
118
104
  )
119
105
  args = parser.parse_args()
120
106
 
107
+ # 没有提供参数时显示帮助信息
108
+ if args.input is None:
109
+ parser.print_help()
110
+ sys.exit(0)
111
+
121
112
  input_path: Path = args.input
122
113
 
123
114
  # 校验路径存在
@@ -145,18 +136,18 @@ def main() -> None:
145
136
  sys.exit(1)
146
137
  provider, model_name, _desc = entry
147
138
 
148
- # API Key:命令行 > 环境变量(Ollama / LiteParse 跳过)
149
- api_key = _get_api_key(provider, args.api_key)
139
+ # API Key:从环境变量读取(Ollama / LiteParse 跳过)
140
+ api_key = _get_api_key(provider)
150
141
  if not api_key and provider not in ("liteparse", "ollama"):
151
142
  env_var = _PROVIDER_ENV.get(provider, "")
152
143
  print(
153
- f"请设置 {env_var} 环境变量或使用 --api-key 参数。",
144
+ f"请设置 {env_var} 环境变量。",
154
145
  file=sys.stderr,
155
146
  )
156
147
  sys.exit(1)
157
148
 
158
149
  # 获取 Ollama base_url(仅 ollama 引擎使用)
159
- ollama_url = args.ollama_url or os.environ.get("OLLAMA_BASE_URL")
150
+ ollama_url = os.environ.get("OLLAMA_BASE_URL")
160
151
 
161
152
  # 并发数
162
153
  concurrency: int = args.concurrency
@@ -234,7 +234,6 @@ wheels = [
234
234
 
235
235
  [[package]]
236
236
  name = "multi-ocr-py"
237
- version = "0.1.0"
238
237
  source = { editable = "." }
239
238
  dependencies = [
240
239
  { name = "liteparse" },
@@ -1,129 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: multi-ocr-py
3
- Version: 0.2.1
4
- Summary: 多引擎 OCR 工具包:将 PDF 和图片转换为 Markdown,支持 CLI 全局安装和 SDK 依赖两种使用方式
5
- Project-URL: Repository, https://github.com/BlackBoxRecorder/multi-ocr
6
- Author-email: Yinnan <im.yinnan@outlook.com>
7
- License-Expression: MIT
8
- License-File: LICENSE
9
- Keywords: cli,markdown,ocr,pdf,vision-language-model
10
- Classifier: Development Status :: 3 - Alpha
11
- Classifier: Intended Audience :: Developers
12
- Classifier: License :: OSI Approved :: MIT License
13
- Classifier: Programming Language :: Python :: 3
14
- Classifier: Programming Language :: Python :: 3.11
15
- Classifier: Programming Language :: Python :: 3.12
16
- Classifier: Programming Language :: Python :: 3.13
17
- Classifier: Topic :: Scientific/Engineering :: Image Recognition
18
- Classifier: Topic :: Text Processing :: Markup :: Markdown
19
- Requires-Python: >=3.11
20
- Requires-Dist: liteparse
21
- Requires-Dist: ollama
22
- Requires-Dist: openai>=2.45.0
23
- Requires-Dist: pymupdf>=1.28.0
24
- Requires-Dist: tqdm>=4.67.0
25
- Description-Content-Type: text/markdown
26
-
27
- # multi-ocr
28
-
29
- 多引擎 OCR 工具包,将 PDF 和图片转换为 Markdown 文档。
30
-
31
- - **CLI 工具**:全局安装后一行命令完成 OCR
32
- - **SDK 依赖**:作为 Python 库集成到你的项目中
33
-
34
- ## 支持的引擎
35
-
36
- | 引擎 | 说明 | 类型 | 场景 | 费用 |
37
- |---|---|---|---|---|
38
- | SiliconFlow + DeepSeek-OCR | 云端 OCR,精度高 | API | 图片+PDF | 免费 |
39
- | SiliconFlow + PaddleOCR-VL-1.5 | 云端 OCR,轻量快速 | API | 图片+PDF | 免费 |
40
- | LiteParse | 本地 PDF 解析,无需联网 | 本地 | PDF | 免费 |
41
- | Ollama + DeepSeek-OCR | 本地部署 OCR | 本地 | 图片+PDF | 免费 |
42
-
43
-
44
- > 本地运行 ollama 参考:https://ollama.com/library/deepseek-ocr
45
-
46
- ## 安装
47
-
48
- ### CLI 全局安装
49
-
50
- ```bash
51
- uv tool install multi-ocr-py
52
- # 或
53
- pip install multi-ocr-py
54
- ```
55
-
56
- ### SDK 依赖安装
57
-
58
- ```bash
59
- pip install multi-ocr-py
60
- # 或
61
- uv add multi-ocr-py
62
- ```
63
-
64
- ## CLI 使用
65
-
66
- ```bash
67
- # 单文件 OCR
68
- multi-ocr document.pdf
69
-
70
- # 指定引擎和页码范围
71
- multi-ocr document.pdf --model liteparse --pages 1-5
72
-
73
- # 批量处理目录,4个并发
74
- multi-ocr ./scans/ --model silicon-deepseek-ocr -j 4
75
-
76
- # 查看帮助
77
- multi-ocr -h
78
- ```
79
-
80
- ### 环境变量
81
-
82
- | 引擎 | 环境变量 |
83
- |---|---|
84
- | SiliconFlow | `SILICONFLOW_API_KEY` |
85
- | Ollama | `OLLAMA_BASE_URL`(可选,默认 http://127.0.0.1:11434)|
86
-
87
-
88
- ## SDK 使用
89
-
90
- ```python
91
- from pathlib import Path
92
- from multi_ocr import get_engine, ocr_file, OCREngine
93
-
94
- # 创建引擎
95
- engine = get_engine(
96
- provider="siliconflow",
97
- model="deepseek-ai/DeepSeek-OCR",
98
- api_key="your-api-key",
99
- )
100
-
101
- # 识别图片
102
- text = engine.parse_image(Path("scan.jpg"))
103
-
104
- # 识别 PDF
105
- result = ocr_file(Path("document.pdf"), engine, pages="1-3")
106
-
107
- # 批量处理目录
108
- from multi_ocr import ocr_directory
109
- ocr_directory(Path("./scans/"), engine, concurrency=4)
110
- ```
111
-
112
- ### 自定义引擎
113
-
114
- ```python
115
- from multi_ocr import OCREngine
116
-
117
- class MyEngine(OCREngine):
118
- def parse_image(self, image_path: Path) -> str:
119
- # 你的 OCR 逻辑
120
- return "recognized text"
121
- ```
122
-
123
- ## 要求
124
-
125
- - Python >= 3.11
126
-
127
- ## 协议
128
-
129
- MIT License
@@ -1,103 +0,0 @@
1
- # multi-ocr
2
-
3
- 多引擎 OCR 工具包,将 PDF 和图片转换为 Markdown 文档。
4
-
5
- - **CLI 工具**:全局安装后一行命令完成 OCR
6
- - **SDK 依赖**:作为 Python 库集成到你的项目中
7
-
8
- ## 支持的引擎
9
-
10
- | 引擎 | 说明 | 类型 | 场景 | 费用 |
11
- |---|---|---|---|---|
12
- | SiliconFlow + DeepSeek-OCR | 云端 OCR,精度高 | API | 图片+PDF | 免费 |
13
- | SiliconFlow + PaddleOCR-VL-1.5 | 云端 OCR,轻量快速 | API | 图片+PDF | 免费 |
14
- | LiteParse | 本地 PDF 解析,无需联网 | 本地 | PDF | 免费 |
15
- | Ollama + DeepSeek-OCR | 本地部署 OCR | 本地 | 图片+PDF | 免费 |
16
-
17
-
18
- > 本地运行 ollama 参考:https://ollama.com/library/deepseek-ocr
19
-
20
- ## 安装
21
-
22
- ### CLI 全局安装
23
-
24
- ```bash
25
- uv tool install multi-ocr-py
26
- # 或
27
- pip install multi-ocr-py
28
- ```
29
-
30
- ### SDK 依赖安装
31
-
32
- ```bash
33
- pip install multi-ocr-py
34
- # 或
35
- uv add multi-ocr-py
36
- ```
37
-
38
- ## CLI 使用
39
-
40
- ```bash
41
- # 单文件 OCR
42
- multi-ocr document.pdf
43
-
44
- # 指定引擎和页码范围
45
- multi-ocr document.pdf --model liteparse --pages 1-5
46
-
47
- # 批量处理目录,4个并发
48
- multi-ocr ./scans/ --model silicon-deepseek-ocr -j 4
49
-
50
- # 查看帮助
51
- multi-ocr -h
52
- ```
53
-
54
- ### 环境变量
55
-
56
- | 引擎 | 环境变量 |
57
- |---|---|
58
- | SiliconFlow | `SILICONFLOW_API_KEY` |
59
- | Ollama | `OLLAMA_BASE_URL`(可选,默认 http://127.0.0.1:11434)|
60
-
61
-
62
- ## SDK 使用
63
-
64
- ```python
65
- from pathlib import Path
66
- from multi_ocr import get_engine, ocr_file, OCREngine
67
-
68
- # 创建引擎
69
- engine = get_engine(
70
- provider="siliconflow",
71
- model="deepseek-ai/DeepSeek-OCR",
72
- api_key="your-api-key",
73
- )
74
-
75
- # 识别图片
76
- text = engine.parse_image(Path("scan.jpg"))
77
-
78
- # 识别 PDF
79
- result = ocr_file(Path("document.pdf"), engine, pages="1-3")
80
-
81
- # 批量处理目录
82
- from multi_ocr import ocr_directory
83
- ocr_directory(Path("./scans/"), engine, concurrency=4)
84
- ```
85
-
86
- ### 自定义引擎
87
-
88
- ```python
89
- from multi_ocr import OCREngine
90
-
91
- class MyEngine(OCREngine):
92
- def parse_image(self, image_path: Path) -> str:
93
- # 你的 OCR 逻辑
94
- return "recognized text"
95
- ```
96
-
97
- ## 要求
98
-
99
- - Python >= 3.11
100
-
101
- ## 协议
102
-
103
- MIT License
File without changes
File without changes
File without changes
File without changes