{"id":7804,"library":"translate-toolkit","title":"Translate Toolkit","description":"The Translate Toolkit is a comprehensive suite of software and a Python API designed to enhance the productivity of localizers and streamline localization and translation engineering workflows. It supports a wide array of file formats, including common standards like Gettext PO and XLIFF, alongside many others. As of April 2026, the current version is 3.19.5, actively maintained with regular releases that include improvements and bug fixes.","status":"active","version":"3.19.5","language":"en","source_language":"en","source_url":"https://github.com/translate/translate","tags":["i18n","l10n","localization","translation","gettext","xliff","po-files","quality-assurance"],"install":[{"cmd":"pip install translate-toolkit","lang":"bash","label":"Basic Installation"},{"cmd":"pip install \"translate-toolkit[all]\"","lang":"bash","label":"Full Features (with optional dependencies)"},{"cmd":"uv pip install translate-toolkit","lang":"bash","label":"Recommended with uv (Windows)"}],"dependencies":[{"reason":"Required for full XML/XLIFF processing capabilities, especially for robust parsing and serialization.","package":"lxml","optional":false},{"reason":"Enables translation of language names (e.g., 'English (South Africa)') within the `lang.data` module.","package":"pycountry","optional":true},{"reason":"Provides spellchecking functionality within the toolkit's quality assurance tools.","package":"enchant","optional":true},{"reason":"Used for optimized Levenshtein distance calculations in fuzzy matching operations (since version 3.19.0).","package":"RapidFuzz","optional":true}],"imports":[{"note":"The PoFile class for working with Gettext PO files is found within the 'pofile' submodule of 'translate.storage'.","symbol":"PoFile","correct":"from translate.storage.po import pofile"},{"note":"Similar to PoFile, XliffFile is located within its respective submodule for XLIFF format handling.","symbol":"XliffFile","correct":"from translate.storage.xliff import xliff"}],"quickstart":{"code":"import os\nfrom translate.storage import po\n\n# 1. Create a dummy PO file for demonstration\npo_content = '''\nmsgid \"\"\nmsgstr \"\"\n\"Project-Id-Version: Example Project 1.0\\n\"\n\"Content-Type: text/plain; charset=UTF-8\\n\"\n\nmsgid \"Hello, world!\"\nmsgstr \"¡Hola, mundo!\"\n\nmsgid \"Welcome to our application.\"\nmsgstr \"Bienvenido a nuestra aplicación.\"\n'''\n\nwith open(\"example.po\", \"w\", encoding=\"utf-8\") as f:\n    f.write(po_content)\n\n# 2. Load the PO file\ntry:\n    po_file = po.pofile.PoFile(\"example.po\")\n    print(f\"Loaded PO file with {len(po_file.units)} translation units (including header).\")\n\n    # 3. Iterate and print translation units\n    for unit in po_file.units:\n        if not unit.isblank(): # Skip the header unit\n            print(f\"---\\nOriginal: '{unit.source}'\\nTranslated: '{unit.target}'\")\n\n    # 4. Modify a translation unit (example)\n    if len(po_file.units) > 1: # Ensure there's at least one real unit after header\n        first_translatable_unit = po_file.units[1]\n        print(f\"\\nModifying unit: '{first_translatable_unit.source}'\")\n        first_translatable_unit.target = \"¡Saludos, universo!\"\n        print(f\"New translation: '{first_translatable_unit.target}'\")\n\n    # 5. Save the modified PO file (optional)\n    po_file.save(\"example_modified.po\")\n    print(\"\\nModified file saved to example_modified.po\")\n\nexcept Exception as e:\n    print(f\"An error occurred: {e}\")\nfinally:\n    # 6. Clean up dummy files\n    if os.path.exists(\"example.po\"):\n        os.remove(\"example.po\")\n    if os.path.exists(\"example_modified.po\"):\n        os.remove(\"example_modified.po\")\n    print(\"\\nCleaned up dummy files.\")\n","lang":"python","description":"This quickstart demonstrates how to programmatically load, inspect, and modify a Gettext PO file using the Translate Toolkit's API. It creates a temporary PO file, reads its content, prints individual translation units, shows how to update a target string, and optionally saves the changes to a new file, finally cleaning up the temporary files."},"warnings":[{"fix":"Upgrade your Python environment to 3.11 or a newer compatible version. (e.g., `pyenv install 3.11.9 && pyenv local 3.11.9`)","message":"Translate Toolkit versions 3.19.x and newer require Python 3.11 or later. Older Python versions (e.g., 3.10) are no longer supported.","severity":"breaking","affected_versions":">=3.19.0"},{"fix":"Migrate any usage of `tmserver` or `project storage` functionality to alternative mechanisms or newer components within the toolkit's API, or external translation memory solutions.","message":"The `tmserver` (translation memory server) and related project storage components were removed from the toolkit.","severity":"breaking","affected_versions":">=3.19.0"},{"fix":"If working with CSV files generated by older versions, update the header row to `location,source,target` or remove it entirely for correct parsing.","message":"CSV column headers generated by `csv2po` changed from `comment,original,translation` to `location,source,target` for better alignment with toolkit terminology.","severity":"gotcha","affected_versions":"<1.4.1"},{"fix":"Expect and review layout changes when processing older PO files. It is recommended to consistently use PO files with headers for better interoperability with Gettext tools.","message":"All generated PO files now consistently include headers, which may cause layout changes when `pofilter` or `pogrep` are used on older, headerless files.","severity":"gotcha","affected_versions":">=1.6.0"}],"env_vars":null,"last_verified":"2026-04-16T00:00:00.000Z","next_check":"2026-07-15T00:00:00.000Z","problems":[{"fix":"Explicitly specify the correct encoding when reading files (e.g., `PoFile(filename, encoding='iso-8859-1')`). The toolkit has improved charset detection in newer versions, but explicit specification is always safer for diverse inputs.","cause":"File encoding mismatch, where the default system encoding or an assumed encoding (e.g., UTF-8) does not match the actual encoding of the localization file.","error":"UnicodeDecodeError: 'charmap' codec can't decode byte 0x81 in position X: character maps to <undefined>"},{"fix":"Before sending to machine translation, pre-process your localization files to replace template variables with simple, unique placeholders (e.g., `_VAR_1_`). After translation, post-process to restore the original variables.","cause":"Automatic tokenization in machine translation services often breaks or translates placeholders/variables, as they are not recognized as non-translatable tokens.","error":"Machine translation errors due to Django/Python template variables (e.g., `{{ variable }}`) being translated or mangled."}]}