Repository: plotly/dash

Issue:
[BUG] Deprecation warnings when running basic test in dash documentation
```
dash                 2.6.2
dash-core-components 2.0.0
dash-html-components 2.0.0
dash-table           5.0.0
```

**Describe the bug**

When running the basic [dash test](https://dash.plotly.com/testing#example---basic-test) from the documentation, I get the following warning.
```
tests/test_website.py::test_001_child_with_0
  C:\Users\ethopon\AppData\Local\pypoetry\Cache\virtualenvs\poetry-demo-VBrwyLAy-py3.10\lib\site-packages\flask\scaffold.py:50: DeprecationWarning:

  'before_first_request' is deprecated and will be removed in Flask 2.3. Run setup code while creating the application instead.

-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
```
**Expected behavior**

I expect to get no warnings.





Discussion:

Resolving patch:
diff --git a/dash/_pages.py b/dash/_pages.py
--- a/dash/_pages.py
+++ b/dash/_pages.py
@@ -5,11 +5,13 @@
 from urllib.parse import parse_qs
 from fnmatch import fnmatch
 import re
+import flask
 
 from . import _validate
 from ._utils import AttributeDict
 from ._get_paths import get_relative_path
 from ._callback_context import context_value
+from ._get_app import get_app
 
 
 CONFIG = AttributeDict()
@@ -118,6 +120,25 @@ def _parse_path_variables(pathname, path_template):
     return dict(zip(var_names, variables))
 
 
+def _create_redirect_function(redirect_to):
+    def redirect():
+        return flask.redirect(redirect_to, code=301)
+
+    return redirect
+
+
+def _set_redirect(redirect_from, path):
+    app = get_app()
+    if redirect_from and len(redirect_from):
+        for redirect in redirect_from:
+            fullname = app.get_relative_path(redirect)
+            app.server.add_url_rule(
+                fullname,
+                fullname,
+                _create_redirect_function(app.get_relative_path(path)),
+            )
+
+
 def register_page(
     module,
     path=None,
@@ -280,7 +301,7 @@ def register_page(
         image=(image if image is not None else _infer_image(module)),
         image_url=image_url,
     )
-    page.update(redirect_from=redirect_from)
+    page.update(redirect_from=_set_redirect(redirect_from, page["path"]))
 
     PAGE_REGISTRY[module] = page
 
diff --git a/dash/dash.py b/dash/dash.py
--- a/dash/dash.py
+++ b/dash/dash.py
@@ -497,6 +497,9 @@ def __init__(  # pylint: disable=too-many-statements
             for plugin in plugins:
                 plugin.plug(self)
 
+        # tracks internally if a function already handled at least one request.
+        self._got_first_request = {"pages": False, "setup_server": False}
+
         if self.server is not None:
             self.init_app()
 
@@ -542,7 +545,7 @@ def _handle_error(_):
             """Handle a halted callback and return an empty 204 response."""
             return "", 204
 
-        self.server.before_first_request(self._setup_server)
+        self.server.before_request(self._setup_server)
 
         # add a handler for components suites errors to return 404
         self.server.errorhandler(InvalidResourceError)(self._invalid_resources_handler)
@@ -1271,6 +1274,10 @@ def dispatch(self):
         return response
 
     def _setup_server(self):
+        if self._got_first_request["setup_server"]:
+            return
+        self._got_first_request["setup_server"] = True
+
         # Apply _force_eager_loading overrides from modules
         eager_loading = self.config.eager_loading
         for module_name in ComponentRegistry.registry:
@@ -2027,8 +2034,12 @@ def enable_pages(self):
         if self.pages_folder:
             self._import_layouts_from_pages()
 
-        @self.server.before_first_request
+        @self.server.before_request
         def router():
+            if self._got_first_request["pages"]:
+                return
+            self._got_first_request["pages"] = True
+
             @self.callback(
                 Output(_ID_CONTENT, "children"),
                 Output(_ID_STORE, "data"),
@@ -2107,24 +2118,6 @@ def update(pathname, search):
                 Input(_ID_STORE, "data"),
             )
 
-            def create_redirect_function(redirect_to):
-                def redirect():
-                    return flask.redirect(redirect_to, code=301)
-
-                return redirect
-
-            # Set redirects
-            for module in _pages.PAGE_REGISTRY:
-                page = _pages.PAGE_REGISTRY[module]
-                if page["redirect_from"] and len(page["redirect_from"]):
-                    for redirect in page["redirect_from"]:
-                        fullname = self.get_relative_path(redirect)
-                        self.server.add_url_rule(
-                            fullname,
-                            fullname,
-                            create_redirect_function(page["relative_path"]),
-                        )
-
     def run_server(self, *args, **kwargs):
         """`run_server` is a deprecated alias of `run` and may be removed in a
         future version. We recommend using `app.run` instead.


Test patch: