Translate Markdown docs into multiple languages using LLMs with smart caching and custom prompts
Project description
mdxlate
Translate Markdown docs into multiple languages using LLMs.
Batteries included: prompt template, CLI, OpenAI/OpenRouter provider switch, and a simple change-detection cache.
📚 Documentation
- Getting Started – Installation and quick start
- CLI Reference – Complete command-line guide
- Programmatic Usage – Python API and examples
- Caching System – How the cache works
- Custom Prompt – Customize translations
- Error Handling – Failure recovery
- Development Guide – Contributing
- FAQ – Troubleshooting
Install
pip install -e .
Quick start
- Initialize the editable prompt (creates
~/.mdxlate/translation_instruction.txt):
mdx init
- Run translations:
export OPENAI_API_KEY=sk-... # or use OPEN_ROUTER_API_KEY when provider=openrouter
mdx run docs_src out --languages de fr --model gpt-4o-mini
Result: translated files under out/<lang>/..., preserving the original folder structure.
A cache file .mdxlate.hashes.json is written in docs_src.
CLI
mdx run [OPTIONS] DOCS_SRC OUT_DIR
Options
--base-language TEXT– Base language (default:en)--languages TEXT...– Target languages, space-separated (default:de)--model TEXT– Model name (default:gpt-4o-mini)--provider [openai|openrouter]– Backend provider (default:openai)--api-key TEXT– API key (overrides env)--api-env-key TEXT– Env var to read (default:OPENAI_API_KEY)--base-url TEXT– Custom base URL (e.g., OpenRouter)--prompt-path PATH– Use a custom prompt file instead of the default--force– Force re-translation, bypassing cache--cache-dir PATH– Directory for cache file (defaults to source directory)
Examples
OpenAI (env var):
export OPENAI_API_KEY=sk-...
mdx run docs_src out --languages de fr --model gpt-4o-mini
OpenRouter:
export OPEN_ROUTER_API_KEY=or-...
mdx run docs_src out --languages de --provider openrouter --model google/gemini-2.5-pro
Custom prompt:
mdx run docs_src out --languages de --prompt-path ./my_prompt.txt
Custom cache directory (for read-only CI/CD):
mdx run docs_src out --languages de --cache-dir /tmp
Error Handling
If any file fails to translate (e.g., due to API errors, rate limits, or network issues), mdxlate will:
- Continue processing other files instead of crashing
- Save the cache for successful translations
- Generate a failure report at
.mdxlate.failures.jsonwith details about what failed
Example failure report:
{
"failures": [
{
"file": "docs/advanced.md",
"error": "Rate limit exceeded",
"error_type": "RateLimitError"
}
]
}
After fixing the issue (e.g., waiting for rate limits to reset), re-run the translation. Only failed files will be retried thanks to the cache.
Behavior
- Prompt: default lives at
~/.mdxlate/translation_instruction.txt(created bymdx init). You can edit it freely or pass--prompt-path. - Cache: re-translation is skipped if file bytes + prompt content + model + language are unchanged. By default, cache is written to source directory as
.mdxlate.hashes.json. Use--cache-dirfor read-only environments. - Structure: each language gets its own mirror tree under
OUT_DIR/<lang>/.
Programmatic use
from pathlib import Path
from mdxlate.start_translation import start_translation
start_translation(
docs_src=Path("docs_src"),
out_dir=Path("out"),
base_language="en",
languages=["de", "fr"],
model="gpt-4o-mini",
provider="openai", # or "openrouter"
api_key=None, # pass explicitly or rely on env
base_url=None,
prompt_path=None,
cache_dir=None, # optional: specify custom cache directory
)
Integrations
- Jekyll – Complete guide for translating Jekyll sites with frontmatter preservation
Files of interest
mdxlate/cli.py– Typer CLI (mdx init,mdx run)mdxlate/client.py–make_client()factory (OpenAI/OpenRouter)mdxlate/translator.py– translation, hashing, and I/Omdxlate/translation_instruction.txt– default prompt template
Development
Setup
pip install -e .
pip install ruff mypy pytest
Code Quality
This project uses Ruff for linting and formatting, and Mypy for type checking:
# Lint code
ruff check src tests
# Auto-fix linting issues
ruff check --fix src tests
# Format code
ruff format src tests
# Type check
mypy src --ignore-missing-imports
# Run tests
pytest tests/
CI/CD
The .github/workflows/quality.yml workflow runs automatically on every push and PR:
- ✅ Ruff linting
- ✅ Ruff formatting check
- ✅ Mypy type checking
License
MIT
Layout
repo/
pyproject.toml
README.md
src/
mdxlate/
__init__.py
cli.py
client.py
translator.py
start_translation.py
translation_instruction.txt
tests/ # optional
main.py # optional local test runner
---
# pyproject.toml
```toml
[build-system]
requires = ["setuptools>=69", "wheel"]
build-backend = "setuptools.build_meta"
[project]
name = "mdxlate"
version = "0.1.0"
description = "Translate Markdown docs into multiple languages using LLMs."
readme = "README.md"
requires-python = ">=3.10"
license = { text = "MIT" }
authors = [{ name = "Tobias Bück" }]
dependencies = [
"typer>=0.12",
"openai>=1.40",
"tenacity>=8.2",
]
[project.scripts]
mdx = "mdxlate.cli:app"
[tool.setuptools]
package-dir = {"" = "src"}
[tool.setuptools.packages.find]
where = ["src"]
include = ["mdxlate*"]
[tool.setuptools.package-data]
mdxlate = ["translation_instruction.txt"]
[tool.pytest.ini_options]
addopts = "-q"
testpaths = ["tests"]
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file mdxlate-1.1.5.tar.gz.
File metadata
- Download URL: mdxlate-1.1.5.tar.gz
- Upload date:
- Size: 17.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.8.22
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0584a1591b44e814e570de2bf8604fa12ce9818d2dce291c34ca1c264a03a220
|
|
| MD5 |
b04eae9d678c2751639c1bf0e62a2a8d
|
|
| BLAKE2b-256 |
f55dbf167ce428f0d9455fc30fddd46b881b59fc9dc1dbc6c0185bff7646509c
|
File details
Details for the file mdxlate-1.1.5-py3-none-any.whl.
File metadata
- Download URL: mdxlate-1.1.5-py3-none-any.whl
- Upload date:
- Size: 12.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.8.22
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
46396d6fd259230cd669ec6708250209f123b2e8cf4d465063c6f33b795cee6f
|
|
| MD5 |
5a5b8101c20a1710e379ef17d7af4562
|
|
| BLAKE2b-256 |
83f7dc57fa8d7d7837f22888980fe344359f48c0486621393852154bf5f0f532
|