Hacktoberfest 2026 : les issues que les mainteneurs ont marquées pour octobre, ouvertes et accessibles aux débutants. Parcourir les issues Hacktoberfest

[BUG] Dash.run(debug=True, backend="fastapi") reload subprocess silently ignores reload_dirs/reload_excludes kwargs

Fermée
#3,962 1 commentaire 1 réaction 1 personne assignée Voir sur GitHub

Les mainteneurs répondent en général sous 2 jours

@T4rk1n y travaille déjà.

Depuis le 27/8/2026.

Évaluation

Cette issue n'a pas encore été évaluée.

Description

bug P2 size: 1

Summary

When using the FastAPI backend, app.run(host=..., port=..., debug=True, **kwargs) (main-thread, non-Jupyter path) triggers dash/backends/_fastapi.py::FastAPIBackend.run(), which spawns python -m uvicorn <module>:<app>.server --reload as a subprocess. Extra kwargs such as reload_dirs=[...] or reload_excludes=[...] are accepted by Dash.run(..., **flask_run_options) without error and flow straight into FastAPIBackend.run()'s **kwargs — but only kwargs.get("reload") is ever read there; every other reload-related kwarg is silently dropped when building the subprocess's CLI args. The comment directly above the subprocess.Popen(...) call even says:

# Add any other kwargs as CLI args if needed
proc = subprocess.Popen(uvicorn_args, env=env)

...but nothing implements it.

Practical effect: without an explicit --reload-dir, uvicorn/watchfiles fall back to watching the entire current working directory. In any project run with cwd above the app's own package (e.g. a monorepo, or simply python path/to/app/index.py invoked from a parent directory), the reload subprocess ends up recursively watching unrelated directories — including a shared virtualenv (.venv/site-packages/...) — so any unrelated package file being touched triggers a full, spurious app reload.

Reproduction

# repro.py -- run as `python repro.py` from a directory ABOVE this file,
# e.g.:
#   mkdir -p repo_root/app_dir && cd repo_root
#   (place this file at repo_root/app_dir/repro.py)
#   python app_dir/repro.py
from dash import Dash, html

app = Dash(__name__, backend="fastapi")
app.layout = html.Div("hello")

if __name__ == "__main__":
    app.run(
        host="127.0.0.1",
        port=8050,
        debug=True,
        reload_dirs=["app_dir"],
        reload_excludes=["app_dir/tests/*"],
    )
  • Expected: the spawned uvicorn --reload subprocess only watches app_dir/, excluding app_dir/tests/*.
  • Actual: reload_dirs/reload_excludes are silently ignored. The subprocess inherits the parent's cwd (repo_root/) and uvicorn defaults reload_dirs to [Path.cwd()], so it watches repo_root/ recursively -- including repo_root/.venv if one exists there.

Root cause

dash/backends/_fastapi.py, FastAPIBackend.run() (dash 4.4.1):

def run(self, dash_app: Dash, host, port, debug, **kwargs):
    ...
    uvicorn_args = [
        sys.executable, "-m", "uvicorn", app_path,
        "--host", str(host), "--port", str(port),
    ]
    if kwargs.get("reload"):
        uvicorn_args.append("--reload")

    dev_tools = dash_app._dev_tools
    config = dict(
        {"debug": debug} if debug else {"debug": False},
        **{f"dev_tools_{k}": v for k, v in dev_tools.items()},
    )
    env = os.environ.copy()
    env[_ENV_CONFIG] = json.dumps(config)

    # Add any other kwargs as CLI args if needed

    proc = subprocess.Popen(uvicorn_args, env=env)
    proc.wait()

Only kwargs["reload"] is ever consulted. reload_dirs, reload_excludes, reload_includes (and anything else a caller passes through app.run(...)) reach this function but are never translated into --reload-dir / --reload-exclude / --reload-include CLI args for the child process.

Suggested fix

Forward at least the reload-scoping kwargs onto uvicorn_args, e.g.:

for d in kwargs.get("reload_dirs") or []:
    uvicorn_args += ["--reload-dir", str(d)]
for p in kwargs.get("reload_excludes") or []:
    uvicorn_args += ["--reload-exclude", str(p)]
for p in kwargs.get("reload_includes") or []:
    uvicorn_args += ["--reload-include", str(p)]

Since this is silent today (no error, no warning), a caller has no way to discover the gap short of reading this source file directly. At minimum, forwarding these three would close the gap for the common case; more generally it might be worth warning on any kwarg that isn't recognized/forwarded here.

Environment

  • dash 4.4.1 (dash[fastapi], backend="fastapi")
  • uvicorn 0.52.0
  • Windows 11, Python 3.11 (the affected code path is not inside a platform-specific branch, so this should reproduce on any OS)

Related

Possibly adjacent to #3818 / #3912 (uvicorn --reload subprocess handling in the FastAPI backend also has callback double-registration issues there), but this is a distinct symptom -- silently dropped reload-scoping kwargs / overly broad default watch scope, not callback duplication.

Langage dominant
Python
Étoiles
24.4k
Forks
2.3k
Merge moyen
2 j 14 h
PR mergées (30 j)
23

Préparer son environnement

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Autres issues de plotly/dash

Toutes les issues de plotly/dash

Issues similaires

Plus d'issues Python

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.