Skip to content

Commit 1a3b284

Browse files
committed
handle static files for multiple django configurations
1 parent 1abf2ea commit 1a3b284

File tree

3 files changed

+63
-12
lines changed

3 files changed

+63
-12
lines changed

bokeh_django/apps.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343

4444
class DjangoBokehConfig(AppConfig):
4545

46-
name = 'bokeh-django'
46+
name = 'bokeh_django'
4747
label = 'bokeh_django'
4848

4949
_routes: RoutingConfiguration | None = None

bokeh_django/consumers.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -153,8 +153,8 @@ async def handle(self, body: bytes) -> None:
153153
resources_param = self.get_argument("resources", "default")
154154
resources = self.resources(server_url) if resources_param != "none" else None
155155

156-
resources = self.resources(server_url)
157-
bundle = bundle_for_objs_and_resources(None, resources)
156+
root_url = urljoin(absolute_url, self._prefix) if absolute_url else self._prefix
157+
bundle = bundle_for_objs_and_resources(None, resources) # , root_url=root_url) TODO add root_url argument in bokeh
158158

159159
render_items = [RenderItem(token=session.token, elementid=element_id, use_for_title=False)]
160160
bundle.add(Script(script_for_render_items({}, render_items, app_path=app_path, absolute_url=absolute_url)))

bokeh_django/static.py

Lines changed: 60 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
from django.http import Http404
2626
from django.urls import re_path
2727
from django.views import static
28+
from django.contrib.staticfiles.finders import BaseFinder
29+
from django.utils._os import safe_join
2830

2931
# Bokeh imports
3032
from bokeh.embed.bundle import extension_dirs
@@ -33,17 +35,66 @@
3335
# General API
3436
# -----------------------------------------------------------------------------
3537

38+
class BokehExtensionFinder(BaseFinder):
39+
"""
40+
A custom staticfiles finder class to find bokeh resources.
41+
42+
In Django settings:
43+
When using `django.contrib.staticfiles' in `INSTALLED_APPS` then add
44+
`bokeh_django.static.BokehExtensionFinder` to `STATICFILES_FINDERS`
45+
"""
46+
_root = extension_dirs
47+
_prefix = 'extensions/'
48+
49+
def find(self, path, all=False):
50+
"""
51+
Given a relative file path, find an absolute file path.
52+
53+
If the ``all`` parameter is False (default) return only the first found
54+
file path; if True, return a list of all found files paths.
55+
"""
56+
matches = []
57+
location = self.find_location(path, self._prefix)
58+
if location:
59+
if not all:
60+
return location
61+
else:
62+
matches.append(location)
63+
64+
return matches
65+
66+
@classmethod
67+
def find_location(cls, path, prefix=None, as_components=False):
68+
"""
69+
Find the absolute path to a resouces given a relative path.
70+
71+
Args:
72+
path (str): relative path to resource
73+
prefix (str): if passed then verifies that path starts with `prefix` else returns `None`
74+
as_components (bool): If `True` return tuple of (artifacts_dir, artifact_path) rather than absolute path.
75+
Used when needing seperate components for `static.serve` function to manually serve resources.
76+
"""
77+
prefix = prefix or ''
78+
if not prefix or path.startswith(prefix):
79+
path = path[len(prefix):]
80+
try:
81+
name, artifact_path = path.split(os.sep, 1)
82+
except ValueError:
83+
pass
84+
else:
85+
artifacts_dir = cls._root.get(name, None)
86+
if artifacts_dir is not None:
87+
path = safe_join(artifacts_dir, artifact_path)
88+
if os.path.exists(path):
89+
if as_components:
90+
return artifacts_dir, artifact_path
91+
return path
3692

37-
def serve_extensions(request, path):
38-
root = extension_dirs
39-
40-
try:
41-
name, artifact_path = path.split(os.sep, 1)
42-
except ValueError:
43-
raise Http404
4493

45-
artifacts_dir = root.get(name, None)
46-
if artifacts_dir is not None:
94+
def serve_extensions(request, path):
95+
components = BokehExtensionFinder.find_location(path, as_components=True)
96+
if components is not None:
97+
artifacts_dir, artifact_path = components
4798
return static.serve(request, artifact_path, document_root=artifacts_dir)
4899
else:
49100
raise Http404

0 commit comments

Comments
 (0)