Сделайте свое ремесло глобальным с помощью Python, Gettext и Localazy

Время от времени ваша работа в качестве специалиста по данным может заключаться в создании отчета, который вы можете отправить по электронной почте заинтересованным сторонам или поделиться через интранет. Документы Word могут показаться немного устаревшими, но все же есть случаи, когда их использование является кратчайшим путем к этой цели. Всякий раз, когда обсуждается автоматизация, предпочтительным инструментом является Python. Создание автоматизированного отчета с его помощью - довольно стандартный навык для специалиста по данным.

Но все весело и весело, пока не появятся другие языки.

Теоретически подготовка другой языковой версии не кажется сложной. В конце концов, достаточно перевести отдельные метки и описания на другой язык, а затем жестко закодировать их в следующей версии скрипта. На практике этот простой подход требует времени и подвержен ошибкам, особенно когда есть постоянная потребность в изменении некоторых сообщений. Не говоря уже о сложности работы с нетехническими переводчиками с помощью этого метода.

В этой статье показано, как сэкономить время за счет перевода отчета с данными, созданного Python, с помощью Gettext и Localazy. Я покажу вам, как извлекать сообщения из исходного кода (Gettext), хранить их в отдельных файлах и как сделать их доступными в средстве совместного перевода (Localazy). Кроме того, вы узнаете, как справляться с трудностями при переводе f-строк.

«🔔 Хотите больше подобных статей? Подпишите здесь."

Почему?

Представьте, что вы работаете в команде аналитиков в международной компании, которая имеет 3 филиала в разных странах (Англия, Германия, Польша).

Вы создали интересный описательный отчет, результаты которого могут значительно улучшить производительность каждой ветви.

Вы хотите, чтобы он охватил максимально широкую аудиторию, но ваша компания не работает исключительно на английском языке. Поскольку ваш отчет создается автоматически один раз в день, переводить его на национальные языки каждый раз вручную не представляется возможным.

Но если вы можете автоматизировать создание отчетов, почему бы не сделать то же самое с переводом?

Старт проекта

Вначале ваш проект представляет собой один файл с основным скриптом и набором данных в формате CSV.

Сценарий говорит сам за себя. Используя данные, загруженные из файла CSV, он вычисляет различную статистику, генерирует гистограмму и упаковывает все в документ Word. Использование скрипта простое. Все, что вам нужно сделать, это указать город и дату.

Примечание. Этот проект направлен на обучение локализации приложений Python, поэтому я пропускаю такие аспекты, как проверка входных переменных или интерес 😆

Возможно, мы могли бы переводить сообщения на другие языки и использовать операторы if, чтобы изменять их по желанию пользователя, но такой подход был бы утомительным и подверженным ошибкам. Поэтому сначала мы извлечем все строки из кода, чтобы работать с ними отдельно от бизнес-логики.

Gettext

GNU gettext - это универсальный набор инструментов для создания многоязычных сообщений. Он предоставляет основу для поддержки переведенных строк сообщений. Он поддерживает множество языков программирования;), включая Python. Модуль gettext поставляется со стандартной библиотекой Python. Лучшее в gettext - это то, что он помогает нам легко извлекать текстовые сообщения в отдельные файлы.

Поскольку наш отчет готовится на основе данных из Лондона, Варшавы и Берлина, мы подготовим версии на английском, польском и немецком языках. Во-первых, нам нужно подготовить структуру каталогов.

mkdir -p locales/{de,pl}/LC_MESSAGES

Затем мы должны извлечь сообщения из кода.

xgettext -d base -o locales/base.pot

Или, альтернативно:

/Library/Frameworks/Python.framework/Versions/3.8/share/doc/python3.8/examples/Tools/i18n/pygettext.py -d base -o locales/base.pot report.py

Чтобы найти файл pygettext.py, вы можете использовать команду: locate pygettext.py.

Примечание: использование простой команды gettext заставит вас изменить файл результатов, добавив заголовок CHARSET «Content-Type: text / plain; charset = UTF-8 \ n ”

Это создаст в папке locales файл base.pot со строками, взятыми из файла report.py.

К сожалению, как видите, сгенерированный base.pot не содержит никаких строк. Чтобы исправить это, нам нужно изменить report.py, пометив сообщения для перевода.

После повторного создания base.pot в нем появляются две строки.

После этого абзаца проект должен выглядеть так:

Https://github.com/fischerbach/python_localization_tutorial/tree/002-gettext

Используйте этот репозиторий: https://github.com/fischerbach/python_localization_tutorial

Ветви содержат следующие шаги, описанные в этой статье.

Первые переводы

А теперь подготовим первые переводы. Скопируйте и переименуйте base.pot в каждую языковую папку:

cp locales/base.pot locales/de/LC_MESSAGES/base.po
cp locales/base.pot locales/pl/LC_MESSAGES/base.po

Давайте изменим отдельные языковые файлы:

Чтобы использовать перевод в нашей программе, нам нужно сгенерировать файлы MO. Файлы MO - это файлы двоичных данных, которые анализируются модулем Python gettext и используются в программе.

