Skip to main content

Smart translation workflow utilities for Django/Lino - extracts only the strings your app actually uses

Project description

Smart translation workflow for Django/Lino applications.

Polyglot UI filters untranslated strings from .po files (generated by inv mm) by checking which Python objects and modules are actually imported by your app, then translates them using Google Gemini API.

Features

  • Filter untranslated help texts by checking if their Python object path is accessible

  • Filter untranslated strings from .po files by checking occurrence comments against sys.modules

  • Extract all untranslated strings from HTML template sources

  • Translate using Google Gemini API with batch processing and resume capability

  • Update and compile .po files automatically

  • Support for plural forms and format specifier preservation

Installation

From PyPI:

pip install polyglot-ui

For development:

pip install -e .

Requirements:

  • Python 3.8+

  • GEMINI_API_KEY environment variable for translation:

    export GEMINI_API_KEY="your-key-here"

Get your API key from https://ai.google.dev/

Quick Start

# 1. Generate .po files (if not done)
inv mm

# 2. Extract untranslated strings (requires Django context)
python manage.py run $(which polyglot-ui) helptexts \
    -p lino -l lino -L bn -o translateables.json

# 3. Translate
polyglot-ui translate -i translateables.json -o translated.json

# 4. Update .po files
polyglot-ui update -t translated.json -l lino --lang bn

Commands

Command

Description

Django Context

helptexts

Filter help texts by object accessibility

Required

modules

Filter by sys.modules (–all: everything)

Optional*

html

Extract untranslated HTML strings

No

translate

Translate using Gemini API

No

update

Update .po with translations and compile

No

compile

Compile .po to .mo

No

* Required only when filtering by sys.modules (without –all flag)

Detailed Usage

1. helptexts

Filters untranslated help texts from locale_root/help_texts.py by checking if the Python object path is accessible.

How it works:

  1. Reads help_texts dict from locale_root/help_texts.py

  2. For each key (e.g., "lino.modlib.users.User.username"), attempts to resolve it as a Python object using getattr iteratively

  3. Checks if corresponding entry in .po file is untranslated

  4. Only includes help texts for objects accessible in current sys.modules

Requires Django context (use python manage.py run):

python manage.py run $(which polyglot-ui) helptexts \
    -p lino_pronto -l lino_pronto -L bn -o helptexts.json

Arguments:

  • -p, --project_name: Project name (required)

  • -l, --locale_root: Locale root (required, must have help_texts.py)

  • -L, --lang: Language code (default: bn)

  • -o, --output_file: Output JSON file (default: translateables.json)

2. modules

Filters untranslated strings from .po file (generated by inv mm) by checking if occurrence comments reference imported modules.

