Skip to content

Commit 493d150

Browse files
committed
fixes for pages
1 parent 16b3c9e commit 493d150

File tree

5 files changed

+181
-152
lines changed

5 files changed

+181
-152
lines changed

dash/_pages.py

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -150,22 +150,13 @@ def _parse_path_variables(pathname, path_template):
150150
return dict(zip(var_names, variables))
151151

152152

153-
def _create_redirect_function(redirect_to):
154-
def redirect():
155-
return flask.redirect(redirect_to, code=301)
156-
157-
return redirect
158-
159-
160153
def _set_redirect(redirect_from, path):
161154
app = get_app()
162155
if redirect_from and len(redirect_from):
163156
for redirect in redirect_from:
164157
fullname = app.get_relative_path(redirect)
165-
app.server.add_url_rule(
166-
fullname,
167-
fullname,
168-
_create_redirect_function(app.get_relative_path(path)),
158+
app.backend.add_redirect_rule(
159+
app, fullname, app.get_relative_path(path)
169160
)
170161

171162

dash/backends/_fastapi.py

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515

1616
try:
1717
from fastapi import FastAPI, Request, Response, Body
18-
from fastapi.responses import JSONResponse
18+
from fastapi.responses import JSONResponse, RedirectResponse
1919
from fastapi.staticfiles import StaticFiles
2020
from starlette.responses import Response as StarletteResponse
2121
from starlette.datastructures import MutableHeaders
@@ -27,6 +27,7 @@
2727
Response = None
2828
Body = None
2929
JSONResponse = None
30+
RedirectResponse = None
3031
StaticFiles = None
3132
StarletteResponse = None
3233
MutableHeaders = None
@@ -115,6 +116,7 @@ def __init__(self, server: FastAPI):
115116
self.server: FastAPI = server
116117
self.error_handling_mode = "ignore"
117118
self.request_adapter = FastAPIRequestAdapter
119+
self._before_request_funcs = []
118120
super().__init__()
119121

120122
def __call__(self, *args: Any, **kwargs: Any):
@@ -213,9 +215,13 @@ def add_url_rule(
213215
)
214216

215217
def before_request(self, func: Callable[[], Any] | None):
216-
# FastAPI does not have before_request, but we can use middleware
217-
self.server.add_middleware(CurrentRequestMiddleware)
218-
self.server.middleware("http")(self._make_before_middleware(func))
218+
if func is not None:
219+
self._before_request_funcs.append(func)
220+
# Only add the middleware once
221+
if not hasattr(self, "_before_middleware_added"):
222+
self.server.add_middleware(CurrentRequestMiddleware)
223+
self.server.middleware("http")(self._make_before_middleware())
224+
self._before_middleware_added = True
219225

220226
def after_request(self, func: Callable[[], Any] | None):
221227
# FastAPI does not have after_request, but we can use middleware
@@ -262,18 +268,20 @@ def make_response(
262268
def jsonify(self, obj: Any):
263269
return JSONResponse(content=obj)
264270

265-
def _make_before_middleware(self, _func: Callable[[], Any] | None):
271+
def _make_before_middleware(self):
266272
async def middleware(request, call_next):
273+
for func in self._before_request_funcs:
274+
if inspect.iscoroutinefunction(func):
275+
await func()
276+
else:
277+
func()
267278
try:
268279
response = await call_next(request)
269280
return response
270281
except PreventUpdate:
271-
# No content, nothing to update
272282
return Response(status_code=204)
273-
except (Exception) as e: # pylint: disable=broad-except
274-
# Handle exceptions based on error_handling_mode
283+
except Exception as e:
275284
if self.error_handling_mode in ["raise", "prune"]:
276-
# Prune the traceback to remove internal Dash calls
277285
tb = self._get_traceback(None, e)
278286
return Response(content=tb, media_type="text/html", status_code=500)
279287
return JSONResponse(
@@ -338,6 +346,21 @@ async def serve(request: Request, package_name: str, fingerprinted_path: str):
338346
name = "_dash-component-suites/{package_name}/{fingerprinted_path:path}"
339347
dash_app._add_url(name, serve) # pylint: disable=protected-access
340348

349+
def _create_redirect_function(self, redirect_to):
350+
def _redirect():
351+
return RedirectResponse(url=redirect_to, status_code=301)
352+
353+
return _redirect
354+
355+
def add_redirect_rule(self, app, fullname, path):
356+
self.server.add_api_route(
357+
fullname,
358+
self._create_redirect_function(app.get_relative_path(path)),
359+
methods=["GET"],
360+
name=fullname,
361+
include_in_schema=False,
362+
)
363+
341364
def dispatch(self, dash_app: Dash):
342365
async def _dispatch(request: Request):
343366
# pylint: disable=protected-access

dash/backends/_flask.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
request,
1717
jsonify,
1818
g as flask_g,
19+
redirect,
1920
)
2021
from werkzeug.debug import tbtools
2122

@@ -194,6 +195,19 @@ def serve(package_name, fingerprinted_path):
194195
serve,
195196
)
196197

198+
def _create_redirect_function(self, redirect_to):
199+
def _redirect():
200+
return redirect(redirect_to, code=301)
201+
202+
return _redirect
203+
204+
def add_redirect_rule(self, app, fullname, path):
205+
self.server.add_url_rule(
206+
fullname,
207+
fullname,
208+
self._create_redirect_function(app.get_relative_path(path)),
209+
)
210+
197211
# pylint: disable=unused-argument
198212
def dispatch(self, dash_app: Dash):
199213
def _dispatch():

dash/backends/_quart.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
request,
1818
Blueprint,
1919
g,
20+
redirect,
2021
)
2122
except ImportError:
2223
Quart = None
@@ -233,6 +234,19 @@ async def serve(package_name, fingerprinted_path):
233234
serve,
234235
)
235236

237+
def _create_redirect_function(self, redirect_to):
238+
def _redirect():
239+
return redirect(redirect_to, code=301)
240+
241+
return _redirect
242+
243+
def add_redirect_rule(self, app, fullname, path):
244+
self.server.add_url_rule(
245+
fullname,
246+
fullname,
247+
self._create_redirect_function(app.get_relative_path(path)),
248+
)
249+
236250
# pylint: disable=unused-argument
237251
def dispatch(self, dash_app: Dash): # type: ignore[name-defined] Quart always async
238252
async def _dispatch():

0 commit comments

Comments
 (0)