Allow overriding how the locale is set
Analog to the flask-babel locale_selector, these small, but effective changes provide a much higher user-comfort as they are not restricted to only the integrated locale-selection method.
For instance, some users may want to save the locale of a logged-in-user which has a preferred locale in the request session or even as a cookie. Currently, it is not possible except to override the locale inside a view function like this:
from app.main import babel
async def some_function(abc: str):
babel.locale = "de"
Which is fairly un-pythonic and adds a lot of repetitive code when you have a lot of view functions. Instead of this, one can, optionally override this behaviour like this:
In main.py:
# code omitted before
...
def get_locale_from_session(request: Request) -> str:
# If user logged in, we stored locale in session:
session_locale = request.session.get("locale")
print(f"session_locale: {session_locale}")
if session_locale and session_locale in settings.SUPPORTED_LANGUAGES:
return session_locale
# Fallback to Accept-Language header, or Babel default locale
accept_language = request.headers.get("accept-language", "")
if accept_language:
languages = [lang.split(";")[0] for lang in accept_language.split(",")]
# Check if any of the user's preferred languages match supported ones
for lang in languages:
if lang in settings.SUPPORTED_LANGUAGES:
print("get_locale: ", lang)
return lang
return babel.default_locale # Fallback if no match is found
# before
app.add_middleware(BabelMiddleware, babel_configs=babel_configs, jinja2_templates=templates)
# after
app.add_middleware(BabelMiddleware, babel_configs=babel_configs, jinja2_templates=templates, locale_selector=get_locale_from_session)
Which does the following; if a user is logged in, take their preferred locale to set the babel locale. If no user was found (i.e. not logged in), use the accept-language header instead. Of course, the user is free to set the locale in whichever way they want, e.g. database queries, cookies, sessions etc.
On my end, I have done some testing with some fairly good results. I kindly ask to merge the changes into main after doing some tests on your end too and having these changes available in the next release in the near future.