Explore All i18n Advantages of Babel for Your Python App

Python Babel is a well-known solution that assists in internationalizing and localizing Python applications, with an emphasis on web-based applications. If you are working with dates and times, numbers or getttext translations, then it will help you automate a part of the process. In this tutorial, we are going to explore the advanced usages of this library with practical examples.

In the past, we have given detailed tutorials on Gettext tools as well as integrating Gettext with Python. We are going to extend our knowledge by using Babel and see some practical examples of its usage in python i18n. We are also going to see how to integrate it with Jinja2 templates and how to integrate Phrase’s In-Context Editor into a Flask application to help with the translation process by simply browsing the website and edit texts along the way, making your python localization process a lot simpler. You can also find the code described in this tutorial on Github.

About Babel

Babel provides for internationalization (python i18n) and localization (python l10n) helpers and tools that work on two areas. The first is the gettext  module that use gettext to update, extract and compile message catalogs and manipulate PO  files. The second one is the usage of CLDR (Common Locale Data Repository) to provide formatting methods for currencies, dates numbers etc. based on a locale parameter. Both aspects aim to help to automate the process of internationalizing Python applications as well as providing convenient methods for accessing and using this data.

Babel, in essence, works as an abstraction mechanism for a larger message extraction framework, as you can extend it with your own extractors and strategies that are not tied to a particular platform.

Installing and using Babel

Installing Babel is simple using pip

If you don’t have pip installed, you can get it with  easy_install

Working with Locale Data

(CLDR) Unicode Common Locale Data Repository is a standardized repository of locale data used for formatting, parsing and displaying locale-specific information. Instead of translating, for example, day names or month names for a particular language or script, you can make use of the translations provided by the locale data included with Babel based on CLDR data.

Let’s see some examples…

Create a file name loc.py  and add the following code:

We are showing some examples of the Locale class. It is used to print, negotiate or identify language tags. If you run this example, you will see the following output:

These are useful as they are provided by the (CLDR) dataset and do not need translation.

Apart from that, there are several functions that format dates, times, currencies, units etc. Let’s see some examples:

The output is:

Message Extraction

Babel has an extraction mechanism similar to  gettext. It works by walking through the specified directories and based on the configuration rules it applies extractor functions to those files matched. This way there is more flexible than  gettext  as you can leverage the expression power of Python to extend the tool.

Babel comes with a few built-in extractors such as python, javascript, and ignore (which extracts nothing) and you can create your own extractors and there are two different front-ends to access this functionality:

  • A Command-Line Interface
  • Distutils/Setuptools Integration

In this tutorial, we are going to use the Command-Line Interface.

To use it just invoke the  pybabel   tool for example to print all known locales

To actually use the tooling lets walk through the process of extracting messages using pybabel :

Create a file named main.py  and add the following code:

Note that the usage of  gettext  is only convenient because the default extractor uses  gettext  behind the scenes, but Babel, in general, is not tied to that.

Use the  pybabel extract   command to create the initial message catalog:

That will createa base pot file that will contain the following messages:

You don’t have to edit this file now.

Using the   init  command, we can create a new translation catalog based on that POT  template file:

Those files are ready to be translated. When the translations are done, you can use the  compile  command to turn them into  MO  files:

Now, if you make changes to the base.pot file you can update the rest using the  update  command. For example, add the following line to  base.pot

Then run the tool to update the rest of the PO  files:

Integration with Jinja2 templates

Babel can integrate with Jinja templates using the  jinja2.ext.i18n  extension.

It can then be used to mark and translate messages from templates and it is useful for internationalizing HTML pages.

In order to integrate both of those tools together, you need to provide some config.

First, install jinja using pip:

You need to instruct babel to parse jinja templates when extracting the messages and for that, you need to add a configuration file.

Create a file named babel-mapping.ini  and add the following text:

So now when you invoke  pybabel  commands referencing that file it will also extract messages from Jinja templates.

Le’t see how we can load Babel and Jinja templates together:

Create a template called index.html  that will be used to extract our messages:

Invoke the following command to extract the base messages:

That will generate the following catalog:

Now initialize the Italian translations using the init command and provide the translations:

Run the compile command to generate the MO files:

Create a file named app.py  to hook everything together:

We are using the  Translations component to load the message catalogs that we compiled earlier. Then we load them to the Jinja environment using the  install_gettext_translations method. Then we render the template.

If you run this program, you will see the following output:

If we want to change the locale, we need to do the same procedure. For example:

Adding Phrase in-context editor with Flask and Babel

We can also introduce Flask into the picture and integrate Phrase in-context editor by using a technique to replace the gettext callables for the jinja environment.

First, we need to install the required packages:

Create a file named web.py and add the following code:

We set up some configuration first to define the list of supported languages and the PHRASEAPP_* specific keys. What the in-context editor needs is to wrap the translatable strings with specific tags '{{__'  and '__}}' .

Now let’s see the contents of the phrase.py  file

We need to make sure we forward the original parameters to the original gettext functions in case we disabled the editor.

Update the index.html  file to include the script to load the editor:

If you haven’t done that already, go to https://phrase.com/ and signup to try it for free.

Once you set up your account, you can create a project and navigate to Project Settings to find your projectId key.

Use that to assign the PHRASE_APP_TOKEN  environment variable before you start the server.

When you navigate to the page you will see a login modal and once you are authenticated you will see the translated strings change to include edit buttons next to them. The In-Context editor panel will show also.



In this article, we have seen how to do python localization using the Python babel library. We’ve also seen how we can integrate it with Jinja templates and Phrase’s In-Context Editor in our workflow. If you have any other questions left, do not hesitate to post a comment or drop me a line. Thank you for reading and see you again next time!


Explore All i18n Advantages of Babel for Your Python App
4.5 (90%) 4 votes
Theo Phrase Content Team