I am trying to get the flask session to work in my app, but it won’t work, I get the same error as OP: RuntimeError: Working outside of request context.
I looked at the old thread that was linked, but it did not give any useful info to get the app working as a whole. I included an example app below, with in comments my attempts of getting the flask session to work (which it didn’t). Can someone show me what to add in order to get the flask session working?
To start the dashboard, create a directory and add the file app.py
to it. Then next to app.py
create a subdirectory called locale
and add general.se.yml
and general.en.yml
to it. Check the included requirements.txt
to see what needs to be installed.
The example app works with a global variable LOCALE
, which the callback alters. What I would like is to store and read the locale info from the flask session.
Some background context to this post:
I am trying to get an app working with localization/internationalization. The app should be able to run in the cloud where multiple workers and/or processes can work on requests coming from my dash app. The language info should be stored on a per client basis such that language selection by one client does not affect another clients interface that has the dash app open simultaneously in another browser.
The problem is that the web page must be refreshed in order to load the translations for the newly requested language. So to get the correct language loaded, we must store the language setting in a scope that all server workers/processes have access to, that does not get overwritten by reloading the app, and that is independent per client.
This means that any global variable in the code itself doesn’t work (information is not kept when a new worker starts), the internal storage that i18n
provides or using environmental variables doesn’t work (it’s storage that is not client-independent).
As such I was thinking of using flask session storage, to store that info.
I am trying to avoid Dash pages for now, given that my app is quite big and it will be quite some work to rewrite my single-page app to new framework. The benefit of Dash pages however is that I would be able to pass queries in the url and pass localization via the url to the layout. Side question here: is there any way of accessing url query parameters in the single page app like in the example below?
app.py
import dash
import flask
from dash import dcc, html, Input, Output
from flask import session
import i18n
from pathlib import Path
i18n.set("load_path", [Path(__file__).parent / "locale"])
server = flask.Flask(__name__)
LOCALE = 'en'
def serve_layout(locale):
return html.Div(
[
dcc.Location(id="url", refresh=True),
i18n.t("general.language_dropdown", locale=locale),
dcc.Dropdown(
id="ldropdown", options=["se", "en"], placeholder="Select language", persistence='session'
),
i18n.t("general.welcome", locale=locale)
]
)
# @server.route("/")
def get_layout():
# LOCALE = session.get('locale', 'en')
return serve_layout(LOCALE)
app = dash.Dash(__name__, server=server)
app.layout = get_layout
@app.callback(
Output("url", "href"),
Input(component_id="ldropdown", component_property="value"),
prevent_initial_call=True,
)
def change_dashboard_language(language_code):
global LOCALE
LOCALE = language_code
# session['locale'] = language_code
return "/"
if __name__ == "__main__":
app.run_server(debug=True)
locale/general.en.yml
---
en:
language_dropdown: Select language
welcome: Welcome to this dashboard
locale/general.se.yml
---
se:
language_dropdown: Välj språk
welcome: Välkommen till den här instrumentpanelen
requirements.txt
dash
python-i18n[YAML]