Metadata-Version: 2.5
Name: zleap_parser
Version: 0.1.1
Summary: zleap 文档解析 SDK：多格式文件/URL 解析为 markdown，经 zleap-sag 提取、octx 打包为 *.octx 归档
Author: zleap
License-Expression: MIT
License-File: LICENSE
License-File: LICENSES/Apache-2.0.txt
Keywords: document,markdown,octx,parser,sag
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Text Processing :: Markup
Classifier: Typing :: Typed
Requires-Python: >=3.11
Requires-Dist: beautifulsoup4>=4.15.0
Requires-Dist: cloakbrowser<0.4,>=0.3.26
Requires-Dist: octx>=0.1.4
Requires-Dist: pycryptodome>=3.19
Requires-Dist: pydantic<3,>=2.13.4
Requires-Dist: uuid6>=2025.0.1
Requires-Dist: zleap-sag>=0.7.1
Provides-Extra: dev
Requires-Dist: build>=1.5.0; extra == 'dev'
Requires-Dist: mypy>=2.3.0; extra == 'dev'
Requires-Dist: pytest-mock>=3.15.1; extra == 'dev'
Requires-Dist: pytest>=9.1.1; extra == 'dev'
Requires-Dist: ruff>=0.16.2; extra == 'dev'
Requires-Dist: twine>=7.0.0; extra == 'dev'
Provides-Extra: docx
Requires-Dist: docling>=2.73.1; extra == 'docx'
Requires-Dist: markitdown[docx]>=0.1.7; extra == 'docx'
Provides-Extra: media
Requires-Dist: docling-slim[format-video]<3,>=2.119.0; extra == 'media'
Requires-Dist: docling[asr]<3,>=2.119.0; extra == 'media'
Requires-Dist: setuptools<81,>=80; extra == 'media'
Provides-Extra: pdf
Requires-Dist: docling>=2.73.1; extra == 'pdf'
Requires-Dist: markitdown[pdf]>=0.1.7; extra == 'pdf'
Requires-Dist: pypdfium2>=5.12.1; extra == 'pdf'
Requires-Dist: rapidocr>=3.9.2; extra == 'pdf'
Provides-Extra: ppt
Requires-Dist: docling>=2.73.1; extra == 'ppt'
Requires-Dist: markitdown[pptx]>=0.1.7; extra == 'ppt'
Provides-Extra: redis
Requires-Dist: redis>=5.0; extra == 'redis'
Provides-Extra: xlsx
Requires-Dist: docling>=2.73.1; extra == 'xlsx'
Requires-Dist: markitdown[xlsx]>=0.1.7; extra == 'xlsx'
Requires-Dist: matplotlib>=3.11.1; extra == 'xlsx'
Requires-Dist: openpyxl>=3.1.5; extra == 'xlsx'
Description-Content-Type: text/markdown

# zleap_parser

`zleap_parser` 是 zleap 公司开源的**文档解析 SDK**：把本地文件或远程 HTML URL 解析为 markdown，经 `sag` 提取结构化产物后由 `octx` 打包为可传播的 `.octx` Package，供下游项目以 pip 方式集成使用。

> **当前状态：M1 基础框架已实施（开发中）。** 源码位于 `src/`（src 布局）：`Parser`（`parse` / `markdown_to_octx` / 自定义适配器注册）、同步浏览器 URL 采集器、内置适配器（txt / java / javascript / python / tft / image / pdf / docx / ppt / xlsx / html / xml / audio / video，插件化接入）、`zleap-sag` 提取封装与 `octx` 打包封装、旧文件下载器 SSRF 防护与本地二级缓存。计划文档见 `plan/`。

## 阅读顺序

1. **计划总览**（[`plan/PLAN.md`](./plan/PLAN.md)）：项目定位、里程碑划分（M1 解析器 / M2 连接器 / M3 公共服务）与门禁
2. **SDK 导入手册**（[`docs/sdk/install.md`](./docs/sdk/install.md)）：环境要求、安装、快速上手
3. **配置手册**（[`docs/sdk/configuration.md`](./docs/sdk/configuration.md)）：模块级一次配置，M1/M2 复用
4. **文档解析 API 手册**（[`docs/sdk/parse_api.md`](./docs/sdk/parse_api.md)）：`Parser` 用法与异常表
5. **连接器 API 手册**（[`docs/sdk/connector_api.md`](./docs/sdk/connector_api.md)）：数据源同步
6. **公共服务手册**（[`docs/service/`](./docs/service/)）：部署与 HTTP API

## 快速上手

需要 Python 3.11 或更高版本：

```bash
# 安装 Python 依赖
pip install -r requirements.txt   # 上游依赖（octx / zleap-sag / uuid6 / pycryptodome + 开发工具链）
pip install -e .                  # 或 python -m pip install zleap_parser

# 音频/视频转写另需 ASR extra 与系统 ffmpeg
pip install -e ".[media]"
# 使用 uv 运行音视频解析时启用 media extra
uv run --extra media python src/main.py doc/1.m4a

# URL 采集首次运行前安装并检查 CloakBrowser 浏览器二进制
python -m cloakbrowser install
python -m cloakbrowser info
```

模块级配置一次（`llm` 与 `embedding` 必填），`Parser` 与 `Connector` 自动继承复用：