How it works:

  1. Reads .po file and finds untranslated entries

  2. Checks occurrence comments (e.g., #: lino/modlib/users/models.py:123)

  3. Converts file path to module name (e.g., lino.modlib.users.models)

  4. Checks if module is in sys.modules (unless --all flag is used)

  5. Only includes strings from imported modules (or all strings with --all)

Requires Django context (when filtering by sys.modules):

python manage.py run $(which polyglot-ui) modules \
    -p lino -l lino -L bn -o modules.json

Extract all strings (no Django context needed):

polyglot-ui modules -p lino -l lino -L bn -o all_modules.json --all

Arguments:

  • -p, --project_name: Project name (required)

  • -l, --locale_root: Locale root (required)

  • -L, --lang: Language code (default: bn)

  • -o, --output_file: Output JSON file (default: translateables.json)

  • --all: Extract all untranslated strings without filtering by sys.modules

3. html

Extracts ALL untranslated strings from .po file where occurrence comment references an HTML file.

No filtering - extracts all HTML strings regardless of usage:

polyglot-ui html -l lino -L bn -o html.json

Arguments:

  • -l, --locale_root: Locale root (required)

  • -L, --lang: Language code (default: bn)

  • -o, --output_file: Output JSON file (default: translateables_html.json)

4. translate

Translates strings using Google Gemini API. Resumable - skips already translated strings:

export GEMINI_API_KEY="your-key"
polyglot-ui translate -i translateables.json -o translated.json

Arguments:

  • -i, --input_file: Input JSON (required)

  • -o, --output_file: Output JSON (default: translated.json)

  • -l, --lang: Language name (default: “Bengali (bn)”)

  • -n, --batch_size: Batch size (default: 200)

5. update

Updates .po file with translations and compiles to .mo:

polyglot-ui update -t translated.json -l lino --lang bn

Arguments:

  • -t, --translations_files: JSON file(s) with translations (required)

  • -l, --locale_root: Locale root (required)

  • --lang: Language code (default: bn)

6. compile

Manually compile .po to .mo:

polyglot-ui compile /path/to/django.po

Workflow Example

# Setup
export GEMINI_API_KEY="your-key"
cd /path/to/project
inv mm  # Generate .po files

# Extract (requires Django context)
python manage.py run $(which polyglot-ui) helptexts \
    -p lino -l lino -L bn -o helptexts.json
python manage.py run $(which polyglot-ui) modules \
    -p lino -l lino -L bn -o modules.json

# Extract HTML (no Django context)
polyglot-ui html -l lino -L bn -o html.json

# Translate
polyglot-ui translate -i helptexts.json -o t_helptexts.json
polyglot-ui translate -i modules.json -o t_modules.json
polyglot-ui translate -i html.json -o t_html.json

# Update .po files
polyglot-ui update -t t_helptexts.json t_modules.json t_html.json \
    -l lino --lang bn

How It Works

Prerequisites

.po files must exist (generated by inv mm command).

Smart Filtering

Shared packages like lino and lino_xl contain thousands of strings. Each app only uses a subset. Polyglot UI filters by:

  1. Help texts (helptexts):

    • Reads help_texts dict from locale_root/help_texts.py

    • Keys are Python object paths: "lino.modlib.users.User.username"

    • Checks if object is accessible by iteratively using getattr on sys.modules

    • Only includes help texts for accessible objects

  2. Module strings (modules):

    • Reads occurrence comments from .po file: #: lino/modlib/users/models.py:123

    • Converts file path to module name: lino.modlib.users.models

    • By default: Checks if module is in sys.modules (requires Django context)

    • With --all flag: Extracts all strings without filtering (no Django context needed)

    • Only includes strings from imported modules (or all with --all)

  3. HTML strings (html):

    • Checks if occurrence comment ends with .html

    • No filtering - extracts ALL HTML strings

Django Context

Commands requiring python manage.py run:

  • helptexts - needs sys.modules to check object accessibility

  • modules - needs sys.modules to check module imports (unless --all flag is used)

Other commands run standalone.

Tips

  • Run inv mm first to generate/update .po files

  • Organize output: helptexts.json, modules.json, html.json

  • Batch size: 200 (default) works well; reduce if API limits hit

  • Translation is resumable - rerun if interrupted

  • Never commit GEMINI_API_KEY to version control

Troubleshooting

  • “GEMINI_API_KEY not set”: Export your API key

  • “Module not found”: Use python manage.py run for commands requiring Django context

  • “No module named ‘google.genai’”: Run pip install google-genai

  • Incomplete translations: Check API limits, network; rerun to resume

License & Support

GPL-2.0

Contributions welcome via Pull Request.

Changelog

0.1.0 (2026-02-08)

  • Initial release

  • Filter untranslated strings by checking sys.modules and object accessibility

  • Google Gemini API integration

  • Plural forms and format specifier preservation

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

polyglot_ui-0.1.0.tar.gz (18.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

polyglot_ui-0.1.0-py3-none-any.whl (22.0 kB view details)

Uploaded Python 3

File details

Details for the file polyglot_ui-0.1.0.tar.gz.

File metadata

  • Download URL: polyglot_ui-0.1.0.tar.gz
  • Upload date:
  • Size: 18.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.3

File hashes

Hashes for polyglot_ui-0.1.0.tar.gz
Algorithm Hash digest
SHA256 82247fa08d41ea589c22cb3ed393dffd11aa78691c15947e4105a19351b22bd4
MD5 4cf32202d6fe98195be6cf73e53e37fa
BLAKE2b-256 e4ce1088a0e9c7de39619cc921aad3a6eaca22c78e64acda9319159d3590547c

See more details on using hashes here.

File details

Details for the file polyglot_ui-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: polyglot_ui-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 22.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.3

File hashes

Hashes for polyglot_ui-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 70206b81cfffb584b0973f6118b6f1c9263961622c42025dbbc78db744b26bbf
MD5 fe68a5f924a7c3e82af5f2c5217626c3
BLAKE2b-256 e1ab8ba1f2b4b8abb1e57d3c417d3ba66fc04e563d89194951437b152230be26

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page