sdpy-kit 0.4.5__tar.gz → 0.5.1__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.
- {sdpy_kit-0.4.5 → sdpy_kit-0.5.1}/PKG-INFO +57 -14
- {sdpy_kit-0.4.5 → sdpy_kit-0.5.1}/README.md +51 -11
- {sdpy_kit-0.4.5 → sdpy_kit-0.5.1}/kit/__init__.py +1 -1
- {sdpy_kit-0.4.5 → sdpy_kit-0.5.1}/kit/config/kit_config.py +1 -1
- {sdpy_kit-0.4.5 → sdpy_kit-0.5.1}/kit/docs/__init__.py +2 -1
- {sdpy_kit-0.4.5 → sdpy_kit-0.5.1}/kit/docs/anydoc_kit.py +37 -22
- {sdpy_kit-0.4.5 → sdpy_kit-0.5.1}/kit/docs/docx_kit.py +22 -23
- {sdpy_kit-0.4.5 → sdpy_kit-0.5.1}/kit/docs/marker_kit.py +41 -44
- {sdpy_kit-0.4.5 → sdpy_kit-0.5.1}/kit/docs/md2doc_kit.py +19 -14
- {sdpy_kit-0.4.5 → sdpy_kit-0.5.1}/kit/docs/mineru_kit.py +21 -29
- sdpy_kit-0.5.1/kit/docs/rc_docparser_kit.py +654 -0
- {sdpy_kit-0.4.5 → sdpy_kit-0.5.1}/pyproject.toml +7 -3
- {sdpy_kit-0.4.5 → sdpy_kit-0.5.1}/.gitignore +0 -0
- {sdpy_kit-0.4.5 → sdpy_kit-0.5.1}/kit/ai/__init__.py +0 -0
- {sdpy_kit-0.4.5 → sdpy_kit-0.5.1}/kit/ai/base_service.py +0 -0
- {sdpy_kit-0.4.5 → sdpy_kit-0.5.1}/kit/ai/chat_service.py +0 -0
- {sdpy_kit-0.4.5 → sdpy_kit-0.5.1}/kit/ai/embedding_service.py +0 -0
- {sdpy_kit-0.4.5 → sdpy_kit-0.5.1}/kit/ai/exceptions.py +0 -0
- {sdpy_kit-0.4.5 → sdpy_kit-0.5.1}/kit/ai/failover.py +0 -0
- {sdpy_kit-0.4.5 → sdpy_kit-0.5.1}/kit/ai/image_service.py +0 -0
- {sdpy_kit-0.4.5 → sdpy_kit-0.5.1}/kit/ai/model_builder.py +0 -0
- {sdpy_kit-0.4.5 → sdpy_kit-0.5.1}/kit/ai/model_client.py +0 -0
- {sdpy_kit-0.4.5 → sdpy_kit-0.5.1}/kit/ai/pool.py +0 -0
- {sdpy_kit-0.4.5 → sdpy_kit-0.5.1}/kit/ai/profiles.py +0 -0
- {sdpy_kit-0.4.5 → sdpy_kit-0.5.1}/kit/ai/rerank_service.py +0 -0
- {sdpy_kit-0.4.5 → sdpy_kit-0.5.1}/kit/ai/runner.py +0 -0
- {sdpy_kit-0.4.5 → sdpy_kit-0.5.1}/kit/ai/types.py +0 -0
- {sdpy_kit-0.4.5 → sdpy_kit-0.5.1}/kit/common_kit.py +0 -0
- {sdpy_kit-0.4.5 → sdpy_kit-0.5.1}/kit/config/__init__.py +0 -0
- {sdpy_kit-0.4.5 → sdpy_kit-0.5.1}/kit/config/log_config.py +0 -0
- {sdpy_kit-0.4.5 → sdpy_kit-0.5.1}/kit/crawl/__init__.py +0 -0
- {sdpy_kit-0.4.5 → sdpy_kit-0.5.1}/kit/crawl/article_models.py +0 -0
- {sdpy_kit-0.4.5 → sdpy_kit-0.5.1}/kit/crawl/web_article_kit.py +0 -0
- {sdpy_kit-0.4.5 → sdpy_kit-0.5.1}/kit/crawl/wx_article_kit.py +0 -0
- {sdpy_kit-0.4.5 → sdpy_kit-0.5.1}/kit/db/__init__.py +0 -0
- {sdpy_kit-0.4.5 → sdpy_kit-0.5.1}/kit/db/base_db_kit.py +0 -0
- {sdpy_kit-0.4.5 → sdpy_kit-0.5.1}/kit/db/crud.py +0 -0
- {sdpy_kit-0.4.5 → sdpy_kit-0.5.1}/kit/db/engine.py +0 -0
- {sdpy_kit-0.4.5 → sdpy_kit-0.5.1}/kit/db/exceptions.py +0 -0
- {sdpy_kit-0.4.5 → sdpy_kit-0.5.1}/kit/db/models/__init__.py +0 -0
- {sdpy_kit-0.4.5 → sdpy_kit-0.5.1}/kit/db/models/base.py +0 -0
- {sdpy_kit-0.4.5 → sdpy_kit-0.5.1}/kit/db/mysql_kit.py +0 -0
- {sdpy_kit-0.4.5 → sdpy_kit-0.5.1}/kit/db/pg_kit.py +0 -0
- {sdpy_kit-0.4.5 → sdpy_kit-0.5.1}/kit/db/query.py +0 -0
- {sdpy_kit-0.4.5 → sdpy_kit-0.5.1}/kit/db/session.py +0 -0
- {sdpy_kit-0.4.5 → sdpy_kit-0.5.1}/kit/db/sqlite_kit.py +0 -0
- {sdpy_kit-0.4.5 → sdpy_kit-0.5.1}/kit/db/transaction.py +0 -0
- {sdpy_kit-0.4.5 → sdpy_kit-0.5.1}/kit/file_kit.py +0 -0
- {sdpy_kit-0.4.5 → sdpy_kit-0.5.1}/kit/laya_kit.py +0 -0
- {sdpy_kit-0.4.5 → sdpy_kit-0.5.1}/kit/license_kit.py +0 -0
- {sdpy_kit-0.4.5 → sdpy_kit-0.5.1}/kit/redis_kit.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: sdpy-kit
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.5.1
|
|
4
4
|
Summary: SDPY Kit——统一数据库访问层(PG/MySQL/SQLite)与 AI/Redis/文件/文档/向量工具集
|
|
5
5
|
Author-email: Clark <changhongyuan@126.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -32,13 +32,14 @@ Requires-Dist: httpx>=0.28.1; extra == 'all'
|
|
|
32
32
|
Requires-Dist: huggingface-hub<2,>=1.5; extra == 'all'
|
|
33
33
|
Requires-Dist: laya>=0.4.6; extra == 'all'
|
|
34
34
|
Requires-Dist: markdown-it-py>=4.2.0; extra == 'all'
|
|
35
|
-
Requires-Dist: marker-pdf
|
|
35
|
+
Requires-Dist: marker-pdf>=2.0.0; extra == 'all'
|
|
36
36
|
Requires-Dist: numpy>=2.5.4; extra == 'all'
|
|
37
37
|
Requires-Dist: pikepdf>=10.17.0; extra == 'all'
|
|
38
38
|
Requires-Dist: pimd[pdfa]>=2.2.5; extra == 'all'
|
|
39
39
|
Requires-Dist: psycopg2-binary>=2.9.13; extra == 'all'
|
|
40
40
|
Requires-Dist: pymysql>=1.2.3; extra == 'all'
|
|
41
41
|
Requires-Dist: python-dotenv>=1.2.4; extra == 'all'
|
|
42
|
+
Requires-Dist: rc-docparser>=0.2.2; extra == 'all'
|
|
42
43
|
Requires-Dist: redis>=8.1.0; extra == 'all'
|
|
43
44
|
Requires-Dist: requests>=2.34.2; extra == 'all'
|
|
44
45
|
Requires-Dist: sqliteai-vector>=1.1.2; extra == 'all'
|
|
@@ -48,11 +49,13 @@ Requires-Dist: firecrawl-anydoc>=0.2.4; extra == 'anydoc'
|
|
|
48
49
|
Requires-Dist: pikepdf>=10.17.0; extra == 'anydoc'
|
|
49
50
|
Provides-Extra: docx
|
|
50
51
|
Requires-Dist: docxtpl>=0.20.2; extra == 'docx'
|
|
52
|
+
Provides-Extra: docx-parse
|
|
53
|
+
Requires-Dist: rc-docparser>=0.2.2; extra == 'docx-parse'
|
|
51
54
|
Provides-Extra: laya
|
|
52
55
|
Requires-Dist: huggingface-hub<2,>=1.5; extra == 'laya'
|
|
53
56
|
Requires-Dist: laya>=0.4.6; extra == 'laya'
|
|
54
57
|
Provides-Extra: marker
|
|
55
|
-
Requires-Dist: marker-pdf
|
|
58
|
+
Requires-Dist: marker-pdf>=2.0.0; extra == 'marker'
|
|
56
59
|
Provides-Extra: md2doc
|
|
57
60
|
Requires-Dist: markdown-it-py>=4.2.0; extra == 'md2doc'
|
|
58
61
|
Requires-Dist: pimd[pdfa]>=2.2.5; extra == 'md2doc'
|
|
@@ -77,7 +80,7 @@ SDPY 统一工具集(Kit 体系),供 Python 项目开箱即用:
|
|
|
77
80
|
|
|
78
81
|
- **统一数据库访问层**:PostgreSQL / MySQL / SQLite,三个 Kit API 完全一致,切换数据库只改一行 import;
|
|
79
82
|
- **AI 多模型服务池**:chat / embedding / rerank / image 四类能力,多厂商候选链 + 故障自动转移;
|
|
80
|
-
- **工具集**:Redis / 文件 / 雪花 ID / 文档互转 / Word 模板填充 / MinerU 解析 / Marker 本地解析(md + images/) / Laya 类型化决策 / 微信公众号文章抓取存储 / 通用网页文章抓取存储。
|
|
83
|
+
- **工具集**:Redis / 文件 / 雪花 ID / 文档互转 / Word 模板填充 / MinerU 解析 / Marker 本地解析(PDF + 图片 → md + images/) / 离线 docx 解析(md + images/) / Laya 类型化决策 / 微信公众号文章抓取存储 / 通用网页文章抓取存储。
|
|
81
84
|
|
|
82
85
|
> 要求 Python 3.13+
|
|
83
86
|
|
|
@@ -93,9 +96,10 @@ SDPY 统一工具集(Kit 体系),供 Python 项目开箱即用:
|
|
|
93
96
|
| `kit.common_kit` | `CommonKit` | 雪花 ID、时间戳 ID、时间格式化 | 无 |
|
|
94
97
|
| `kit.docs.anydoc_kit` | `AnyDocKit` | docx / pdf / xlsx 等 → Markdown | `anydoc` |
|
|
95
98
|
| `kit.docs.docx_kit` | `DocxKit` | Word 模板动态填充(章节 / 列表 / 表格) | `docx` |
|
|
99
|
+
| `kit.docs.rc_docparser_kit` | `RcDocParserKit` | 离线 docx → Markdown + Images(无模型) | `docx-parse` |
|
|
96
100
|
| `kit.docs.md2doc_kit` | `Md2DocKit` | Markdown → Word / PDF / HTML | `md2doc` |
|
|
97
101
|
| `kit.docs.mineru_kit` | `MinerUKit` | MinerU 文档解析(精准 + Agent 轻量) | `mineru` |
|
|
98
|
-
| `kit.docs.marker_kit` | `MarkerKit` |
|
|
102
|
+
| `kit.docs.marker_kit` | `MarkerKit` | 本地解析(PDF / 图片 → Markdown + Images) | `marker` |
|
|
99
103
|
| `kit.laya_kit` | `LayaKit` | 类型化决策:choice / score / noul,返回判断结果 + 置信度 | `laya` |
|
|
100
104
|
| `kit.crawl.article_models` | `ArticleInfo` / `ArticleResult` / `SavedOutput` 等 | 文章抓取通用模型(两 `*ArticleKit` 共用,含 `reason` 分类与非致命 `warnings`) | 无 |
|
|
101
105
|
| `kit.crawl.wx_article_kit` | `WxArticleKit` | 微信公众号文章 → Markdown + 图片转存 | 无 |
|
|
@@ -121,8 +125,9 @@ uv add sdpy-kit
|
|
|
121
125
|
| `md2doc` | Md2DocKit:Markdown → Word / PDF / HTML(pimd / fpdf2) | `pip install "sdpy-kit[md2doc]"` |
|
|
122
126
|
| `anydoc` | AnyDocKit 文档转 Markdown(firecrawl-anydoc + pikepdf) | `pip install "sdpy-kit[anydoc]"` |
|
|
123
127
|
| `docx` | DocxKit 模板动态填充(docxtpl) | `pip install "sdpy-kit[docx]"` |
|
|
128
|
+
| `docx-parse` | RcDocParserKit 离线 docx 解析(rc-docparser → Markdown + images/) | `pip install "sdpy-kit[docx-parse]"` |
|
|
124
129
|
| `mineru` | MinerUKit 解析 API(精准解析 + Agent 轻量解析) | `pip install "sdpy-kit[mineru]"` |
|
|
125
|
-
| `marker` | MarkerKit
|
|
130
|
+
| `marker` | MarkerKit 本地解析(marker-pdf → Markdown + Images;PDF + 图片,依赖体积大) | `pip install "sdpy-kit[marker]"` |
|
|
126
131
|
| `laya` | LayaKit 类型化决策(laya + torch,本地小模型 choice / score / noul) | `pip install "sdpy-kit[laya]"` |
|
|
127
132
|
| `web-article` | WebArticleKit 通用网页文章抓取转存(trafilatura,纯 HTTP 无浏览器) | `pip install "sdpy-kit[web-article]"` |
|
|
128
133
|
| `all` | 全部能力 | `pip install "sdpy-kit[all]"` |
|
|
@@ -871,10 +876,13 @@ md = AnyDocKit.convert_to_md("scan.pdf", ocr="hosted") # 需 FIRECRAWL_API_KEY
|
|
|
871
876
|
| `detect_format(file_path) -> str \| None` | 由扩展名推断规范格式名 |
|
|
872
877
|
| `convert_to_md(file_path, *, ocr="reject", api_key=None, api_url=None) -> str` | 文件 → Markdown(非标 PDF 自动修复重试) |
|
|
873
878
|
| `convert_bytes_to_md(data, fmt=None, *, ocr="reject", api_key=None, api_url=None) -> str` | 字节内容 → Markdown |
|
|
874
|
-
| `convert(file_path, *, ocr="reject", api_key=None, api_url=None) ->
|
|
879
|
+
| `convert(file_path, *, ocr="reject", api_key=None, api_url=None) -> AnyDocResult` | 安全转换 |
|
|
875
880
|
| `convert_to_file(src_path, dest_path=None, *, ocr="reject", ...) -> str` | 转换并写入 `.md`,返回目标路径 |
|
|
876
881
|
|
|
877
|
-
`
|
|
882
|
+
`AnyDocResult(success, markdown, file_path, source_format, error)`
|
|
883
|
+
|
|
884
|
+
> 异常:沿用上游 `anydoc.ConvertError` 体系(`MalformedError` / `NeedsOcrError` 等子类可直接捕获),
|
|
885
|
+
> `AnyDocError` 是该基类的别名;安全版 `convert()` 会把它们封装为 `AnyDocResult.error`。
|
|
878
886
|
|
|
879
887
|
---
|
|
880
888
|
|
|
@@ -971,9 +979,12 @@ if r.state == "done":
|
|
|
971
979
|
|
|
972
980
|
---
|
|
973
981
|
|
|
974
|
-
## kit.docs.marker_kit ——
|
|
982
|
+
## kit.docs.marker_kit —— 本地解析:PDF + 图片 → Markdown + Images
|
|
983
|
+
|
|
984
|
+
安装:`pip install "sdpy-kit[marker]"`(依赖 `marker-pdf`,含 torch 等 80+ 包,体积较大;不含 `[full]`)
|
|
975
985
|
|
|
976
|
-
|
|
986
|
+
支持面:`.pdf`、`.png`、`.jpg`、`.jpeg`、`.webp`、`.gif`、`.bmp`。docx/pptx/xlsx/html/epub 不在支持面
|
|
987
|
+
(marker 侧实现依赖 weasyprint/GTK),传入会抛 `ValueError`。
|
|
977
988
|
|
|
978
989
|
```python
|
|
979
990
|
from kit.docs.marker_kit import MarkerKit
|
|
@@ -990,15 +1001,18 @@ result = MarkerKit.convert("report.pdf", "out/doc")
|
|
|
990
1001
|
if result.success:
|
|
991
1002
|
print(result.md_path, len(result.image_paths), result.page_count)
|
|
992
1003
|
|
|
993
|
-
#
|
|
994
|
-
md = MarkerKit.convert_to_md("
|
|
1004
|
+
# 文本层 PDF 离线抽取(跳过 VLM/OCR,无需 llama-server)
|
|
1005
|
+
md = MarkerKit.convert_to_md("report.pdf", disable_ocr=True)
|
|
1006
|
+
|
|
1007
|
+
# 图片输入(无文本层,必须 OCR:仅 disable_ocr=True 时无文字内容)
|
|
1008
|
+
md = MarkerKit.convert_to_md("figure.png", disable_ocr=True)
|
|
995
1009
|
|
|
996
1010
|
MarkerKit.shutdown() # 释放模型与推理服务(幂等)
|
|
997
1011
|
```
|
|
998
1012
|
|
|
999
1013
|
| 方法 | 说明 |
|
|
1000
1014
|
|------|------|
|
|
1001
|
-
| `is_supported(file_path) -> bool` |
|
|
1015
|
+
| `is_supported(file_path) -> bool` | 白名单:`.pdf` + `.png/.jpg/.jpeg/.webp/.gif/.bmp` |
|
|
1002
1016
|
| `convert_to_md(file_path, *, mode=None, force_ocr=None, disable_ocr=None, page_range=None) -> str` | 解析并返回 Markdown 文本(图片不落盘) |
|
|
1003
1017
|
| `convert_to_dir(src_path, output_dir=None, *, mode=None, force_ocr=None, disable_ocr=None, page_range=None, extract_images=True) -> str` | 解析并落盘 md + `images/`,返回 md 绝对路径 |
|
|
1004
1018
|
| `convert(src_path, output_dir=None, *, ...) -> MarkerResult` | 安全版:失败封装为 `MarkerResult`,不抛异常 |
|
|
@@ -1007,7 +1021,36 @@ MarkerKit.shutdown() # 释放模型与推理服务(幂等)
|
|
|
1007
1021
|
> 产物:`<output_dir>/<源文件名>.md` + `<output_dir>/images/`(md 内以 `images/<文件名>` 相对引用;无图片不建空目录),**不生成** `_meta.json`。
|
|
1008
1022
|
> 结果类型:`MarkerResult`(`success` / `markdown` / `file_path` / `output_dir` / `md_path` / `image_paths` / `page_count` / `error`);异常:`MarkerError`。
|
|
1009
1023
|
> `mode` 缺省时不写入配置,交由 marker 按设备自动选择;首次使用会下载模型权重(默认走 `MARKER_HF_ENDPOINT` 镜像)。
|
|
1010
|
-
>
|
|
1024
|
+
> **前提条件**:文本层 PDF 传 `disable_ocr=True` 即可完全离线(无需 llama-server);不传时 marker 默认启用 VLM/OCR,
|
|
1025
|
+
> 缺 `llama-server` 抛 `SpawnError`。扫描件 / 图片型 PDF / 图片输入要得到文字,必须有 llama.cpp 的 `llama-server`
|
|
1026
|
+
> (`MARKER_LLAMA_CPP_BINARY`),否则只得到空 md 或一条整图引用。PDF 内嵌图片抽取不需要 `llama-server`。
|
|
1027
|
+
|
|
1028
|
+
## kit.docs.rc_docparser_kit —— 离线 docx → Markdown + Images
|
|
1029
|
+
|
|
1030
|
+
安装:`pip install "sdpy-kit[docx-parse]"`(依赖 `rc-docparser`,纯 Python,无模型 / OCR / GTK)
|
|
1031
|
+
|
|
1032
|
+
支持面:仅 `.docx`。产物与 `MarkerKit` 同一契约:`<out>/<stem>.md` + `<out>/images/`。
|
|
1033
|
+
|
|
1034
|
+
```python
|
|
1035
|
+
from kit.docs.rc_docparser_kit import RcDocParserKit
|
|
1036
|
+
|
|
1037
|
+
md_path = RcDocParserKit.convert_to_dir("report.docx") # -> report/report.md + report/images/
|
|
1038
|
+
md = RcDocParserKit.convert_to_md("report.docx") # 只取文本(图片不落盘)
|
|
1039
|
+
result = RcDocParserKit.convert("report.docx", "out/doc")
|
|
1040
|
+
if result.success:
|
|
1041
|
+
print(result.md_path, len(result.image_paths))
|
|
1042
|
+
```
|
|
1043
|
+
|
|
1044
|
+
| 方法 | 说明 |
|
|
1045
|
+
|------|------|
|
|
1046
|
+
| `is_supported(file_path) -> bool` | 是否 `.docx` |
|
|
1047
|
+
| `convert_to_md(file_path) -> str` | 解析并返回 Markdown 文本 |
|
|
1048
|
+
| `convert_to_dir(src_path, output_dir=None, *, extract_images=True) -> str` | 落盘 md + `images/`,返回 md 绝对路径 |
|
|
1049
|
+
| `convert(src_path, output_dir=None, *, ...) -> RcDocParserResult` | 安全版:失败封装为结果对象 |
|
|
1050
|
+
|
|
1051
|
+
> 产物:`<out>/images/img-NNN-<sha1 前 10>.<ext>`(按出现顺序、内容哈希命名);无图不建空目录。
|
|
1052
|
+
> 前提:中文标题依赖 `w:outlineLvl` 或「标题 N」样式(都没有时退化为正文);合并单元格表格会重建为
|
|
1053
|
+
> 等宽 GFM(覆盖位留空,不输出 HTML `<table>`);页眉页脚/脚注不提取。纯本地,无需模型或 GPU。
|
|
1011
1054
|
|
|
1012
1055
|
## kit.crawl.wx_article_kit —— 微信公众号文章抓取存储
|
|
1013
1056
|
|
|
@@ -4,7 +4,7 @@ SDPY 统一工具集(Kit 体系),供 Python 项目开箱即用:
|
|
|
4
4
|
|
|
5
5
|
- **统一数据库访问层**:PostgreSQL / MySQL / SQLite,三个 Kit API 完全一致,切换数据库只改一行 import;
|
|
6
6
|
- **AI 多模型服务池**:chat / embedding / rerank / image 四类能力,多厂商候选链 + 故障自动转移;
|
|
7
|
-
- **工具集**:Redis / 文件 / 雪花 ID / 文档互转 / Word 模板填充 / MinerU 解析 / Marker 本地解析(md + images/) / Laya 类型化决策 / 微信公众号文章抓取存储 / 通用网页文章抓取存储。
|
|
7
|
+
- **工具集**:Redis / 文件 / 雪花 ID / 文档互转 / Word 模板填充 / MinerU 解析 / Marker 本地解析(PDF + 图片 → md + images/) / 离线 docx 解析(md + images/) / Laya 类型化决策 / 微信公众号文章抓取存储 / 通用网页文章抓取存储。
|
|
8
8
|
|
|
9
9
|
> 要求 Python 3.13+
|
|
10
10
|
|
|
@@ -20,9 +20,10 @@ SDPY 统一工具集(Kit 体系),供 Python 项目开箱即用:
|
|
|
20
20
|
| `kit.common_kit` | `CommonKit` | 雪花 ID、时间戳 ID、时间格式化 | 无 |
|
|
21
21
|
| `kit.docs.anydoc_kit` | `AnyDocKit` | docx / pdf / xlsx 等 → Markdown | `anydoc` |
|
|
22
22
|
| `kit.docs.docx_kit` | `DocxKit` | Word 模板动态填充(章节 / 列表 / 表格) | `docx` |
|
|
23
|
+
| `kit.docs.rc_docparser_kit` | `RcDocParserKit` | 离线 docx → Markdown + Images(无模型) | `docx-parse` |
|
|
23
24
|
| `kit.docs.md2doc_kit` | `Md2DocKit` | Markdown → Word / PDF / HTML | `md2doc` |
|
|
24
25
|
| `kit.docs.mineru_kit` | `MinerUKit` | MinerU 文档解析(精准 + Agent 轻量) | `mineru` |
|
|
25
|
-
| `kit.docs.marker_kit` | `MarkerKit` |
|
|
26
|
+
| `kit.docs.marker_kit` | `MarkerKit` | 本地解析(PDF / 图片 → Markdown + Images) | `marker` |
|
|
26
27
|
| `kit.laya_kit` | `LayaKit` | 类型化决策:choice / score / noul,返回判断结果 + 置信度 | `laya` |
|
|
27
28
|
| `kit.crawl.article_models` | `ArticleInfo` / `ArticleResult` / `SavedOutput` 等 | 文章抓取通用模型(两 `*ArticleKit` 共用,含 `reason` 分类与非致命 `warnings`) | 无 |
|
|
28
29
|
| `kit.crawl.wx_article_kit` | `WxArticleKit` | 微信公众号文章 → Markdown + 图片转存 | 无 |
|
|
@@ -48,8 +49,9 @@ uv add sdpy-kit
|
|
|
48
49
|
| `md2doc` | Md2DocKit:Markdown → Word / PDF / HTML(pimd / fpdf2) | `pip install "sdpy-kit[md2doc]"` |
|
|
49
50
|
| `anydoc` | AnyDocKit 文档转 Markdown(firecrawl-anydoc + pikepdf) | `pip install "sdpy-kit[anydoc]"` |
|
|
50
51
|
| `docx` | DocxKit 模板动态填充(docxtpl) | `pip install "sdpy-kit[docx]"` |
|
|
52
|
+
| `docx-parse` | RcDocParserKit 离线 docx 解析(rc-docparser → Markdown + images/) | `pip install "sdpy-kit[docx-parse]"` |
|
|
51
53
|
| `mineru` | MinerUKit 解析 API(精准解析 + Agent 轻量解析) | `pip install "sdpy-kit[mineru]"` |
|
|
52
|
-
| `marker` | MarkerKit
|
|
54
|
+
| `marker` | MarkerKit 本地解析(marker-pdf → Markdown + Images;PDF + 图片,依赖体积大) | `pip install "sdpy-kit[marker]"` |
|
|
53
55
|
| `laya` | LayaKit 类型化决策(laya + torch,本地小模型 choice / score / noul) | `pip install "sdpy-kit[laya]"` |
|
|
54
56
|
| `web-article` | WebArticleKit 通用网页文章抓取转存(trafilatura,纯 HTTP 无浏览器) | `pip install "sdpy-kit[web-article]"` |
|
|
55
57
|
| `all` | 全部能力 | `pip install "sdpy-kit[all]"` |
|
|
@@ -798,10 +800,13 @@ md = AnyDocKit.convert_to_md("scan.pdf", ocr="hosted") # 需 FIRECRAWL_API_KEY
|
|
|
798
800
|
| `detect_format(file_path) -> str \| None` | 由扩展名推断规范格式名 |
|
|
799
801
|
| `convert_to_md(file_path, *, ocr="reject", api_key=None, api_url=None) -> str` | 文件 → Markdown(非标 PDF 自动修复重试) |
|
|
800
802
|
| `convert_bytes_to_md(data, fmt=None, *, ocr="reject", api_key=None, api_url=None) -> str` | 字节内容 → Markdown |
|
|
801
|
-
| `convert(file_path, *, ocr="reject", api_key=None, api_url=None) ->
|
|
803
|
+
| `convert(file_path, *, ocr="reject", api_key=None, api_url=None) -> AnyDocResult` | 安全转换 |
|
|
802
804
|
| `convert_to_file(src_path, dest_path=None, *, ocr="reject", ...) -> str` | 转换并写入 `.md`,返回目标路径 |
|
|
803
805
|
|
|
804
|
-
`
|
|
806
|
+
`AnyDocResult(success, markdown, file_path, source_format, error)`
|
|
807
|
+
|
|
808
|
+
> 异常:沿用上游 `anydoc.ConvertError` 体系(`MalformedError` / `NeedsOcrError` 等子类可直接捕获),
|
|
809
|
+
> `AnyDocError` 是该基类的别名;安全版 `convert()` 会把它们封装为 `AnyDocResult.error`。
|
|
805
810
|
|
|
806
811
|
---
|
|
807
812
|
|
|
@@ -898,9 +903,12 @@ if r.state == "done":
|
|
|
898
903
|
|
|
899
904
|
---
|
|
900
905
|
|
|
901
|
-
## kit.docs.marker_kit ——
|
|
906
|
+
## kit.docs.marker_kit —— 本地解析:PDF + 图片 → Markdown + Images
|
|
907
|
+
|
|
908
|
+
安装:`pip install "sdpy-kit[marker]"`(依赖 `marker-pdf`,含 torch 等 80+ 包,体积较大;不含 `[full]`)
|
|
902
909
|
|
|
903
|
-
|
|
910
|
+
支持面:`.pdf`、`.png`、`.jpg`、`.jpeg`、`.webp`、`.gif`、`.bmp`。docx/pptx/xlsx/html/epub 不在支持面
|
|
911
|
+
(marker 侧实现依赖 weasyprint/GTK),传入会抛 `ValueError`。
|
|
904
912
|
|
|
905
913
|
```python
|
|
906
914
|
from kit.docs.marker_kit import MarkerKit
|
|
@@ -917,15 +925,18 @@ result = MarkerKit.convert("report.pdf", "out/doc")
|
|
|
917
925
|
if result.success:
|
|
918
926
|
print(result.md_path, len(result.image_paths), result.page_count)
|
|
919
927
|
|
|
920
|
-
#
|
|
921
|
-
md = MarkerKit.convert_to_md("
|
|
928
|
+
# 文本层 PDF 离线抽取(跳过 VLM/OCR,无需 llama-server)
|
|
929
|
+
md = MarkerKit.convert_to_md("report.pdf", disable_ocr=True)
|
|
930
|
+
|
|
931
|
+
# 图片输入(无文本层,必须 OCR:仅 disable_ocr=True 时无文字内容)
|
|
932
|
+
md = MarkerKit.convert_to_md("figure.png", disable_ocr=True)
|
|
922
933
|
|
|
923
934
|
MarkerKit.shutdown() # 释放模型与推理服务(幂等)
|
|
924
935
|
```
|
|
925
936
|
|
|
926
937
|
| 方法 | 说明 |
|
|
927
938
|
|------|------|
|
|
928
|
-
| `is_supported(file_path) -> bool` |
|
|
939
|
+
| `is_supported(file_path) -> bool` | 白名单:`.pdf` + `.png/.jpg/.jpeg/.webp/.gif/.bmp` |
|
|
929
940
|
| `convert_to_md(file_path, *, mode=None, force_ocr=None, disable_ocr=None, page_range=None) -> str` | 解析并返回 Markdown 文本(图片不落盘) |
|
|
930
941
|
| `convert_to_dir(src_path, output_dir=None, *, mode=None, force_ocr=None, disable_ocr=None, page_range=None, extract_images=True) -> str` | 解析并落盘 md + `images/`,返回 md 绝对路径 |
|
|
931
942
|
| `convert(src_path, output_dir=None, *, ...) -> MarkerResult` | 安全版:失败封装为 `MarkerResult`,不抛异常 |
|
|
@@ -934,7 +945,36 @@ MarkerKit.shutdown() # 释放模型与推理服务(幂等)
|
|
|
934
945
|
> 产物:`<output_dir>/<源文件名>.md` + `<output_dir>/images/`(md 内以 `images/<文件名>` 相对引用;无图片不建空目录),**不生成** `_meta.json`。
|
|
935
946
|
> 结果类型:`MarkerResult`(`success` / `markdown` / `file_path` / `output_dir` / `md_path` / `image_paths` / `page_count` / `error`);异常:`MarkerError`。
|
|
936
947
|
> `mode` 缺省时不写入配置,交由 marker 按设备自动选择;首次使用会下载模型权重(默认走 `MARKER_HF_ENDPOINT` 镜像)。
|
|
937
|
-
>
|
|
948
|
+
> **前提条件**:文本层 PDF 传 `disable_ocr=True` 即可完全离线(无需 llama-server);不传时 marker 默认启用 VLM/OCR,
|
|
949
|
+
> 缺 `llama-server` 抛 `SpawnError`。扫描件 / 图片型 PDF / 图片输入要得到文字,必须有 llama.cpp 的 `llama-server`
|
|
950
|
+
> (`MARKER_LLAMA_CPP_BINARY`),否则只得到空 md 或一条整图引用。PDF 内嵌图片抽取不需要 `llama-server`。
|
|
951
|
+
|
|
952
|
+
## kit.docs.rc_docparser_kit —— 离线 docx → Markdown + Images
|
|
953
|
+
|
|
954
|
+
安装:`pip install "sdpy-kit[docx-parse]"`(依赖 `rc-docparser`,纯 Python,无模型 / OCR / GTK)
|
|
955
|
+
|
|
956
|
+
支持面:仅 `.docx`。产物与 `MarkerKit` 同一契约:`<out>/<stem>.md` + `<out>/images/`。
|
|
957
|
+
|
|
958
|
+
```python
|
|
959
|
+
from kit.docs.rc_docparser_kit import RcDocParserKit
|
|
960
|
+
|
|
961
|
+
md_path = RcDocParserKit.convert_to_dir("report.docx") # -> report/report.md + report/images/
|
|
962
|
+
md = RcDocParserKit.convert_to_md("report.docx") # 只取文本(图片不落盘)
|
|
963
|
+
result = RcDocParserKit.convert("report.docx", "out/doc")
|
|
964
|
+
if result.success:
|
|
965
|
+
print(result.md_path, len(result.image_paths))
|
|
966
|
+
```
|
|
967
|
+
|
|
968
|
+
| 方法 | 说明 |
|
|
969
|
+
|------|------|
|
|
970
|
+
| `is_supported(file_path) -> bool` | 是否 `.docx` |
|
|
971
|
+
| `convert_to_md(file_path) -> str` | 解析并返回 Markdown 文本 |
|
|
972
|
+
| `convert_to_dir(src_path, output_dir=None, *, extract_images=True) -> str` | 落盘 md + `images/`,返回 md 绝对路径 |
|
|
973
|
+
| `convert(src_path, output_dir=None, *, ...) -> RcDocParserResult` | 安全版:失败封装为结果对象 |
|
|
974
|
+
|
|
975
|
+
> 产物:`<out>/images/img-NNN-<sha1 前 10>.<ext>`(按出现顺序、内容哈希命名);无图不建空目录。
|
|
976
|
+
> 前提:中文标题依赖 `w:outlineLvl` 或「标题 N」样式(都没有时退化为正文);合并单元格表格会重建为
|
|
977
|
+
> 等宽 GFM(覆盖位留空,不输出 HTML `<table>`);页眉页脚/脚注不提取。纯本地,无需模型或 GPU。
|
|
938
978
|
|
|
939
979
|
## kit.crawl.wx_article_kit —— 微信公众号文章抓取存储
|
|
940
980
|
|
|
@@ -89,7 +89,7 @@ class Settings(BaseSettings):
|
|
|
89
89
|
default=600, ge=10, description="任务轮询总超时(秒),超时抛 MinerUError"
|
|
90
90
|
)
|
|
91
91
|
|
|
92
|
-
# Marker
|
|
92
|
+
# Marker 本地解析配置(marker-pdf,PDF/图片→Markdown+Images,模型本地运行)
|
|
93
93
|
MARKER_MODE: str | None = Field(
|
|
94
94
|
default=None,
|
|
95
95
|
description=(
|
|
@@ -25,7 +25,8 @@ Author: Clark Chang
|
|
|
25
25
|
- md2doc_kit: Md2DocKit Markdown 转 Word/PDF/HTML(pimd,extra: md2doc)
|
|
26
26
|
- docx_kit: DocxKit Word 模板动态填充(docxtpl,extra: docx)
|
|
27
27
|
- mineru_kit: MinerUKit MinerU 文档解析 API(requests,extra: mineru)
|
|
28
|
-
- marker_kit: MarkerKit
|
|
28
|
+
- marker_kit: MarkerKit PDF + 图片本地解析(marker-pdf,extra: marker)
|
|
29
|
+
- rc_docparser_kit: RcDocParserKit 离线 docx 解析(rc-docparser,extra: docx-parse)
|
|
29
30
|
|
|
30
31
|
本 __init__ 不导入任何成员:五个模块均携带重型可选依赖,保持
|
|
31
32
|
`import kit.docs` 在基础安装下零成本可用(对齐 kit.crawl 先例)。
|
|
@@ -18,21 +18,31 @@ Author: Clark Chang
|
|
|
18
18
|
"""
|
|
19
19
|
|
|
20
20
|
# date: 2026-09-23
|
|
21
|
-
"""
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
21
|
+
"""AnyDocKit —— 文档转 Markdown 工具类(基于 firecrawl-anydoc)
|
|
22
|
+
|
|
23
|
+
支持面:`.doc` / `.docx` / `.ppt` / `.pptx` / `.xls` / `.xlsx` / `.csv` / `.pdf`
|
|
24
|
+
(白名单为 anydoc 支持面的常用子集)。
|
|
25
|
+
|
|
26
|
+
实现内容:
|
|
27
|
+
- 全部静态方法、无内部状态;低层 `convert_to_md` 直接抛异常,高层 `convert`
|
|
28
|
+
返回 `AnyDocResult` 封装成功/失败,便于批量处理。
|
|
29
|
+
- PDF 结构非标(如知网件 `%%EOF` 后附加元数据)遇 `MalformedError` 时,用
|
|
30
|
+
pikepdf 重写为临时文件后重试一次;扫描页默认 reject,`ocr="hosted"` 走云端 OCR。
|
|
31
|
+
- 路径参数支持 `str` / `Path`;访问文件的方法内部 resolve 为绝对路径,
|
|
32
|
+
纯扩展名判断方法不做 resolve。
|
|
33
|
+
|
|
34
|
+
前提条件:
|
|
35
|
+
- 只产出 Markdown 文本,**不产出图片**(需要 `md + images/` 时用 `MarkerKit`
|
|
36
|
+
或 `RcDocParserKit`)。
|
|
37
|
+
- 云端 OCR 需 `FIRECRAWL_API_KEY`(或显式传 `api_key`)。
|
|
38
|
+
|
|
39
|
+
依赖:
|
|
40
|
+
- `firecrawl-anydoc`(extra `anydoc`,导入名 `anydoc`)+ `pikepdf`;
|
|
41
|
+
未安装时导入报错并提示安装命令。
|
|
42
|
+
|
|
43
|
+
异常:
|
|
44
|
+
- 沿用上游 `anydoc.ConvertError` 体系(不包装,保留 `MalformedError` /
|
|
45
|
+
`NeedsOcrError` 等子类可捕获性);`AnyDocError` 是该基类的别名。
|
|
36
46
|
"""
|
|
37
47
|
|
|
38
48
|
import io
|
|
@@ -44,12 +54,17 @@ try:
|
|
|
44
54
|
import anydoc
|
|
45
55
|
import pikepdf
|
|
46
56
|
except ImportError as e:
|
|
47
|
-
raise ImportError(
|
|
57
|
+
raise ImportError(
|
|
58
|
+
"anydoc_kit 需要可选依赖,请安装:pip install sdpy-kit[anydoc]"
|
|
59
|
+
) from e
|
|
48
60
|
|
|
49
61
|
from kit.config.log_config import get_default_logger
|
|
50
62
|
|
|
51
63
|
logger = get_default_logger(__name__)
|
|
52
64
|
|
|
65
|
+
# 异常别名:沿用 anydoc 的异常体系,不包装(保留上游子类可捕获性)
|
|
66
|
+
AnyDocError = anydoc.ConvertError
|
|
67
|
+
|
|
53
68
|
# kit 维护的扩展名白名单(用于本地快速校验与错误提示)。
|
|
54
69
|
# 注意:这是 anydoc 实际支持面的子集——anydoc 另支持 docm / pptm / ppsx / ppsm /
|
|
55
70
|
# xlsm / xlsb / pps / pot / odt / ods / odp / rtf / epub 等。
|
|
@@ -139,7 +154,7 @@ def _convert_with_repair(
|
|
|
139
154
|
|
|
140
155
|
|
|
141
156
|
@dataclass(frozen=True, slots=True)
|
|
142
|
-
class
|
|
157
|
+
class AnyDocResult:
|
|
143
158
|
"""文档转换结果对象
|
|
144
159
|
|
|
145
160
|
由 AnyDocKit.convert 返回,将成功与失败信息统一封装,调用方无需 try/except。
|
|
@@ -374,11 +389,11 @@ class AnyDocKit:
|
|
|
374
389
|
ocr: Literal["reject", "hosted"] = "reject",
|
|
375
390
|
api_key: str | None = None,
|
|
376
391
|
api_url: str | None = None,
|
|
377
|
-
) ->
|
|
392
|
+
) -> AnyDocResult:
|
|
378
393
|
"""安全转换文档为 Markdown,返回包含状态的结果对象
|
|
379
394
|
|
|
380
395
|
与 convert_to_md 不同,本方法不抛出转换异常,而是将成功/失败信息
|
|
381
|
-
封装到
|
|
396
|
+
封装到 AnyDocResult 中,便于批量处理或状态检查。
|
|
382
397
|
ocr/api_key/api_url 语义同 convert_to_md(PDF 自动修复对调用方
|
|
383
398
|
透明,失败信息封装在 result.error 中)。
|
|
384
399
|
边界:文件不存在 / 格式不支持 / 转换失败均封装为结果;若 file_path
|
|
@@ -391,7 +406,7 @@ class AnyDocKit:
|
|
|
391
406
|
api_url: 云端 OCR 服务地址;None 时回落 FIRECRAWL_API_URL
|
|
392
407
|
|
|
393
408
|
Returns:
|
|
394
|
-
|
|
409
|
+
AnyDocResult: 转换结果,包含 success/markdown/file_path/source_format/error
|
|
395
410
|
|
|
396
411
|
Example:
|
|
397
412
|
>>> result = AnyDocKit.convert("report.pdf")
|
|
@@ -410,7 +425,7 @@ class AnyDocKit:
|
|
|
410
425
|
except (ValueError, anydoc.ConvertError, OSError) as e:
|
|
411
426
|
# OSError 同时覆盖 FileNotFoundError(文件不存在)与文件读取失败
|
|
412
427
|
logger.warning(f"文档转换失败: {path.name}({type(e).__name__}): {e}")
|
|
413
|
-
return
|
|
428
|
+
return AnyDocResult(
|
|
414
429
|
success=False,
|
|
415
430
|
markdown="",
|
|
416
431
|
file_path=str(path),
|
|
@@ -418,7 +433,7 @@ class AnyDocKit:
|
|
|
418
433
|
error=f"{type(e).__name__}: {e}",
|
|
419
434
|
)
|
|
420
435
|
|
|
421
|
-
return
|
|
436
|
+
return AnyDocResult(
|
|
422
437
|
success=True,
|
|
423
438
|
markdown=markdown,
|
|
424
439
|
file_path=str(path),
|
|
@@ -18,29 +18,28 @@ Author: Clark Chang
|
|
|
18
18
|
"""
|
|
19
19
|
|
|
20
20
|
# date: 2026-09-14
|
|
21
|
-
"""docx
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
``title`` 参数生成(居中、加粗)。
|
|
21
|
+
"""DocxKit —— docx 模板动态填充工具类(基于 docxtpl)
|
|
22
|
+
|
|
23
|
+
支持面:Word 模板(`.docx`)+ 结构化数据 → 成品 docx;章节数量、层级、标题、
|
|
24
|
+
正文段落、多级列表、表格均由运行时数据决定,模板只承载版式骨架。
|
|
25
|
+
|
|
26
|
+
实现内容:
|
|
27
|
+
- 章节循环由模板中的 ``{%p for %}`` 承载;列表/表格以私有使用区字符组成的 marker
|
|
28
|
+
段落承载「位置 + 载荷」,渲染后由 python-docx 原位转换,规避 docxtpl 无法表达
|
|
29
|
+
动态层级与富内容的限制。
|
|
30
|
+
- 章节标题段使用锚点样式(默认 ``DocxSectionTitle``),渲染后按 ``level`` 重设为
|
|
31
|
+
``Heading N``,使模板绑定的 Word 多级列表自动编号生效。
|
|
32
|
+
- 有序列表按「连续组」克隆独立编号定义,避免多个列表被 Word 串成一条编号序列。
|
|
33
|
+
- 渲染开启 ``autoescape``;变量值控制字符沿用 docxtpl 约定(``\\n`` 软换行、
|
|
34
|
+
``\\a`` 新段落)。
|
|
35
|
+
- 全静态方法、无模块级可变状态;路径参数支持 `str` / `Path`。
|
|
36
|
+
|
|
37
|
+
前提条件:
|
|
38
|
+
- 模板需保留样式与书签骨架;字体/标题颜色统一由 `unify_font` /
|
|
39
|
+
`unify_heading_color` 处理,产物继承模板样式。
|
|
40
|
+
|
|
41
|
+
依赖:
|
|
42
|
+
- `docxtpl` + `python-docx`(extra `docx`);未安装时导入报错并提示安装命令。
|
|
44
43
|
"""
|
|
45
44
|
|
|
46
45
|
import re
|
|
@@ -18,33 +18,32 @@ Author: Clark Chang
|
|
|
18
18
|
"""
|
|
19
19
|
|
|
20
20
|
# date: 2026-10-09
|
|
21
|
-
"""
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
-
|
|
39
|
-
|
|
40
|
-
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
-
|
|
47
|
-
可通过 MARKER_LLAMA_CPP_BINARY 指定;否则用 disable_ocr=True 跳过 VLM。
|
|
21
|
+
"""MarkerKit —— PDF + 图片本地解析工具类(基于 marker-pdf)
|
|
22
|
+
|
|
23
|
+
支持面:`.pdf`、`.png`、`.jpg`、`.jpeg`、`.webp`、`.gif`、`.bmp`;其余后缀
|
|
24
|
+
(docx/pptx/xlsx/html/epub 等)抛 `ValueError` 并给出归属指引。
|
|
25
|
+
|
|
26
|
+
实现内容:
|
|
27
|
+
- 模型进程内单例(`create_model_dict` 开销极大),类级缓存 + 线程锁保护,
|
|
28
|
+
转换过程串行化,避免 marker 并发不稳定。
|
|
29
|
+
- 低层 `convert_to_md` / `convert_to_dir` 直接抛异常,高层 `convert` 返回
|
|
30
|
+
`MarkerResult` 封装成功/失败。
|
|
31
|
+
- 产物只落 `md + images/`(不写 marker 默认的 `_meta.json`);图片统一转 RGB
|
|
32
|
+
后保存、文件名取 basename 防路径穿越;md 引用改写为 `images/<文件名>`。
|
|
33
|
+
- 导入 marker 之前应用 HuggingFace 环境(镜像入口、禁用 Xet),否则权重下载
|
|
34
|
+
可能超时或挂起;日志不使用 emoji(Windows GBK 控制台无法编码)。
|
|
35
|
+
|
|
36
|
+
前提条件:
|
|
37
|
+
- 首次使用会自动下载模型权重(默认走 `MARKER_HF_ENDPOINT` 镜像)。
|
|
38
|
+
- **文本层 PDF**:显式 `disable_ocr=True` 可完全离线转换、无需 llama-server;
|
|
39
|
+
不传时默认启用 VLM/OCR 链路,缺 llama-server 抛 `SpawnError`。
|
|
40
|
+
- **扫描件 / 图片型 PDF、图片输入**:没有文本层,必须 OCR;marker 的识别模型
|
|
41
|
+
就是 VLM(由 llama.cpp 的 `llama-server` 承载),缺省时 `disable_ocr=True`
|
|
42
|
+
得到空正文、默认参数抛 `SpawnError`。
|
|
43
|
+
- **PDF 内嵌图片抽取**(`images/` 产物):不需要 llama-server,本地模型即可。
|
|
44
|
+
|
|
45
|
+
依赖:
|
|
46
|
+
- `marker-pdf`(extra `marker`,**不含 `[full]`**);未安装时导入报错并提示安装命令。
|
|
48
47
|
"""
|
|
49
48
|
|
|
50
49
|
import os
|
|
@@ -79,26 +78,19 @@ except ImportError as e:
|
|
|
79
78
|
) from e
|
|
80
79
|
|
|
81
80
|
# kit 维护的扩展名白名单(本地快速校验与错误提示)。
|
|
82
|
-
#
|
|
83
|
-
#
|
|
81
|
+
# 只含 PDF 与图片:marker 对其余格式(docx/pptx/xlsx/html/epub)的实现是「先转 PDF」
|
|
82
|
+
# 且依赖 weasyprint(GTK 系统库),Windows/离线不可用,故不声明(见 0.5.0 方案)。
|
|
84
83
|
_SUPPORTED_EXTENSIONS: frozenset[str] = frozenset(
|
|
85
84
|
{
|
|
86
|
-
# PDF
|
|
85
|
+
# PDF(文本层 PDF 用 disable_ocr=True 可离线转换)
|
|
87
86
|
".pdf",
|
|
88
|
-
#
|
|
87
|
+
# 图片(无文本层,必须 OCR:需 llama-server 才能得到正文)
|
|
89
88
|
".png",
|
|
90
89
|
".jpg",
|
|
91
90
|
".jpeg",
|
|
92
91
|
".webp",
|
|
93
92
|
".gif",
|
|
94
93
|
".bmp",
|
|
95
|
-
# Office(marker-pdf[full]:mammoth / python-pptx / openpyxl)
|
|
96
|
-
".docx",
|
|
97
|
-
".pptx",
|
|
98
|
-
".xlsx",
|
|
99
|
-
# 网页 / 电子书(marker-pdf[full]:weasyprint / ebooklib)
|
|
100
|
-
".html",
|
|
101
|
-
".epub",
|
|
102
94
|
}
|
|
103
95
|
)
|
|
104
96
|
|
|
@@ -141,9 +133,9 @@ class MarkerResult:
|
|
|
141
133
|
|
|
142
134
|
|
|
143
135
|
class MarkerKit:
|
|
144
|
-
"""Marker
|
|
136
|
+
"""Marker 本地文档解析工具类,将 PDF / 图片转为 Markdown + Images
|
|
145
137
|
|
|
146
|
-
|
|
138
|
+
仅支持 PDF 与图片(png/jpg/jpeg/webp/gif/bmp),产物形态为
|
|
147
139
|
「md + images/」一层(md 以 `images/<文件名>` 相对路径引用图片)。
|
|
148
140
|
|
|
149
141
|
使用前安装可选依赖::
|
|
@@ -164,17 +156,20 @@ class MarkerKit:
|
|
|
164
156
|
if result.success:
|
|
165
157
|
print(result.md_path, result.image_paths)
|
|
166
158
|
|
|
167
|
-
# 4.
|
|
168
|
-
md = MarkerKit.convert_to_md("
|
|
159
|
+
# 4. 离线纯文本层抽取(跳过 VLM/OCR,无需 llama-server)
|
|
160
|
+
md = MarkerKit.convert_to_md("report.pdf", disable_ocr=True)
|
|
169
161
|
|
|
170
162
|
# 5. 进程退出前释放模型
|
|
171
163
|
MarkerKit.shutdown()
|
|
172
164
|
|
|
173
165
|
注意:
|
|
166
|
+
- **文本层 PDF**:`disable_ocr=True` 可完全离线转换;不传时 marker 默认启用
|
|
167
|
+
VLM/OCR 链路,缺 llama-server 会抛 SpawnError。
|
|
168
|
+
- **扫描件/图片型 PDF、图片输入**:必须 OCR,需 llama.cpp 的 llama-server
|
|
169
|
+
(MARKER_LLAMA_CPP_BINARY 指定);缺省时 `disable_ocr=True` 得到空正文、
|
|
170
|
+
默认参数抛 SpawnError。PDF 内嵌图片抽取不受影响。
|
|
174
171
|
- 默认模式由 MARKER_MODE 决定,未配置时不写 mode,交由 marker 按设备自动
|
|
175
172
|
选择(CUDA→balanced,CPU/MPS→fast);可用 mode 参数显式覆盖。
|
|
176
|
-
- 非 NVIDIA 平台完整 VLM 能力需 llama.cpp 的 llama-server,缺失时可通过
|
|
177
|
-
disable_ocr=True 跳过(公式与扫描页不做 OCR)。
|
|
178
173
|
- 建议串行调用;模型与转换过程由内部锁保护,不做多线程并发转换。
|
|
179
174
|
"""
|
|
180
175
|
|
|
@@ -224,6 +219,8 @@ class MarkerKit:
|
|
|
224
219
|
if not MarkerKit.is_supported(path):
|
|
225
220
|
raise ValueError(
|
|
226
221
|
f"不支持的文件格式: {path.suffix or '<无扩展名>'},"
|
|
222
|
+
f"MarkerKit 仅处理 PDF 与图片"
|
|
223
|
+
f"(docx/pptx/xlsx/html/epub 已不由本工具处理),"
|
|
227
224
|
f"支持的格式: {', '.join(sorted(MarkerKit.SUPPORTED_EXTENSIONS))}"
|
|
228
225
|
)
|
|
229
226
|
return path
|