msgfmt -o locales/de/LC_MESSAGES/base.mo locales/de/LC_MESSAGES/base
msgfmt -o locales/pl/LC_MESSAGES/base.mo locales/pl/LC_MESSAGES/base

Теперь мы можем изменить скрипт для создания отчетов на разных языках.

С этого момента мы также передадим соответствующую функцию перевода функции generate_report.

Давайте проверим:

python3 report.py sales.csv Warsaw 2019-01-04 pl

Заменено предложение в среднем абзаце! Если мы изменим последний параметр на de, мы получим версию на немецком языке.

Одно предложение в отчете переведено, пора делать все остальное. Порядок такой же. Каждый раз, когда в исходном коде появляется строка с сообщением, окружайте ее функцией _(‘This is a string’). Как только это будет сделано, сгенерируйте файл POT с самого начала, скопируйте его в локали каждого языка, переведите его и сгенерируйте двоичные файлы.

Но эй, это должно было быть проще

Итак, в следующей итерации нашего решения мы создаем два вспомогательных скрипта (generate_po.sh и generate_mo.sh). Здесь все изменения:

Https://github.com/fischerbach/python_localization_tutorial/tree/004-gettext-generators

Давайте проверим один из языковых файлов:

Https://github.com/fischerbach/python_localization_tutorial/blob/004-gettext-generators/locales/pl/LC_MESSAGES/base.po

Как видите, даже относительно простой отчет может привести к переводу довольно большого количества меток. Кроме того, при каждом изменении нам придется заботиться об объединении изменений с помощью msgmerge. Но мы воспользуемся чем-нибудь получше.

Localazy

Localazy - отличная программа, которая делает обычно ужасный перевод сносным и даже почти приятным. Он поддерживает множество фреймворков и форматов файлов и предоставляет инструменты CLI для автоматизации сборки. Мои любимые функции - это возможность совместного перевода и автоматическое управление изменениями в переведенных файлах.

Итак, давайте объединим наш отчет с Localazy. Сначала создайте учетную запись Localazy и установите Localazy CLI. Затем создайте новое приложение.

Обязательно установите Тип приложения на Частное приложение. Если ваше приложение не содержит конфиденциальных данных, вы можете спокойно оставить его общедоступным. Однако мы установим для него частный режим по причинам, описанным в последнем разделе «Проблема с f-строками» этой статьи. Затем выберите файлы POT из доступных форматов файлов.

Вы увидите файл конфигурации шаблона localazy.json. Скопируйте его в основную папку проекта.

Не забудьте изменить путь к папке locales. Зайдите в свое приложение на Localazy и добавьте несколько новых языков.

Теперь вы можете снова сгенерировать файлы PO и загрузить их в Localazy:

bash generate_po.sh
localazy upload

Через некоторое время вы увидите список фраз для перевода на каждый язык вашего приложения.

И самое главное, что каждая фраза сопровождается машинным переводом.

После того, как все переводы будут приняты или созданы, вы можете загрузить их в свое приложение и повторно сгенерировать двоичные файлы MO:

localazy download
bash generate_mo.sh

Давайте проверим отчет на польском языке:

Как человек, хоть немного разбирающийся в польском, я бы сказал, что это вполне приемлемо. Наконец, обратимся к еще одной проблеме.

проблема с f-строками

В проекте довольно широко используются ф-струны. К сожалению, мы не можем использовать их в качестве аргументов функции _(), gettext вернет ошибку. Проблема может быть решена путем замены f-строк на .format() операторы или конкатенации строк. Но мне нравятся f-строки, и создание текстовых отчетов действительно является модельным примером их использования. К счастью, есть обходной путь.

Https://gist.github.com/fischerbach/993e6fab4caf67af6c63281fe3cb8b67

Мы просто оборачиваем f-строку в функцию, которая ее оценивает. Однако существуют потенциальные риски, связанные с использованием функции eval, поскольку она запускает код, содержащийся в строке. Вот почему мы сделали приложение в Localazy закрытым, чтобы не запускать нефильтрованный код от пользователей.

Еще одно ограничение заключается в том, что каждый раз, когда вам нужно изменить выражение внутри строки, вам также нужно будет обновить свой .po-файл. Однако, благодаря Localazy, сделать это несложно.

Выводы

Как видите, дуэт Gettext и Localazy - это гибкое решение проблем локализации. Каждый обращается к разным источникам нагрузки и прекрасно дополняет друг друга.

Проблема с f-строкой еще не решена, особенно в контексте переводов сообщества. Также стоит подумать, что делать с метками, которые появляются в наборе данных.

использованная литература

GNU Gettext:
https://www.gnu.org/software/gettext/

Localazy:
https://localazy.com/

Спецификация файлов PO:
https://www.gnu.org/software/gettext/manual/html_node/PO-Files.html

Https://python-docx.readthedocs.io/en/latest/#what-it-can-do
https://phrase.com/blog/posts/translate-python-gnu-gettext /
https://localazy.com/blog/javascript-app-localization-i18next-localazy