bokeh-django
Support for running Bokeh apps with Django
Introduction
Both Bokeh and Django are web frameworks that can be used independently to build and host web applications. They each have their own strengths and the purpose of the bokeh_django package is to integrate these two frameworks so their strengths can be used together.
Installation
pip install bokeh-django
Configuration
This documentation assumes that you have already started a Django project.
bokeh-django enables you to define routes (URLs) in your Django project that will map to Bokeh applications or embed Bokeh applications into a template rendered by Django. However, before defining the routes there are several configuration steps that need to be completed first.
-
Configure
INSTALLED_APPS:In the
settings.pyfile ensure that bothchannelsandbokeh_djangoare added to theINSTALLED_APPSlist:INSTALLED_APPS = [ ..., 'channels', 'bokeh_django', ]
-
Set Up an ASGI Application:
By default, the Django project will be configured to use a WSGI application, but the
startprojectcommand should have also created anasgi.pyfile.In
settings.pychange theWSGI_APPLICATIONsetting toASGI_APPLICATIONand modify the path accordingly. It should look something like this:ASGI_APPLICATION = 'mysite.asgi.application'
Next, modify the contents of the
asgi.pyfile to get the URL patterns from thebokeh_djangoapp config. Something similar to this will work:from channels.auth import AuthMiddlewareStack from channels.routing import ProtocolTypeRouter, URLRouter from django.apps import apps bokeh_app_config = apps.get_app_config('bokeh_django') application = ProtocolTypeRouter({ 'websocket': AuthMiddlewareStack(URLRouter(bokeh_app_config.routes.get_websocket_urlpatterns())), 'http': AuthMiddlewareStack(URLRouter(bokeh_app_config.routes.get_http_urlpatterns())), })
-
Configure Static Files:
Both Bokeh and Django have several ways of configuring serving static resources. This documentation will describe several possible configuration approaches.
The Bokeh
resourcessetting can be set to one of several values (e.gserver,inline,cdn), the default iscdn. If this setting is set toinline, orcdnthen Bokeh resources will be served independently of Django resources. However, if the Bokehresourcessetting is set toserver, then the Bokeh resources are served up by the Django server in the same way that the Django static resources are and so Django must be configured to be able to find the Bokeh resources.To specify the Bokeh
resourcessetting add the following to the Djangosettings.pyfile:from bokeh.settings import settings as bokeh_settings bokeh_settings.resources = 'server'
If the Bokeh
resourcessetting is set toserverthen we must add the location of the Bokeh resources to theSTATICFILES_DIRSsetting:from bokeh.settings import settings as bokeh_settings try: bokeh_js_dir = bokeh_settings.bokehjs_path() except AttributeError: # support bokeh versions < 3.4 bokeh_js_dir = bokeh_settings.bokehjsdir() STATICFILES_DIRS = [ ..., bokeh_js_dir, ]
Django can be configured to automatically find and collect static files using the
staticfilesapp, or the static file URL patterns can be explicitly added to the list ofurlpatternsin theurls.pyfile.To explicitly add the static file
urlpatternsadd the following to theurls.pyfile:from django.contrib.staticfiles.urls import staticfiles_urlpatterns from bokeh_django import static_extensions urlpatterns = [ ..., *static_extensions(), *staticfiles_urlpatterns(), ]
Be sure that the
static_extensionsare listed before thestaticfiles_urlpatterns.Alternatively, you can configure the
staticfilesapp by adding'django.contrib.staticfiles',toINSTALLED_APPS:INSTALLED_APPS = [ ..., 'django.contrib.staticfiles', 'channels', 'bokeh_django', ]
Next add
bokeh_django.static.BokehExtensionFinderto theSTATICFILES_FINDERSsetting. The default value forSTATICFILES_FINDERShas two items. If you override the default by adding theSTATICFILES_FINDERSsetting to yoursettings.pyfile, then be sure to also list the two default values in addition to theBokehExtensionFinder:STATICFILES_FINDERS = ( "django.contrib.staticfiles.finders.FileSystemFinder", "django.contrib.staticfiles.finders.AppDirectoriesFinder", 'bokeh_django.static.BokehExtensionFinder', )
Define Routes
Bokeh applications are integrated into Django through routing or URLs.
In a Django app, the file specified by the ROOT_URLCONF setting (e.g. urls.py) must define urlpatterns which is a sequence of django.url.path and/or django.url.re_path objects. When integrating a Django app with Bokeh, the urls.py file must also define bokeh_apps as a sequence of bokeh_django routing objects. This should be done using the bokeh_djagno.document and/or bokeh_django.autoload functions.
Document
The first way to define a route is to use bokeh_django.document, which defines a route to a Bokeh app (as either a file-path or a function).
from bokeh_django import document
from .views import my_bokeh_app_function
bokeh_apps = [
document('url-pattern/', '/path/to/bokeh/app.py'),
document('another-url-pattern/', my_bokeh_app_function)
]
When using the document route Django will route the URL directly to the Bokeh app and all the rendering will be handled by Bokeh.
Directory
An alternative way to create document routes is to use bokeh_django.directory to automatically create a document route for all the bokeh apps found in a directory. In this case the file name will be used as the URL pattern.
from bokeh_django import directory
bokeh_apps = directory('/path/to/bokeh/apps/')
Autoload
To integrate more fully into a Django application routes can be created using autoload. This allows the Bokeh application to be embedded in a template that is rendered by Django. This has the advantage of being able to leverage Django capabilities in the view and the template, but is slightly more involved to set up. There are five components that all need to be configured to work together: the Bokeh handler, the Django view, the template, the Django URL path, and the Bokeh URL route.
Bokeh Handler
The handler is a function (or any callable) that accepts a bokeh.document.Document object and configures it with the Bokeh content that should be embedded. This is done by adding a Bokeh object as the document root:
from bokeh.document import Document
from bokeh.layouts import column
from bokeh.models import Slider
def bokeh_handler(doc: Document) -> None:
slider = Slider(start=0, end=30, value=0, step=1, title="Example")
doc.add_root(column(slider))
The handler can also embed a Panel object. In this case the document is passed in to the server_doc method of the Panel object:
import panel as pn
def panel_handler(doc: Document) -> None:
pn.Row().server_doc(doc)
Django View
The view is a Django function that accepts a request object and returns a response. A view that embeds a Bokeh app must create a bokeh.embed.server_document and pass it in the context to the template when rendering the response.
from bokeh.embed import server_document
from django.shortcuts import render
def view_function(request):
script = server_document(request.build_absolute_uri())
return render(request, "embed.html", dict(script=script))
Template
The template document is a Django HTML template (e.g. "embed.html") that will be rendered by Django. It can be as complex as desired, but at the very least must render the script that was passed in from the context:
<!doctype html>
<html lang="en">
<body>
{{ script|safe }}
</body>
</html>
Django URL Path
The Django URL Path is a django.url.path or django.url.re_path object that is included in the urlpatters sequence and that maps a URL pattern to the Django View as would normally be done with Django.
urlpatterns = [
path("embedded-bokeh-app/", views.view_function),
]
Bokeh URL Route
The Bokeh URL Route is a bokeh_django.autoload object that is included in the bokeh_apps sequence and that maps a URL pattern to the Bokeh handler.
from bokeh_django import autoload
bokeh_apps = [
autoload("embedded-bokeh-app/", views.handler)
]
Note that the URL pattern should be the same URL pattern that was used in the corresponding Django URL Path. In reality the URL pattern must match the URL that the server_document script is configured with in the Django View. Normally, it is easiest to use the URL from the request object (e.g. script = server_document(request.build_absolute_uri())), which is the URL of the corresponding Django URL Path.
Metadata
Release files for bokeh-django 0.2.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| bokeh_django-0.2.1.tar.gz | 16.6 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| bokeh_django-0.2.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 32.1 kB
Release files / bokeh_django-0.2.1.tar.gz
| Download URL | bokeh_django-0.2.1.tar.gz |
|---|---|
| Size | 16.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
d97221b86a63b8398a1a2d784d93807b14c910541da76c260b83b5b88be8679a
|
|
BLAKE2b-256 checksum How to use checksums |
4eac0b084305154d00233bf5d7a5d4485bbdcdfde87d07f1b1c5e73ca449cd0c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.2
|
Release files / bokeh_django-0.2.1-py3-none-any.whl
| Download URL | bokeh_django-0.2.1-py3-none-any.whl |
|---|---|
| Size | 15.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
c69437ac8f251d1266de025342c4d8235415b8538236876ef94728fbd8bb2802
|
|
BLAKE2b-256 checksum How to use checksums |
5fe6874ed997c449cf985638fe6df585010e2366b76b574789986efe3b9a28c8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.2
|
Security for bokeh-django 0.2.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.