This program uses several cloud and local AI models to translate gettext PO files.
- Supports several backends, both local HuggingFace models, self-hosted Ollama, and remote API services.
- Extensible. You can write your own translation plugins.
- Supports fuzzy translations.
- Supports automatic translation of missing entries.
- Supports tagging of AI-generated translations.
- Supports automatic detection of language.
- Supports msgctxt field for better contextual translation.
See the README.md file in each plugin's directory for examples and information about the backends. Currently this system works with the following backends:
- Azure AI Translator (README): remote API, commercial, API key required.
- OpenAI ChatGPT (README): remote API, several models, commercial, API key required.
- Google Gemini (README): remote API, several models, commercial with a free layer, API key required.
- MarianMT (README): local HuggingFace Helsinki-NLP model, free, auth token might be required.
- NLLB (README): local HuggingFace NLLB model, free, auth token might be required.
- Ollama (README): self-hosted (by yourself) Ollama server running free models.
The command line tool supports the following arguments:
--info: Shows information about the backend.--backend: Which backend to use.--po: The path to the .po file.--src: The source language.--dst: The language to translate to.--fuzzy: Fuzzy translations?--context: Optional default translation context for msgid without msgctxt.--ascribe: Include a comment in each entry indicating that it was translated with AI.--config: Path to the YAML configuration file for the backend.--verbose: Show useful information. Possible values: debug, info, warning, error, critical. Default: warning.--help: Shows the help message.
To avoid cluttering of the command line arguments, each backend has its own configuration file, in YAML format. This file contains the backend's-specific options, as described in each plugin's README.md file. Please refer to those files (linked above), or use the --info argument todisplay the README.md and list the available options for each backend (view usage example below).
You must specify the path to the configuration file using the --config argument.
A sample configuration file for each backend is provided in each plugin's directory, under translators/gettext-translator-<backend>/<backend>-sample.yaml.
First, change to the src/gettext_translator directory:
cd src/gettext_translator/You can view the README file for the plugin and which options are available for it using the --info argument:
python gettext_translator.py --info --backend chatgptShow information about the ChatGPT backend:
python gettext_translator.py --info --backend chatgptTranslate using the Azure AI Translator backend:
python gettext_translator.py --backend azure --src es --dst de_DE --config ../../translators/gettext-translator-azure/azure-sample.yaml --po ../../example/messages.poTranslate using the ChatGPT backend, adding a comment attributing translations to AI:
python gettext_translator.py --backend chatgpt --src es --dst de_DE --config ../../translators/gettext-translator-chatgpt/chatgpt-sample.yaml --po ../../example/messages.po --ascribe=trueSee the requirements.txt files in the main CLI program directory and in each of the plugin directories.
You can install the main CLI program and each plugin using pip from their respective root directories. For example:
Change to a translator directory, for example:
cd translators/gettext-translator-azure/Install it:
pip install .If you want to modify something, install the plugins in editable mode:
pip install -e .This software was designed with extensibility as a priority, so it's not restricted to a single service or provider. It is based on an auto-discovery plugin system, and users can create additional plugins as needed.
- It is recommended that you learn about gettext and the format of PO files. But of course, if you are reading this, you should already know it.
- Why gettext?
- It uses full strings in the source language as keys. This is the most relevant reason, as it means you don't have to search for abstract keys like
page.title.hellooritem.specification. While that approach may work for a few strings, it becomes complicated and chaotic with hundreds or thousands of them. - The original key string is used as a fallback. If a translation doesn't exist, the original string is displayed.
- It's a tried and trusted GNU standard.
- It uses full strings in the source language as keys. This is the most relevant reason, as it means you don't have to search for abstract keys like
- For the example PO file, the best contextual results were obtained using Azure's AI Translator service and the
qwen3:14bmodel in Ollama.
Copyright (C) 2026 Rodolfo González González.
Licensed under GPL 3.0.
