Flask-BabelEx translations in a Celery task

The problem with translation in a Celery task is that there is no request context and flask_babelex.get_locale returns None. For Flask-Babel there is a force_locale context manager which solves this problem. But Flask-Security uses Flask-BabelEx and it does not work well with Flask-Babel.

Here is an example how to create a context manager which provides dummy request context.

from contextlib import contextmanager
from flask import current_app
from babel import Locale

from ..config import SERVER_NAME, PREFERRED_URL_SCHEME


@contextmanager
def force_locale(locale=None):
    if not locale:
        yield
        return

    env = {
        'wsgi.url_scheme': PREFERRED_URL_SCHEME,
        'SERVER_NAME': SERVER_NAME,
        'SERVER_PORT': '',
        'REQUEST_METHOD': ''
    }
    with current_app.request_context(env) as ctx:
        ctx.babel_locale = Locale.parse(locale)
        yield

And an example of use

@celery.task()
def some_task(user_id):
	user = User.objects.get(id=user_id)
	with force_locale(user.locale):
		...gettext('TranslationKey')...
comments powered by Disqus