I managed to make the following “work”. It’s hacky and gets into a bad state if you move the slider too fast…
from bokeh.core.json_encoder import serialize_json
from bokeh.embed.elements import div_for_render_item
from bokeh.embed.util import RenderItem
from bokeh.io import curdoc, output_notebook
from bokeh.io.notebook import get_comms, publish_display_data
from bokeh.protocol import Protocol
from bokeh.util.serialization import make_id
template = ‘’’
{
const { Document } = Bokeh.require(‘document’);
const { notebook: { kernel: { comm_manager } } } = Jupyter;
const doc = Document.from_json(%s); // doc_json
const { elementid, roots } = %s; // render_item
const target = ‘%s’;
comm_manager.register_target(target, (comm) => {
comm.on_msg(({ content: { data } }) => {
doc.apply_json_patch(data);
});
doc.on_change((event) => {
if (event.setter_id === target) {
return;
}
comm.send(doc.create_json_patch([event]));
});
});
const element = document.getElementById(elementid);
const root_ids = Object.entries(roots)
.reduce((obj, [key, id]) => ({ …obj, [key]: document.getElementById(id) }), {});
Bokeh.embed.add_document_standalone(doc, element, root_ids);
}‘’’
def show(model):
doc = curdoc()
doc.clear()
doc.add_root(model)
comms_target = make_id()
render_item = RenderItem(make_id(), elementid=make_id(), roots=[model])
div = div_for_render_item(render_item)
script = template % (serialize_json(doc.to_json()),
serialize_json(render_item.to_json()),
comms_target)
HTML_MIME_TYPE = ‘text/html’
JS_MIME_TYPE = ‘application/javascript’
EXEC_MIME_TYPE = ‘application/vnd.bokehjs_exec.v0+json’
publish_display_data({HTML_MIME_TYPE: div})
publish_display_data({JS_MIME_TYPE: script, EXEC_MIME_TYPE: “”},
metadata={EXEC_MIME_TYPE: {“id”: model._id}})
comms = get_comms(comms_target)
protocol = Protocol(‘1.0’)
@doc.on_change
def send_patch_doc(event):
message = protocol.create(‘PATCH-DOC’, [event])
comms.send(message.content)
@comms.on_msg
def handle_msg(msg):
doc.apply_json_patch(msg[‘content’][‘data’])
output_notebook()
``
···
On Friday, April 26, 2019 at 12:47:34 AM UTC-4, Bryan Van de Ven wrote:
Hi,
Unfortunately this is not really in my area of expertise, I’d suggest trying to ping some of the people on the original PR for guidance:
[https://github.com/bokeh/bokeh/pull/7686](https://github.com/bokeh/bokeh/pull/7686)
Thanks,
Bryan
On Apr 25, 2019, at 3:27 PM, [email protected] wrote:
Note BTW that it’s not just failing because a https page tries loading from http, it’s also trying to load from ‘localhost’ which presumably means something very different on my desktop then in the docker container where the Bokeh Server is actually running.
On Thursday, April 25, 2019 at 6:24:45 PM UTC-4, [email protected] wrote:
Yes, I did try using the amended proxy function and observed basically the same thing you did. I’m wondering whether it wouldn’t be easier to only create pieces of a Bokeh Server (not sure which ones yet) then push messages through Jupyter websockets like in the notebook handle scenario. What do you think of that approach?
On Thursday, April 25, 2019 at 10:59:32 AM UTC-4, Bryan Van de Ven wrote:
Hi,
The discussion here is orthogonal to all the deployment scenarios discussion in my mind. The central issue is that A secure https page is trying to load a script from an unsecure http URL. I’m not sure why that ia offhand. Did you actually try using the proxy function below? What exact steps did you try?
Thanks,
Bryan
On Apr 25, 2019, at 4:38 AM, [email protected] wrote:
Yes, I concur that it does work fine when I run the notebook locally. I’m looking for a way to run it in MyBinder because I wrote a notebook I’d like to publish as a blog. It would be so much more interesting if it could link to a “live” demo.
Is the real challenge here that, while I can launch a Bokeh server from a Jupyter notebook running in MyBinder, I can’t do any of the necessary Deployment Scenarios steps? Do you think the MyBinder folks have any appetite to support that? Maybe a hint in the github repo that lets them know to spin up a Bokeh Server alongside the JupyterHub one and a hook in bokeh.io.output_notebook to use bokeh.embed.server_session in that context.
The blog, if you’re curious, walks through four distinct implementations of the the same simple Bokeh app (a stripped down version of http://optioncreator.com/):
• using a Bokeh server and python callbacks
• leveraging CustomJS.from_py_func
• leveraging CustomJS but writing the JavaScript by hand
• using only BokehJS, no python
This mirrors how we leveraged Bokeh in a corporate environment for, well, reasons. To be fair, the deployment story is one reason we rewrote our callbacks in JavaScript.
On Wednesday, April 24, 2019 at 10:22:45 PM UTC-4, Bryan Van de Ven wrote:
Hi,
It works fine when I run the notebook locally. On MyBinder the JS log shows:
[blocked] The page at https://hub.mybinder.org/user/bokeh-bokeh-notebooks-hrgw5y2i/notebooks/tutorial/11%20-%20Running%20Bokeh%20Applications.ipynb was not allowed to run insecure content from http://localhost:42457/autoload.js?bokeh-autoload-element=1002&bokeh-absolute-url=http://localhost:42457&resources=none.
Which suggests MyBinder is running a configuration that is incompatible with embedding Bokeh apps in the notebook. Specifically, it looks like that have not run jupyterhub itself behind HTTPS. No browser will ever load a JS script on an https page, from an http URL and I am not sure that the remote_jupyter_proxy_url approach helps with this problem. (Tho if I am wrong I hope someone can correct me) Otherwise I can only suggest to clone the repo and run locally:
[https://github.com/bokeh/bokeh-notebooks](https://github.com/bokeh/bokeh-notebooks)
Thanks,
Bryan
On Apr 24, 2019, at 5:55 PM, [email protected] wrote:
Hi,
I would really love to make 11 - Running Bokeh Applications.ipynb work. I have tried adapting this guidance as shown below but it doesn’t work. Has anybody figured this out?
Thanks,
Jan
import os
import urllib.parse
def remote_jupyter_proxy_url(port):
“”"
Callable to configure Bokeh’s show method when a proxy must be
configured.
If port is None we're asking about the URL
for the origin header.
"""
base_url = '[https://hub.mybinder.org](https://hub.mybinder.org)'
host = urllib.parse.urlparse(base_url).netloc
# If port is None we're asking for the URL origin
# so return the public hostname.
if port is None:
return host
service_url_path = os.environ['JUPYTERHUB_SERVICE_PREFIX']
proxy_url_path = 'proxy/%d' % port
user_url = urllib.parse.urljoin(base_url, service_url_path)
full_url = urllib.parse.urljoin(user_url, proxy_url_path)
return full_url
–
You received this message because you are subscribed to the Google Groups “Bokeh Discussion - Public” group.
To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit https://groups.google.com/a/continuum.io/d/msgid/bokeh/e43de983-b88b-4371-b02c-d3b3cd2d965c%40continuum.io.
For more options, visit https://groups.google.com/a/continuum.io/d/optout.
–
You received this message because you are subscribed to the Google Groups “Bokeh Discussion - Public” group.
To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit https://groups.google.com/a/continuum.io/d/msgid/bokeh/26c2b5cb-76f6-4466-81a9-1a99003d75c2%40continuum.io.
For more options, visit https://groups.google.com/a/continuum.io/d/optout.
–
You received this message because you are subscribed to the Google Groups “Bokeh Discussion - Public” group.
To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit https://groups.google.com/a/continuum.io/d/msgid/bokeh/6efe9f98-f016-49c5-9521-b06fdf2dacfb%40continuum.io.
For more options, visit https://groups.google.com/a/continuum.io/d/optout.