-
-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Description
Hi,
Not sure if it is a bug or me not knowing how to do this properly but I am trying to make a Dash app with Flask login and home page. User would be redirected to Dash app when link clicked on home page. My app structure is as below with Dash app in app1.py:
example/
dashapp/
static/
custom-css.css
templates/
base.html
home.html
login.html
__init__.py
app1.py
forms.py
models.py
routes.py
application.py
config.py
users.db
I wanted to pass logged user name into Dash app but kept getting 'RuntimeError: Working outside of request context.' error. After multiple searches I found a solution which involved putting app layout into function. It works fine unless any callback is added. Is there a solution for this? I tried adding callbacks into another function but it didn't do anything.
Code for app1.py:
import dash
import dash_html_components as html
from dash.dependencies import Input, Output
from werkzeug.urls import url_parse
from dashapp import application, routes
from flask_login import login_required, current_user
from flask import session, current_app
app1 = dash.Dash(__name__, server = application, routes_pathname_prefix = '/app1/', assets_folder = 'static', assets_url_path = '/static')
app1.scripts.config.serve_locally = True
app1.css.config.serve_locally = True
def serve_layout():
return html.Div(
children = [
html.Div(
id='div1',
children = 'Test1'
),
html.Div(
id='div2',
children = '{}'.format(session.get('username', None))
),
html.Div(
id='div3',
children = 'Test3'
),
],
)
#def app_callback(app):
# @app.callback(
# Output('div1', 'children'),
# [Input('div3', 'children')])
# def update_intervalCurrentTime(children):
# return children
app1.layout = serve_layout
#app_callback(app1)
for view_func in app1.server.view_functions:
if view_func.startswith('/app1/'):
app1.server.view_functions[view_func] = login_required(app1.server.view_functions[view_func])
Code for routes.py:
from flask import render_template, flash, redirect, url_for, request, session
from flask_login import login_user, logout_user, current_user, login_required
from werkzeug.urls import url_parse
from dashapp import application, db
from dashapp.forms import LoginForm
from dashapp.models import User
from dashapp import app1
@application.route('/')
@application.route('/home')
@login_required
def home():
return render_template('home.html')
@application.route('/login', methods=['GET', 'POST'])
def login():
if current_user.is_authenticated:
session['username'] = current_user.username
return redirect(url_for('home'))
form = LoginForm()
if form.validate_on_submit():
session['username'] = form.username.data
user = User.query.filter_by(username=form.username.data).first()
if user is None or not user.check_password(form.password.data):
flash('Invalid username or password')
return redirect(url_for('login'))
login_user(user, remember=form.remember_me.data)
next_page = request.args.get('next')
if not next_page or url_parse(next_page).netloc != '':
next_page = url_for('home')
return redirect(next_page)
return render_template('login.html', form=form)
@application.route('/logout')
def logout():
logout_user()
return redirect(url_for('login'))
Other files are pretty much standard. I can paste those later if needed.
Traceback:
Traceback (most recent call last):
File "application.py", line 1, in <module>
from dashapp import application, db
File "C:\Users\Mudyla\Desktop\Example\dashapp\__init__.py", line 16, in <module>
from dashapp import routes, models
File "C:\Users\Mudyla\Desktop\Example\dashapp\routes.py", line 7, in <module>
from dashapp import app1
File "C:\Users\Mudyla\Desktop\Example\dashapp\app1.py", line 42, in <module>
app_callback(app1)
File "C:\Users\Mudyla\Desktop\Example\dashapp\app1.py", line 37, in app_callback
[Input('div3', 'children')])
File "C:\Users\Mudyla\AppData\Roaming\Python\Python37\site-packages\dash\dash.py", line 1153, in callback
self._validate_callback(output, inputs, state)
File "C:\Users\Mudyla\AppData\Roaming\Python\Python37\site-packages\dash\dash.py", line 807, in _validate_callback
layout = self._cached_layout or self._layout_value()
File "C:\Users\Mudyla\AppData\Roaming\Python\Python37\site-packages\dash\dash.py", line 430, in _layout_value
self._cached_layout = self._layout()
File "C:\Users\Mudyla\Desktop\Example\dashapp\app1.py", line 23, in serve_layout
children = '{}'.format(session.get('username', None))
File "C:\Users\Mudyla\AppData\Roaming\Python\Python37\site-packages\werkzeug\local.py", line 348, in __getattr__
return getattr(self._get_current_object(), name)
File "C:\Users\Mudyla\AppData\Roaming\Python\Python37\site-packages\werkzeug\local.py", line 307, in _get_current_object
return self.__local()
File "C:\Users\Mudyla\AppData\Roaming\Python\Python37\site-packages\flask\globals.py", line 37, in _lookup_req_object
raise RuntimeError(_request_ctx_err_msg)
RuntimeError: Working outside of request context.
Let me know if any other details are needed. Thanks!