python gettext different languages at same time python gettext different languages at same time flask flask

python gettext different languages at same time


I have next render_template function for emails:

def render_template(template_name_or_list, **context):    # get  request context    ctx = _request_ctx_stack.top    # check request context    # if function called without request context    # then call with `test_tequest_context`    # this because I send email from celery tasks    if ctx is None:        with current_app.test_request_context():            return render_template(template_name_or_list, **context)    # I have specific locale detection (from url)    # and also use `lang` variable in template for `url_for` links    # so you can just pass language parameter without context parameter    # and always set `babel_locate` with passed language    locale = getattr(ctx, 'babel_locale', None)    if locale is None:        ctx.babel_locale = Locale.parse(context['lang'])    # render template without additinals context processor    # because I don't need this context for emails    # (compare with default flask `render_template` function)    return _render(ctx.app.jinja_env.get_or_select_template(        template_name_or_list), context, ctx.app)

So if you need just change language in request context use next code (see get_locale):

def set_langauge(lang)    ctx = _request_ctx_stack.top    ctx.babel_locale = Locale.parse(lang)


Thanks to @tbicr I ended up with this solution.

In my app.py I have set_locale function:

from flask import _request_ctx_stack as ctx_stack# ...def set_locale(lang):    ctx = ctx_stack.top    ctx.babel_locale = lang# ...

and I call it before rendering email template.

The problem was I need to send emails to many users with different languages at the same time:

with app.test_request_context():    with mail.connect() as conn:        for user in users:            set_locale(user.get_lang())            subject = _(u'Best works').format(get_month_display(month))            body = render_template('emails/best_works.eml'                recipients = [user.email]                msg = Message(subject, html=body, recipients=recipients)                conn.send(msg)

and when I call set_locale first time the value of locale was cached and all emails were rendered with language of first user.

The solution is to call flaskext.babel.refresh each time after set_locale