Spaces:
Sleeping
Sleeping
|
Download docs/zh/advanced/API/python.md from ryusaksun/PDFTranslate: direct link, hf CLI and curl.
- Browser
- Download file 9.16 kB
-
https://huggingface.co/spaces/ryusaksun/PDFTranslate/resolve/main/docs/zh/advanced/API/python.md
- Command line
-
hf download hf://spaces/ryusaksun/PDFTranslate/docs/zh/advanced/API/python.md
-
curl -L -o python.md https://huggingface.co/spaces/ryusaksun/PDFTranslate/resolve/main/docs/zh/advanced/API/python.md
9.16 kB
| > [!NOTE] | |
| > 本文档可能包含 AI 生成内容。虽然我们力求准确,但仍可能存在不准确之处。请通过以下方式报告任何问题: | |
| > | |
| > - [GitHub Issues](https://github.com/PDFMathTranslate-next/PDFMathTranslate-next/issues) | |
| > - 社区贡献(欢迎提交 PR!) | |
| ## Python API: do_translate_async_stream | |
| ### 概述 | |
| - do_translate_async_stream 是底层的异步入口点,用于翻译单个 PDF 并生成事件流(进度/错误/完成)。 | |
| - 它适用于构建您自己的 UI 或 CLI,在这些场景中您需要实时进度和对结果的完全控制。 | |
| - 它接受一个经过验证的 SettingsModel 和一个文件路径,并返回一个字典事件的异步生成器。 | |
| ### 签名 | |
| - 导入:`from pdf2zh_next.high_level import do_translate_async_stream` | |
| - 调用:`async for event in do_translate_async_stream(settings, file): ...` | |
| - 参数: | |
| - settings: SettingsModel。必须有效;该函数将调用 `settings.validate_settings()`。 | |
| - file: str | pathlib.Path。要翻译的单个 PDF 文件。必须存在。 | |
| 注意: | |
| - `settings.basic.input_files` 被此函数忽略;仅翻译给定的 `file`。 | |
| - 如果 `settings.basic.debug` 为 True,翻译在主进程中运行;否则在子进程中运行。两种情况下的事件模式是相同的。 | |
| ### 事件流契约 | |
| 异步生成器会产生以下类型的类 JSON 字典事件: | |
| - 阶段摘要事件:`stage_summary`(可选,可能首先出现) | |
| - 字段 | |
| - `type`:"stage_summary" | |
| - `stages`:对象列表 `{ "name": str, "percent": float }`,描述估计的工作分布 | |
| - `part_index`:对于此摘要事件可能为 0 | |
| - `total_parts`:总部分数(>= 1) | |
| - 进度事件:`progress_start`、`progress_update`、`progress_end` | |
| - 公共字段 | |
| - `type`:上述之一 | |
| - `stage`:人类可读的阶段名称(例如,"解析 PDF 并创建中间表示"、"翻译段落"、"保存 PDF") | |
| - `stage_progress`:[0, 100] 范围内的浮点数,指示当前阶段内的进度 | |
| - `overall_progress`:[0, 100] 范围内的浮点数,指示总体进度 | |
| - `part_index`:当前部分索引(对于进度事件通常从 1 开始) | |
| - `total_parts`:总部分数(>= 1)。大型文档可能会自动拆分。 | |
| - `stage_current`:阶段内的当前步骤 | |
| - `stage_total`:阶段内的总步骤数 | |
| - 完成事件:`finish` | |
| - 字段 | |
| - `type`:"finish" | |
| - `translate_result`:一个提供最终输出的**对象**(注意:不是字典,而是类实例) | |
| - `original_pdf_path`:输入 PDF 的路径 | |
| - `mono_pdf_path`:单语翻译 PDF 的路径(或 None) | |
| - `dual_pdf_path`:双语翻译 PDF 的路径(或 None) | |
| - `no_watermark_mono_pdf_path`:无水印单语输出的路径(如果已生成),否则为 None | |
| - `no_watermark_dual_pdf_path`:无水印双语输出的路径(如果已生成),否则为 None | |
| - `auto_extracted_glossary_path`:自动提取的术语表 CSV 的路径(或 None) | |
| - `total_seconds`:经过的秒数(浮点数) | |
| - `peak_memory_usage`:翻译过程中的近似峰值内存使用量(浮点数;具体单位取决于实现) | |
| - 错误事件:`error` | |
| - 字段 | |
| - `type`:"error" | |
| - `error`:人类可读的错误消息 | |
| - `error_type`:`BabeldocError`、`SubprocessError`、`IPCError`、`SubprocessCrashError` 等之一 | |
| - `details`:可选的详细信息(例如,原始错误或回溯) | |
| 重要行为: | |
| - 在进度开始之前,可能会发出一个可选的 `stage_summary`。 | |
| - 在某些故障情况下,生成器将首先产生一个 `error` 事件,然后抛出一个派生自 `TranslationError` 的异常。您应该既检查错误事件,又准备好捕获异常。 | |
| - `progress_update` 事件可能会重复出现相同的值;如有必要,消费者应进行去抖处理。 | |
| - 当您收到 `finish` 事件时,请停止消费流。 | |
| ### 最小使用示例(异步) | |
| ```python | |
| import asyncio | |
| from pathlib import Path | |
| from pdf2zh_next.high_level import do_translate_async_stream | |
| # Assume you already have a valid SettingsModel instance named `settings` | |
| # and a PDF file path | |
| async def translate_one(settings, pdf_path: str | Path): | |
| try: | |
| async for event in do_translate_async_stream(settings, pdf_path): | |
| etype = event.get("type") | |
| if etype == "stage_summary": | |
| # Optional pre-flight summary of stages | |
| stages = event.get("stages", []) | |
| print("Stage summary:", ", ".join(f"{s['name']}:{s['percent']:.2f}" for s in stages)) | |
| elif etype in {"progress_start", "progress_update", "progress_end"}: | |
| stage = event.get("stage") | |
| stage_prog = event.get("stage_progress") # 0..100 | |
| overall = event.get("overall_progress") # 0..100 | |
| part_i = event.get("part_index") | |
| part_n = event.get("total_parts") | |
| print(f"[{etype}] {stage} | stage {stage_prog:.1f}% | overall {overall:.1f}% (part {part_i}/{part_n})") | |
| elif etype == "error": | |
| # You will also get a raised exception after this yield | |
| print("[error]", event.get("error"), event.get("error_type")) | |
| elif etype == "finish": | |
| result = event["translate_result"] | |
| print("Done in", getattr(result, "total_seconds", None), "s") | |
| print("Mono:", getattr(result, "mono_pdf_path", None)) | |
| print("Dual:", getattr(result, "dual_pdf_path", None)) | |
| print("No-watermark Mono:", getattr(result, "no_watermark_mono_pdf_path", None)) | |
| print("No-watermark Dual:", getattr(result, "no_watermark_dual_pdf_path", None)) | |
| print("Glossary:", getattr(result, "auto_extracted_glossary_path", None)) | |
| print("Peak memory:", getattr(result, "peak_memory_usage", None)) | |
| break | |
| except Exception as exc: | |
| # Catch exceptions raised by the stream after an error event | |
| print("Translation failed:", exc) | |
| # asyncio.run(translate_one(settings, "/path/to/file.pdf")) | |
| ``` | |
| ### 取消 | |
| 您可以取消消耗流式传输的任务。取消操作会传播到底层的翻译进程。 | |
| ```python | |
| import asyncio | |
| from pdf2zh_next.high_level import do_translate_async_stream | |
| async def cancellable(settings, pdf): | |
| task = asyncio.create_task(_consume(settings, pdf)) | |
| await asyncio.sleep(1.0) # let it start | |
| task.cancel() | |
| try: | |
| await task | |
| except asyncio.CancelledError: | |
| print("Cancelled") | |
| async def _consume(settings, pdf): | |
| async for event in do_translate_async_stream(settings, pdf): | |
| if event["type"] == "finish": | |
| break | |
| ``` | |
| ### 示例事件形状 | |
| 阶段摘要事件(示例): | |
| ```json | |
| { | |
| "type": "stage_summary", | |
| "stages": [ | |
| {"name": "Parse PDF and Create Intermediate Representation", "percent": 0.1086}, | |
| {"name": "DetectScannedFile", "percent": 0.0188}, | |
| {"name": "Parse Page Layout", "percent": 0.1079} | |
| // ... more stages ... | |
| ], | |
| "part_index": 0, | |
| "total_parts": 1 | |
| } | |
| ``` | |
| Progress event (example): | |
| ```json | |
| { | |
| "type": "progress_update", | |
| "stage": "Translate Paragraphs", | |
| "stage_progress": 2.04, | |
| "stage_current": 1, | |
| "stage_total": 49, | |
| "overall_progress": 53.44, | |
| "part_index": 1, | |
| "total_parts": 1 | |
| } | |
| ``` | |
| 完成事件(示例): | |
| ```json | |
| { | |
| "type": "finish", | |
| "translate_result": { | |
| "original_pdf_path": "pdf2zh_files/<session>/table.pdf", | |
| "mono_pdf_path": "pdf2zh_files/<session>/table.zh-CN.mono.pdf", | |
| "dual_pdf_path": "pdf2zh_files/<session>/table.zh-CN.dual.pdf", | |
| "no_watermark_mono_pdf_path": "pdf2zh_files/<session>/table.no_watermark.zh-CN.mono.pdf", | |
| "no_watermark_dual_pdf_path": "pdf2zh_files/<session>/table.no_watermark.zh-CN.dual.pdf", | |
| "auto_extracted_glossary_path": "pdf2zh_files/<session>/table.zh-CN.glossary.csv", | |
| "total_seconds": 42.83, | |
| "peak_memory_usage": 4651.55 | |
| } | |
| } | |
| ``` | |
| 错误事件(示例): | |
| ```json | |
| { | |
| "type": "error", | |
| "error": "Babeldoc translation error: <message>", | |
| "error_type": "BabeldocError", | |
| "details": "<optional original error or traceback>" | |
| } | |
| ``` | |
| ### 注意事项与最佳实践 | |
| - 始终处理来自生成器的错误事件和异常。 | |
| - 在 `finish` 事件时中断循环,以避免不必要的工作。 | |
| - 在调用前确保 `file` 存在且 `settings.validate_settings()` 通过验证。 | |
| - 大型文档可能会被拆分;使用 `part_index/total_parts` 和 `overall_progress` 来驱动您的用户界面。 | |
| - 如果您的用户界面对重复、相同的更新敏感,请对 `progress_update` 进行防抖处理。 | |
| - `report_interval` (SettingsModel):仅控制 `progress_update` 事件的发射频率。它不影响 `stage_summary`、`progress_start`、`progress_end` 或 `finish`。默认值为 0.1 秒,允许的最小值为 0.05 秒。根据进度监视器逻辑,当 `stage_total <= 3` 时,更新不受 `report_interval` 的限制。 | |
| <div align="right"> | |
| <h6><small>本页面的部分内容由 GPT 翻译,可能包含错误。</small></h6> |