
Research
/Security News
9 Malicious NuGet Packages Deliver Time-Delayed Destructive Payloads
Socket researchers discovered nine malicious NuGet packages that use time-delayed payloads to crash applications and corrupt industrial control systems.
docutranslate
Advanced tools
A lightweight local file translation tool based on Large Language Models
pdf, docx, xlsx, md, txt, json, epub,
srt, ass, and more.docling and mineru PDF parsing engines.jsonpath-ng
syntax).docx and xlsx files while preserving their original formatting (
does not yet support doc or xls files).docling local PDF parser).When translating
QQ Discussion Group: 1047781902
UI Interface:

Academic Paper Translation:

Novel Translation:

For users who want to get started quickly, we provide all-in-one packages on GitHub Releases. Simply download, unzip, and enter your AI platform API Key to begin.
minerU engine to parse PDF documents. Choose this version if
you don't need local PDF parsing (recommended).docling local PDF parsing engine. Choose this version if
you need local PDF parsing.# Basic installation
pip install docutranslate
# To use docling for local PDF parsing
pip install docutranslate[docling]
# Initialize environment
uv init
# Basic installation
uv add docutranslate
# Install docling extension
uv add docutranslate[docling]
# Initialize environment
git clone https://github.com/xunbu/docutranslate.git
cd docutranslate
uv sync
The core of the new DocuTranslate is the Workflow. Each workflow is a complete, end-to-end translation pipeline designed for a specific file type. Instead of interacting with a single large class, you select and configure a workflow based on your file type.
The basic usage flow is as follows:
MarkdownBasedWorkflow or TXTWorkflow.MarkdownBasedWorkflowConfig). This object contains all necessary sub-configurations, such as:
.read_*() and .translate() / .translate_async() methods..export_to_*() or .save_as_*() methods to get or save the translation results.| Workflow | Use Case | Input Formats | Output Formats | Core Config Class |
|---|---|---|---|---|
MarkdownBasedWorkflow | Processes rich text documents like PDF, Word, images. Flow: File -> Markdown -> Translate -> Export. | .pdf, .docx, .md, .png, .jpg, etc. | .md, .zip, .html | MarkdownBasedWorkflowConfig |
TXTWorkflow | Processes plain text documents. Flow: txt -> Translate -> Export. | .txt and other plain text formats | .txt, .html | TXTWorkflowConfig |
JsonWorkflow | Processes JSON files. Flow: json -> Translate -> Export. | .json | .json, .html | JsonWorkflowConfig |
DocxWorkflow | Processes docx files. Flow: docx -> Translate -> Export. | .docx | .docx, .html | DocxWorkflowConfig |
XlsxWorkflow | Processes xlsx files. Flow: xlsx -> Translate -> Export. | .xlsx, .csv | .xlsx, .html | XlsxWorkflowConfig |
SrtWorkflow | Processes srt files. Flow: srt -> Translate -> Export. | .srt | .srt, .html | SrtWorkflowConfig |
EpubWorkflow | Processes epub files. Flow: epub -> Translate -> Export. | .epub | .epub, .html | EpubWorkflowConfig |
HtmlWorkflow | Processes html files. Flow: html -> Translate -> Export. | .html, .htm | .html | HtmlWorkflowConfig |
You can export to PDF format in the interactive interface.
For ease of use, DocuTranslate provides a full-featured Web interface and RESTful API.
Start the service:
# Start the service, listening on port 8010 by default
docutranslate -i
# Start on a specific port
docutranslate -i -p 8011
# You can also specify the port via an environment variable
export DOCUTRANSLATE_PORT=8011
docutranslate -i
http://127.0.0.1:8010 (or your specified port) in your
browser.http://127.0.0.1:8010/docs.MarkdownBasedWorkflow)This is the most common use case. We will use the minerU engine to convert the PDF to Markdown and then use an LLM for
translation. This example uses the asynchronous method.
import asyncio
from docutranslate.workflow.md_based_workflow import MarkdownBasedWorkflow, MarkdownBasedWorkflowConfig
from docutranslate.converter.x2md.converter_mineru import ConverterMineruConfig
from docutranslate.translator.ai_translator.md_translator import MDTranslatorConfig
from docutranslate.exporter.md.md2html_exporter import MD2HTMLExporterConfig
async def main():
# 1. Build translator configuration
translator_config = MDTranslatorConfig(
base_url="https://open.bigmodel.cn/api/paas/v4", # AI Platform Base URL
api_key="YOUR_ZHIPU_API_KEY", # AI Platform API Key
model_id="glm-4-air", # Model ID
to_lang="English", # Target language
chunk_size=3000, # Text chunk size
concurrent=10, # Concurrency level
# glossary_generate_enable=True, # Enable automatic glossary generation
# glossary_dict={"Jobs":"乔布斯"}, # Pass in a glossary
# system_proxy_enable=True, # Enable system proxy
)
# 2. Build converter configuration (using minerU)
converter_config = ConverterMineruConfig(
mineru_token="YOUR_MINERU_TOKEN", # Your minerU Token
formula_ocr=True # Enable formula recognition
)
# 3. Build main workflow configuration
workflow_config = MarkdownBasedWorkflowConfig(
convert_engine="mineru", # Specify the parsing engine
converter_config=converter_config, # Pass the converter config
translator_config=translator_config, # Pass the translator config
html_exporter_config=MD2HTMLExporterConfig(cdn=True) # HTML export configuration
)
# 4. Instantiate the workflow
workflow = MarkdownBasedWorkflow(config=workflow_config)
# 5. Read the file and execute translation
print("Reading and translating the file...")
workflow.read_path("path/to/your/document.pdf")
await workflow.translate_async()
# Or use the synchronous method
# workflow.translate()
print("Translation complete!")
# 6. Save the results
workflow.save_as_html(name="translated_document.html")
workflow.save_as_markdown_zip(name="translated_document.zip")
workflow.save_as_markdown(name="translated_document.md") # Markdown with embedded images
print("Files saved to the ./output folder.")
# Or get the content strings directly
html_content = workflow.export_to_html()
html_content = workflow.export_to_markdown()
# print(html_content)
if __name__ == "__main__":
asyncio.run(main())
TXTWorkflow)For plain text files, the process is simpler as it doesn't require a document parsing (conversion) step. This example uses the asynchronous method.
import asyncio
from docutranslate.workflow.txt_workflow import TXTWorkflow, TXTWorkflowConfig
from docutranslate.translator.ai_translator.txt_translator import TXTTranslatorConfig
from docutranslate.exporter.txt.txt2html_exporter import TXT2HTMLExporterConfig
async def main():
# 1. Build translator configuration
translator_config = TXTTranslatorConfig(
base_url="https://api.openai.com/v1/",
api_key="YOUR_OPENAI_API_KEY",
model_id="gpt-4o",
to_lang="Chinese",
)
# 2. Build main workflow configuration
workflow_config = TXTWorkflowConfig(
translator_config=translator_config,
html_exporter_config=TXT2HTMLExporterConfig(cdn=True)
)
# 3. Instantiate the workflow
workflow = TXTWorkflow(config=workflow_config)
# 4. Read the file and execute translation
workflow.read_path("path/to/your/notes.txt")
await workflow.translate_async()
# Or use the synchronous method
# workflow.translate()
# 5. Save the result
workflow.save_as_txt(name="translated_notes.txt")
print("TXT file saved.")
# You can also export the translated plain text
text = workflow.export_to_txt()
if __name__ == "__main__":
asyncio.run(main())
JsonWorkflow)This example uses the asynchronous method. The json_paths item in JsonTranslatorConfig needs to specify the JSON
paths to be translated (conforming to the jsonpath-ng syntax). Only values matching these paths will be translated.
import asyncio
from docutranslate.exporter.js.json2html_exporter import Json2HTMLExporterConfig
from docutranslate.translator.ai_translator.json_translator import JsonTranslatorConfig
from docutranslate.workflow.json_workflow import JsonWorkflowConfig, JsonWorkflow
async def main():
# 1. Build translator configuration
translator_config = JsonTranslatorConfig(
base_url="https://api.openai.com/v1/",
api_key="YOUR_OPENAI_API_KEY",
model_id="gpt-4o",
to_lang="Chinese",
json_paths=["$.*", "$.name"] # Conforms to jsonpath-ng syntax, values at matching paths will be translated
)
# 2. Build main workflow configuration
workflow_config = JsonWorkflowConfig(
translator_config=translator_config,
html_exporter_config=Json2HTMLExporterConfig(cdn=True)
)
# 3. Instantiate the workflow
workflow = JsonWorkflow(config=workflow_config)
# 4. Read the file and execute translation
workflow.read_path("path/to/your/notes.json")
await workflow.translate_async()
# Or use the synchronous method
# workflow.translate()
# 5. Save the result
workflow.save_as_json(name="translated_notes.json")
print("JSON file saved.")
# You can also export the translated JSON text
text = workflow.export_to_json()
if __name__ == "__main__":
asyncio.run(main())
DocxWorkflow)This example uses the asynchronous method.
import asyncio
from docutranslate.exporter.docx.docx2html_exporter import Docx2HTMLExporterConfig
from docutranslate.translator.ai_translator.docx_translator import DocxTranslatorConfig
from docutranslate.workflow.docx_workflow import DocxWorkflowConfig, DocxWorkflow
async def main():
# 1. Build translator configuration
translator_config = DocxTranslatorConfig(
base_url="https://api.openai.com/v1/",
api_key="YOUR_OPENAI_API_KEY",
model_id="gpt-4o",
to_lang="Chinese",
insert_mode="replace", # Options: "replace", "append", "prepend"
separator="\n", # Separator used in "append" and "prepend" modes
)
# 2. Build main workflow configuration
workflow_config = DocxWorkflowConfig(
translator_config=translator_config,
html_exporter_config=Docx2HTMLExporterConfig(cdn=True)
)
# 3. Instantiate the workflow
workflow = DocxWorkflow(config=workflow_config)
# 4. Read the file and execute translation
workflow.read_path("path/to/your/notes.docx")
await workflow.translate_async()
# Or use the synchronous method
# workflow.translate()
# 5. Save the result
workflow.save_as_docx(name="translated_notes.docx")
print("DOCX file saved.")
# You can also export the translated DOCX as bytes
text_bytes = workflow.export_to_docx()
if __name__ == "__main__":
asyncio.run(main())
XlsxWorkflow)This example uses the asynchronous method.
import asyncio
from docutranslate.exporter.xlsx.xlsx2html_exporter import Xlsx2HTMLExporterConfig
from docutranslate.translator.ai_translator.xlsx_translator import XlsxTranslatorConfig
from docutranslate.workflow.xlsx_workflow import XlsxWorkflowConfig, XlsxWorkflow
async def main():
# 1. Build translator configuration
translator_config = XlsxTranslatorConfig(
base_url="https://api.openai.com/v1/",
api_key="YOUR_OPENAI_API_KEY",
model_id="gpt-4o",
to_lang="Chinese",
insert_mode="replace", # Options: "replace", "append", "prepend"
separator="\n", # Separator used in "append" and "prepend" modes
)
# 2. Build main workflow configuration
workflow_config = XlsxWorkflowConfig(
translator_config=translator_config,
html_exporter_config=Xlsx2HTMLExporterConfig(cdn=True)
)
# 3. Instantiate the workflow
workflow = XlsxWorkflow(config=workflow_config)
# 4. Read the file and execute translation
workflow.read_path("path/to/your/notes.xlsx")
await workflow.translate_async()
# Or use the synchronous method
# workflow.translate()
# 5. Save the result
workflow.save_as_xlsx(name="translated_notes.xlsx")
print("XLSX file saved.")
# You can also export the translated XLSX as bytes
text_bytes = workflow.export_to_xlsx()
if __name__ == "__main__":
asyncio.run(main())
HtmlWorkflow, EpubWorkflow)Here is an example using asynchronous mode.
# HtmlWorkflow
from docutranslate.translator.ai_translator.html_translator import HtmlTranslatorConfig
from docutranslate.workflow.html_workflow import HtmlWorkflowConfig, HtmlWorkflow
async def html():
# 1. Create translator configuration
translator_config = HtmlTranslatorConfig(
base_url="https://api.openai.com/v1/",
api_key="YOUR_OPENAI_API_KEY",
model_id="gpt-4o",
to_lang="Chinese",
insert_mode="replace", # Options: "replace", "append", "prepend"
separator="\n", # Separator used for "append" and "prepend" modes
)
# 2. Create main workflow configuration
workflow_config = HtmlWorkflowConfig(
translator_config=translator_config,
)
workflow_html = HtmlWorkflow(config=workflow_config)
# EpubWorkflow
from docutranslate.exporter.epub.epub2html_exporter import Epub2HTMLExporterConfig
from docutranslate.translator.ai_translator.epub_translator import EpubTranslatorConfig
from docutranslate.workflow.epub_workflow import EpubWorkflowConfig, EpubWorkflow
async def epub():
# 1. Create translator configuration
translator_config = EpubTranslatorConfig(
base_url="https://api.openai.com/v1/",
api_key="YOUR_OPENAI_API_KEY",
model_id="gpt-4o",
to_lang="Chinese",
insert_mode="replace", # Options: "replace", "append", "prepend"
separator="\n", # Separator used for "append" and "prepend" modes
)
# 2. Create main workflow configuration
workflow_config = EpubWorkflowConfig(
translator_config=translator_config,
html_exporter_config=Epub2HTMLExporterConfig(cdn=True),
)
workflow_epub = EpubWorkflow(config=workflow_config)
The translation feature relies on large language models. You need to obtain a base_url, api_key, and model_id from
the respective AI platform.
Recommended models: Volcengine's
doubao-seed-1-6-flashanddoubao-seed-1-6series, Zhipu'sglm-4-flash, Alibaba Cloud'sqwen-plusandqwen-flash, Deepseek'sdeepseek-chat, etc.
302.AI👈 Register through this link to enjoy a $1 free credit
| Platform Name | Get API Key | Base URL |
|---|---|---|
| ollama | http://127.0.0.1:11434/v1 | |
| lm studio | http://127.0.0.1:1234/v1 | |
| 302.AI | Click to get | https://api.302.ai/v1 |
| openrouter | Click to get | https://openrouter.ai/api/v1 |
| openai | Click to get | https://api.openai.com/v1/ |
| gemini | Click to get | https://generativelanguage.googleapis.com/v1beta/openai/ |
| deepseek | Click to get | https://api.deepseek.com/v1 |
| Zhipu AI (智谱ai) | Click to get | https://open.bigmodel.cn/api/paas/v4 |
| Tencent Hunyuan (腾讯混元) | Click to get | https://api.hunyuan.cloud.tencent.com/v1 |
| Alibaba Cloud Bailian (阿里云百炼) | Click to get | https://dashscope.aliyuncs.com/compatible-mode/v1 |
| Volcengine (火山引擎) | Click to get | https://ark.cn-beijing.volces.com/api/v3 |
| SiliconFlow (硅基流动) | Click to get | https://api.siliconflow.cn/v1 |
| DMXAPI | Click to get | https://www.dmxapi.cn/v1 |
| Juguang AI (聚光AI) | Click to get | https://ai.juguang.chat/v1 |
If you choose mineru as your document parsing engine (convert_engine="mineru"), you need to apply for a free token.
Note: minerU Tokens are valid for 14 days. Please create a new one after expiration.
If you choose docling as your document parsing engine (convert_engine="docling"), it will download the required
models from Hugging Face upon first use.
A better option is to download
docling_artifact.zipfrom GitHub Releases and extract it to your working directory.
Solutions for network issues when downloading docling models:
HF_ENDPOINT and restart your IDE or
terminal.
HF_ENDPOINT=https://hf-mirror.com
import os
os.environ['HF_ENDPOINT'] = 'https://hf-mirror.com'
docling_artifact.zip from GitHub Releases.from docutranslate.converter.x2md.converter_docling import ConverterDoclingConfig
converter_config = ConverterDoclingConfig(
artifact="./docling_artifact", # Path to the extracted folder
code_ocr=True,
formula_ocr=True
)
Q: Why is the translated text still in the original language?
A: Check the logs for errors. It's usually due to an overdue payment on the AI platform or network issues (check if you
need to enable the system proxy).
Q: Port 8010 is already in use. What should I do?
A: Use the -p parameter to specify a new port, or set the DOCUTRANSLATE_PORT environment variable.
Q: Does it support translating scanned PDFs?
A: Yes. Please use the mineru parsing engine, which has powerful OCR capabilities.
Q: Why is the first PDF translation very slow?
A: If you are using the docling engine, it needs to download models from Hugging Face on its first run. Please refer
to the "Network Issues Solutions" section above to speed up this process.
Q: How can I use it in an intranet (offline) environment?
A: Absolutely. You need to meet the following conditions:
base_url in TranslatorConfig.docling engine and download the model package in
advance as described in the "Offline Usage" section above.Q: How does the PDF parsing cache mechanism work?
A: MarkdownBasedWorkflow automatically caches the results of document parsing (file-to-Markdown conversion) to avoid
repetitive, time-consuming parsing. The cache is stored in memory by default and records the last 10 parses. You can
change the cache size using the DOCUTRANSLATE_CACHE_NUM environment variable.
Q: How can I make the software use a proxy?
A: By default, the software does not use the system proxy. You can enable it by setting system_proxy_enable=True in
TranslatorConfig.
Your support is welcome! Please mention the reason for your donation in the memo.
FAQs
We found that docutranslate demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Research
/Security News
Socket researchers discovered nine malicious NuGet packages that use time-delayed payloads to crash applications and corrupt industrial control systems.

Security News
Socket CTO Ahmad Nassri discusses why supply chain attacks now target developer machines and what AI means for the future of enterprise security.

Security News
Learn the essential steps every developer should take to stay secure on npm and reduce exposure to supply chain attacks.