Skip to content

Dash callbacks raising Flask 'RuntimeError: Working outside of request context.' #966

@Mudyla

Description

@Mudyla

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!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions