How to handle with redirect in Dash app?

You need to adjust your code based on your app’s layout. I made some adjustment so that this can work for your case.

import datetime

import dash
from dash import Input, Output, dcc, html
from flask import Flask, jsonify, redirect, request, session

# Initialize Flask and Dash apps
server = Flask(__name__)
server.secret_key = "your_secret_key"  # Used to protect the session
server.config["PERMANENT_SESSION_LIFETIME"] = datetime.timedelta(seconds=30)
app = dash.Dash(__name__, server=server, url_base_pathname="/")


# Let's assume this is the function to check the user's logged-in status
def user_is_logged_in():
    return bool(session.get("user"))


@server.route("/login", methods=["GET", "POST"])
def login_page():
    session.permanent = True
    if request.method == "POST":
        session["user"] = f"{request.form['username']}:{request.form['password']}"
        return redirect("/")
    else:
        return (
            '<form method="post">'
            '<input type="text" name="username" id="un" title="username" placeholder="username"/>'
            '<input type="password" name="password" id="pw" title="username" placeholder="password"/>'
            '<button type="submit">Login</button>'
            "</form>"
        )


@server.before_request
def before_request_func():
    # Check if the user is logged in
    if not user_is_logged_in() and request.path != "/login":
        # Check the request path and method
        if request.path == "/_dash-update-component" and request.method == "POST":
            # If the user is not logged in, return a JSON response to redirect to /login
            return jsonify({"multi": True, "response": {"url": {"pathname": "/login"}}})
        else:
            return redirect("/login")


d = {v: v.capitalize() for v in ["a", "b", "c", "d"]}

app.layout = html.Div(
    [
        dcc.Location(id="url", refresh=True),
        html.Div(
            [
                html.Label("Labels"),
                dcc.Dropdown(
                    [{"label": v, "value": k} for k, v in d.items()],
                    value=None,
                    id="dropdown",
                ),
                html.Div("Select one of the label"),
            ],
        ),
        html.Div(id="indicator"),
    ]
)


@app.callback(
    Output("indicator", "children"),
    [Input("dropdown", "value")],
    prevent_initial_call=True,
)
def update_indicator(val):
    return d[val]


# Run the server
if __name__ == "__main__":
    server.run(port=5008)

2 Likes