Skip to content

Commit 31a832e

Browse files
committed
🔗 get_relative_path
1 parent ee35164 commit 31a832e

File tree

3 files changed

+70
-3
lines changed

3 files changed

+70
-3
lines changed

dash/_utils.py

+12
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,18 @@ def get_asset_path(requests_pathname, asset_path, asset_url_path):
5454
)
5555

5656

57+
58+
def get_relative_path(requests_pathname, path):
59+
60+
return "/".join(
61+
[
62+
# Only take the first part of the pathname
63+
requests_pathname.rstrip("/"),
64+
path
65+
]
66+
)
67+
68+
5769
# pylint: disable=no-member
5870
def patch_collections_abc(member):
5971
return getattr(collections if utils.PY2 else collections.abc, member)

dash/dash.py

+30-2
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
from ._utils import patch_collections_abc as _patch_collections_abc
3636
from . import _watch
3737
from ._utils import get_asset_path as _get_asset_path
38+
from ._utils import get_relative_path as _get_relative_path
3839
from ._utils import create_callback_id as _create_callback_id
3940
from ._configs import get_combined_config, pathname_configs
4041
from .version import __version__
@@ -1357,7 +1358,7 @@ def add_context(*args, **kwargs):
13571358
has_update = False
13581359
for i, o in enumerate(output):
13591360
val = output_value[i]
1360-
if not isinstance(val, _NoUpdate):
1361+
if val is not no_update:
13611362
has_update = True
13621363
o_id, o_prop = o.component_id, o.component_property
13631364
component_ids[o_id][o_prop] = val
@@ -1367,7 +1368,7 @@ def add_context(*args, **kwargs):
13671368

13681369
response = {"response": component_ids, "multi": True}
13691370
else:
1370-
if isinstance(output_value, _NoUpdate):
1371+
if output_value is no_update:
13711372
raise exceptions.PreventUpdate
13721373

13731374
response = {
@@ -1565,6 +1566,33 @@ def get_asset_url(self, path):
15651566

15661567
return asset
15671568

1569+
def get_relative_path(self, path):
1570+
"""
1571+
Return a path with `requests_pathname_prefix` prefixed before it.
1572+
1573+
Use this function when specifying local URL paths that will work
1574+
in environments regardless of what `requests_pathname_prefix` is.
1575+
1576+
In some deployment environments, like Dash Enterprise,
1577+
`requests_pathname_prefix` is set to the application name,
1578+
e.g. `my-dash-app`.
1579+
1580+
When working locally, `requests_pathname_prefix` might be unset and
1581+
so a relative URL like `/page-2` can just be `/page-2`.
1582+
1583+
However, when the app is deployed to a URL like `/my-dash-app`, then
1584+
`app.get_relative_path('/page-2')` will return `/my-dash-app/page-2`.
1585+
1586+
This can be used as an alternative to `get_asset_url` as well with
1587+
`app.get_relative_path('/assets/logo.png')`
1588+
"""
1589+
asset = _get_relative_path(
1590+
self.config.requests_pathname_prefix,
1591+
path,
1592+
)
1593+
1594+
return asset
1595+
15681596
def _setup_dev_tools(self, **kwargs):
15691597
debug = kwargs.get("debug", False)
15701598
dev_tools = self._dev_tools = _AttributeDict()

tests/unit/test_configs.py

+28-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,10 @@
1212
get_combined_config,
1313
load_dash_env_vars,
1414
)
15-
from dash._utils import get_asset_path
15+
from dash._utils import (
16+
get_asset_path,
17+
get_relative_path,
18+
)
1619

1720

1821
@pytest.fixture
@@ -156,3 +159,27 @@ def test_load_dash_env_vars_refects_to_os_environ(empty_environ):
156159
def test_app_name_server(empty_environ, name, server, expected):
157160
app = Dash(name=name, server=server)
158161
assert app.config.name == expected
162+
163+
164+
@pytest.mark.parametrize(
165+
"prefix, partial_path, expected",
166+
[
167+
("/", "/", "/"),
168+
("/my-dash-app", "/", "/my-dash-app/"),
169+
170+
("/", "/page-1", "/page-1"),
171+
("/my-dash-app", "/page-1", "/my-dash-app/page-1"),
172+
173+
("/", "/page-1/", "/page-1/"),
174+
("/my-dash-app", "/page-1/", "/my-dash-app/page-1/"),
175+
176+
("/", "/page-1/sub-page-1", "/page-1/sub-page-1"),
177+
("/my-dash-app", "/page-1/sub-page-1", "/my-dash-app/page-1/sub-page-1"),
178+
179+
("/", "relative-page-1", "relative-page-1"),
180+
("/my-dash-app", "/my-dash-apprelative-page-1", "/my-dash-apprelative-page-1"),
181+
],
182+
)
183+
def test_pathname_prefix_relative_url(prefix, partial_path, expected):
184+
path = get_relative_path(prefix, partial_path)
185+
assert path == expected

0 commit comments

Comments
 (0)