```python
import zleap_parser
from zleap_parser import Parser, LLMConfig, EmbeddingConfig

zleap_parser.config(
    llm=LLMConfig(base_url="https://api.xxx.com/v1", api_key="sk-...", model="qwen3.6-flash"),
    embedding=EmbeddingConfig(model="Qwen/Qwen3-Embedding-0.6B", dimensions=1024),
)

parser = Parser()

# 本地文件走 magic bytes、格式适配器和文件内容缓存链路
result = parser.parse(file="/path/to/document.pdf")

# URL 只支持 HTML，走同步 CloakBrowser 正文采集链路
url_result = parser.parse(url="https://example.com/article")

# 两种入口都返回 {result: *.octx 归档文件路径, usage: LLM token 用量}
print(result["result"], result["usage"])     # usage: prompt_tokens / completion_tokens / total_tokens
print(url_result["result"], url_result["usage"])
```

本地冒烟测试（读取根目录 `.env` 初始化配置）：

```bash
cp .env.example .env      # 填入 LLM / Embedding 配置
python src/main.py --list                 # 打印生效配置
python src/main.py tests/fixtures/sample.txt   # 解析本地文件
python src/main.py                        # 默认解析 tests/fixtures/ 下全部样例
```

## 核心能力

| 能力 | 说明 | 手册 |
| --- | --- | --- |
| 文档解析（M1） | HTML URL / 本地文件 → markdown → `*.octx`；URL 正文规则与本地格式适配器分流 | [`parse_api.md`](./docs/sdk/parse_api.md) |
| 数据同步（M2） | 数据源（网页搜索等）文档清单 → 逐文档解析 → `*.octx` | [`connector_api.md`](./docs/sdk/connector_api.md) |
| 公共服务（M3） | 文档解析、连接器同步 HTTP API | [`service/`](./docs/service/) |

## 要点

- 产出物统一为 `*.octx` 归档文件：可读 markdown + 稳定身份、版本、完整性信息及可选的 chunks、events、entities、vectors。
- 文件类型以 **内容优先** 判定：PDF、图片、OOXML、HTML、XML 等二进制/结构化格式优先按 magic bytes 或内容特征识别；普通文本在确认没有 NUL/control bytes 后，源码类文件再按受控扩展名或 Python shebang 细分。
- **配置**：模块级 `zleap_parser.config(...)` 一次配置，`Parser`/`Connector` 自动继承；实例级 `*.config()` 与全局合并，便于高度自定义。
- **缓存**：本地文件解析使用 Redis 或本地二级缓存；URL 输入每次重新执行浏览器采集，不使用持久缓存。
- **URL 采集**：只校验 HTTP(S) URL 格式，不执行 DNS/IP 类型判定；每次调用独立创建并关闭 Browser、Context、Page，不使用进程级信号量，多个线程可并发调用。正文提取、正文图片筛选和 Markdown 转换沿用参考 webcrawler 的规则语义，正文质量不足严格抛 `ConversionError`。
- **URL 附件**：成功渲染的 `page.html` 与成功下载的正文图片随 `markdown_to_octx(source_files=[...])` 以同一 `document_id` 写入 OCTX；远程 PDF/图片/普通文件不接受。
- **pdf 兜底链路**：用户自定义适配器 → Docling → markitdown（其他兜底可追加）。
- **docx 兜底链路**：用户自定义适配器 → Docling → markitdown；DOCX 内嵌图片随原文件写入 OCTX 附件。
- **ppt 兜底链路**：用户自定义适配器 → Docling → markitdown；按 OOXML 内容识别 PPTX，即使扩展名为 `.ppt` 也可解析。
- **xlsx 兜底链路**：用户自定义适配器 → Docling → markitdown；按 OOXML 内容识别 XLSX，保留工作表表格，并提取内嵌位图、渲染常见柱状图/折线图/饼图作为 OCTX 附件。
- **音视频 ASR 链路**：音频/视频先由 FFmpeg 统一抽取为 16 kHz、16-bit、单声道 WAV 并做 -23 LUFS 响度归一化，再由 Docling Whisper 转写并执行说话人分离；输出复用聊天数据源的会话 Markdown 结构，包含相对时间段与 `speaker_1`、`speaker_2` 等说话人标签。
- **源码文本链路**：txt 保持原文直出；java / javascript / python / tft 包装为带语言标识的 Markdown 代码块，避免源码被当作 Markdown 语法解析。

- **异常**：所有 API 失败均抛 `ZleapParserError` 及子类（`ConfigError` / `AdapterNotFoundError` / `ConversionError` / `DownloadError` / `TimeoutError` / `ExtractError`），不裸奔底层异常；URL 采集编排层保留已有 SDK 异常，并将其他内部异常包装为 `ConversionError`。

## 边界

- 不定义搜索 API、召回算法或 Agent 协议；解析与归档之外的能力由下游自行实现。
- 核心解析框架与格式实现解耦：新增格式即新增适配器，不改核心代码。
- 上游参考实现：`sag`（markdown 结构化提取）与 `octx`（`*.octx` 打包）位于本地仓库 `../SAG` 与 `../open-context`。
- URL 正文规则直接复制 MinerU HTML webcrawler 的正文抽取器（本地命名为 `article_extractor.py`）；许可与归属见 [`THIRD_PARTY_NOTICES.md`](./THIRD_PARTY_NOTICES.md) 及 `LICENSES/`。
