What are you trying to do?
I’m trying to modify the flask_gunicorn_embed.py
script from the github examples (link) to have multiple interactive Bokeh apps embedded on the same HTML page. My only requirements are that
-
both embedded apps are interactive, so each should be controlled by its own widget(s)
-
gunicorn
will utilize multiple worker processes (i.e.--workers
will be larger than 1)
If this is a question about Bokeh code, please post a Minimal, Reproducible Example so that reviewers can test and see what you see. A guide to do this is here: How to create a Minimal, Reproducible Example - Help Center - Stack Overflow
Yes, this is about Bokeh code. Specifically, it is focused on adapting (explained next) the flask_gunicorn_embed.py
example from github.
What have you tried that did NOT work as expected?
The working procedure I’ve followed to modify flask_gunicorn_embed.py
is below
First, I added a second Bokeh application. As with the existing one (used in the github example), I passed a single handler
bkapp1 = Application(FunctionHandler(bkapp)) # original
bkapp2 = Application(FunctionHandler(bkapp)) # added this <---
Next, modify bkapp_page()
to include a second application, where the server_document
(doc) url
parameter includes the second app’s name (I chose bkapp2
)
@app.route("/", methods=["GET"])
def bkapp_page():
script = {
"app_one": server_document("http://localhost:8000/bkapp"), # original
"app_two": server_document("http://localhost:8000/bkapp2") # added this <---
}
Next, modify the dict of applications
submitted to BokehTornado
(doc) to include the second app (bkapp2
)
def bk_worker()
BokehTornado(
{
"/bkapp1": bkapp, # original
"/bkapp2": bkapp2, # added this <---
},
extra_websocket_origins=["localhost:8000"],
)
Lastly, modify the HTML body
content in embed.html
to include both apps. Replace
<body>
<div>
This Bokeh app...
</div>
{{ script|safe }}
</body>
by this
<body>
<div>
This Bokeh app...
</div>
{{ script.app_one|safe }}
{{ script.app_two|safe }}
</body>
When I run this as recommended in the script’s docstring
gunicorn -w 4 flask_gunicorn_embed:app
the two Bokeh apps appear to be working fine (embedded on the same web page, as required).
Next, I replaced the entire app definition itself bkapp(doc)
(lines 36 to 54 from flask_gunicorn_embed.py
) with the sliders example from the Gallery (no changes), and everything continues to work just fine - two independent interactive versions of the same app are embeded on the same HTML page (see the attached screenshot). Each of the two slider widgets controls their own app and there are no delays or other unexpected behaviours.
This seems too simple and I’m sure I’m missing something or not following best practices.
Questions
- Is this the correct approach to embed multiple interactive Bokeh apps in the same HTML page using Flask and Gunicorn?
- Additionally, I’m concerned about using the same port (8000) in both apps’
server_document()
definition (http://localhost:8000/bkapp
andhttp://localhost:8000/bkapp2
) - is this a problem, or could it cause performance issues as more apps are added in the same way?
System Details
bokeh==2.2.3
Python 3.8.5
Operating System == Ubuntu 20.04 LTS (Desktop version)
Other Links I searched through
-
Google Groups post from 2016
- linked to from this SO answer from 2019