Search code examples
pythonpython-3.xinternationalizationpyramid

internationalization with pyramid and python 3


What is the current state of internationalization support for Pyramid using Python 3?

Currently it seems that the packages Pyramid uses for this, lingua and babel, aren't Python 3 compatible.

There is https://bitbucket.org/felixschwarz/babel-py3k, but no official release.

Also for lingua, I could only find shadows of something called lingua3k, but the links to it everywhere were broken and also no official releases.

How can I get myself up and running with Pyramid i18n and Python 3?


Solution

  • I was unable to find any info about the status (current or future) of i18n helper packages for pyramid in python 3 (babel and lingua).

    To solve this inconvenience, I did 4 things:

    1. Create a 2nd virtual environment with python2.7
    2. Add a specific i18n setup file called setup_i18n.py
    3. Write a simple wrapper script called translate.py which setup.py will call to do translations.
    4. Add an entry point in setup.py to point to the translate script.

    Details:

    1. I created a very lean 2nd virtual and very lean env with python2.7 inside my project. Just called it env_python_2.7 and put it in the root of my project.

    2. Then in the directory where setup.py lives I created another setup file, setup_i18n.py. This file only makes requirements for just what is needed for i18n support. My setup_i18n.py file looks like:

    
    from setuptools import setup, find_packages
    
    requires = [
        'Babel',
        'lingua',
    ]
    
    setup(name='my_project',
          packages=find_packages(),
          install_requires=requires,
    
          message_extractors={'.': [
              ('**.py', 'lingua_python', None),
              ('**.pt', 'lingua_xml', None),
              ]},
          )
    
    
    1. Then I created a script called translate.py and put that in the same scripts directory that initializedb.py goes into when you create a project from a template. The script is pretty general and could be made to have more specific targets, but it looks like this
    
    import argparse
    import subprocess
    import sys
    
    from pyramid.paster import (
        get_appsettings,
        setup_logging,
        )
    
    description = """\
    A script to facilitate the translation of strings in the app.
    """
    parser = argparse.ArgumentParser(description=description)
    parser.add_argument('ini_file', help='Ini file to setup environment for this script')
    parser.add_argument('-a', '--add', metavar='locale',
                        help='Add locale name of new language for translation (eg: en, de)')
    
    def main(argv=sys.argv):
        args = parser.parse_args()
    
        setup_logging(args.ini_file)
        settings = get_appsettings(args.ini_file)
    
        # Python 2.7 is needed for translation strings at this time, because the
        # available translation string tools are not compatible with Python 3
        # at this time
        python27 = settings['my_project.python27_dir'] + '/bin/python'
        setup_file = settings['my_project.i18n_setup_file']
    
        if args.add:
            subprocess.call([python27, setup_file, 'init_catalog', '-l', args.add])
    
        subprocess.call([python27, setup_file, 'extract_messages'])
        subprocess.call([python27, setup_file, 'update_catalog'])
        subprocess.call([python27, setup_file, 'compile_catalog'])
    
    if __name__ == '__main__':
        main()
    
    
    1. And finally, I modified the setup.py entry points to point to the translate script. My entry points look like:
    
    entry_points="""\
    [paste.app_factory]
    main = my_project:main
    [console_scripts]
    my_project_db = my_project.script.initializedb:main
    my_project_translate = my_project.script.translate:main
    """,
    
    

    Now I can i18n my app by calling 'python3 setup.py my_project_translate'