BokehJS loading unnecessarily?

``

I’m embedding a Bokeh application in a web page, using the autoload_server(…) method outlined at: http://bokeh.pydata.org/en/latest/docs/user_guide/embed.html#autoloading

After overcoming a mountain of issues, I seem to have come down to just one last obstacle. When the script returned by autoload_server(…) runs, I get repeated JavaScript console messages of the form:

    Bokeh: BokehJS not loaded, scheduling load and callback

``

followed by attempts to inject references to various bokeh .js resources of the form:

     https://127.0.0.1:443/static/js/bokeh.min.js?v=9d3af13f493d36073a89714f6a5240c6

``

     https://127.0.0.1:443/static/js/bokeh-widgets.min.js?v=1af1302b8bd7fcc88c7bcafb8771497b

``

Now, if this worked, it wouldn’t be a (big) issue, but in fact those resources are not present at the location specified on my web server, so naturally all these injections fail.

Nor do I see why it is making these attempted injections in the first place, because in fact BokehJS is available to the web page in which the script returned by autoload_server(…) is embedded, via these declarations:

<link href="https://cdn.pydata.org/bokeh/release/bokeh-0.12.4.min.css" rel="stylesheet" type="text/css">

<link href="https://cdn.pydata.org/bokeh/release/bokeh-widgets-0.12.4.min.css" rel="stylesheet" type="text/css">

<script src="https://cdn.pydata.org/bokeh/release/bokeh-0.12.4.min.js"></script>

<script src="https://cdn.pydata.org/bokeh/release/bokeh-widgets-0.12.4.min.js"></script>

``

or so I’m led to believe by the documentation at the link in the first sentence of this post.

So, why doesn’t the script returned by autoload_server(…) recognize that BokehJS is in fact installed, and skip trying to load it?

Or, if BokehJS isn’t in fact installed, despite the links and scripts I put in , why not? And how else can I preload BokehJS to avoid code injection?

Carl

Hi,

You're going to need to provide quite a bit more information, about your network setup, what arguments you are calling autoload_server with, etc. because the situation you describe does not really makes sense as described. Without more info, I can state:

* autoload_server tries to inject BokehJS from the Bokeh server that an app is located on, that is what it is expressly designed to do. This is so that the app is guaranteed to be matched up with exactly the proper version of BokehJS. Depending on your detailed network configuration, further configuration (e.g. of a reverse proxy like nginx, if you are using one) may be necessary. As I said, more information is needed.

* Wherever the CDN injections came from, they didn't come from autoload_server. autoload_server only returns a script tag, which you can template into your own HTML pages, it does not return an HTML page. In particular it does not return or create any <head> sections. It also only ever injects from a Bokeh server, as mentioned above, and never from CDN. Perhaps you are mixing autoload_server with some of the other output functions? That would not be advised. Again, more information about what exactly you have done is needed.

Thanks,

Bryan

···

On Apr 4, 2017, at 20:49, Carl Hostetter <[email protected]> wrote:

I'm embedding a Bokeh application in a web page, using the autoload_server(...) method outlined at: http://bokeh.pydata.org/en/latest/docs/user_guide/embed.html#autoloading

After overcoming a mountain of issues, I seem to have come down to just one last obstacle. When the script returned by autoload_server(...) runs, I get repeated JavaScript console messages of the form:

        Bokeh: BokehJS not loaded, scheduling load and callback

followed by attempts to inject references to various bokeh .js resources of the form:

         https://127.0.0.1:443/static/js/bokeh.min.js?v=9d3af13f493d36073a89714f6a5240c6
         https://127.0.0.1:443/static/js/bokeh-widgets.min.js?v=1af1302b8bd7fcc88c7bcafb8771497b

Now, if this worked, it wouldn't be a (big) issue, but in fact those resources are not present at the location specified on my web server, so naturally all these injections fail.

Nor do I see why it is making these attempted injections in the first place, because in fact BokehJS _is_ available to the web page in which the script returned by autoload_server(...) is embedded, via these <head> declarations:

  <link href="https://cdn.pydata.org/bokeh/release/bokeh-0.12.4.min.css&quot; rel="stylesheet" type="text/css">
  <link href="https://cdn.pydata.org/bokeh/release/bokeh-widgets-0.12.4.min.css&quot; rel="stylesheet" type="text/css">

  <script src="https://cdn.pydata.org/bokeh/release/bokeh-0.12.4.min.js&quot;&gt;&lt;/script&gt;
  <script src="https://cdn.pydata.org/bokeh/release/bokeh-widgets-0.12.4.min.js&quot;&gt;&lt;/script&gt;

or so I'm led to believe by the documentation at the link in the first sentence of this post.

So, why doesn't the script returned by autoload_server(...) recognize that BokehJS is in fact installed, and skip trying to load it?
Or, if BokehJS isn't in fact installed, despite the links and scripts I put in <head>, why not? And how else can I preload BokehJS to avoid code injection?

Carl

--
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/d7a87308-13a1-408a-9e1a-932fc0374812%40continuum.io\.
For more options, visit https://groups.google.com/a/continuum.io/d/optout\.

Thanks for the reply, Bryan. Here’s my setup:

  1. I’m running within a Docker container — in fact, the “official” miniconda Docker container provided by ContinuumIO — on which I’ve installed Nginx, bokeh, and other required tools and libraries. This container exposes ports 443 (for SSL access to my web page, in which I am trying to embed a Bokeh application) and 5100 (the Bokeh server’s port). The container’s port 443 is mapped to the host’s port 8100.

  2. Here is how I serve the Bokeh app:

bokeh serve /coronagraph/apps/coron_model.py --port 5100 --host="*" --use-xheaders &

``

  1. Here is my Nginx server config:

server

{

include /etc/nginx/include/server.conf;

include /etc/nginx/include/security.conf;

listen 443;

include /etc/nginx/include/ssl.conf;

# Exclude match of coron_model_script.html

location ~ ^\/(?!coron_model_script)(coron_model|bokeh)

{

add_header ‘Access-Control-Allow-Origin’ ‘*’;

add_header ‘Access-Control-Allow-Methods’ ‘GET’;

proxy_pass http://127.0.0.1:5100;

    include /etc/nginx/include/proxy.conf;

}

}

``

Notice that everything is handled by Nginx (including the request to retrieve coron_model_script.html which contains the script tag returned by calling autoload_server(…)), except for requests terminating in coron_model or bokeh, which are forward to the Bokeh server on port 5100.

(I can expand on the includes, but they’re just standard boilerplate that I don’t think is relevant to the issue.)

  1. Here is my autoload_server(…) call (in.a small Python script run on container launch):

script = autoload_server(model=None, app_path="/coron_model", url=“https://127.0.0.1:8101”)

``

  1. Here is an example of the script tag returned by the autoload_server(…) call:

``

So far so good, I think. I’ll describe how all this operates together in my next reply.

``

One wrinkle in all this is that I am calling:

script = autoload_server(model=None, app_path="/coron_model", url="[https://127.0.0.1:8101](https://127.0.0.1:8101)")

``

every time the Docker container launches, and saving the resulting script tag to a file (the aforementioned coron_model_script.html). I do this so that I can get a new session ID each time I launch the container, instead of always using the same session ID (which is frowned upon).

Because the script tag is not embedded in my HTML, it has to be inserted when the page loads. Which is easy enough to; but there’s an additional wrinkle: namely, that DOM-inserted script tags are not run after insertion.

To get around that, I have JavaScript that 1) reads coron_model_script.html and then 2) retrieves the actual script to run (from the src tag of the script element, e.g. src=“https://127.0.0.1:8101/coron_model/autoload.js?bokeh-autoload-element=0e2366ed-0312-4d5f-a15a-3ec98f4bf8c8” ), and then appends this script source as a child of my placeholder div.

Which works just fine, in the sense that the script then actually runs. The problem is, that this script does not recognize that the page in which it is running already has BokehJS loaded (as indeed it does, as inspection of the resources tab in the Safari developer inspector shows), and so tries to link to it locally, at https://127.0.0.1:443/static/js/…, which of course a) doesn’t exist, and b) is pointing to the host server of the Docker container, not to the Docker container’s environment nor to the Bokeh server’s environment.

Carl

P.S. In case anyone is wondering why I specify the URL of the autoload_server(…) call as https://127.0.0.1:8101 thus pointing to the host port 8100, instead of http://127.0.0.1:5100, which points directly to the Bokeh server, it’s because all links on an SSL-terminated web page have to be HTTPS, and of course the Bokeh server itself does not do SSL; so my Nginx server has to proxy the script call.

One further point, for anyone wondering: if I disable the script-tag loading on page-load, and instead embed the script tag statically in my HTML:

<script

    src="[https://127.0.0.1:8101/coron_model/autoload.js?bokeh-autoload-element=0e2366ed-0312-4d5f-a15a-3ec98f4bf8c8](https://127.0.0.1:8101/coron_model/autoload.js?bokeh-autoload-element=0e2366ed-0312-4d5f-a15a-3ec98f4bf8c8)"

    id="0e2366ed-0312-4d5f-a15a-3ec98f4bf8c8"

    data-bokeh-model-id=""

data-bokeh-doc-id=""

></script>

``

I still have exactly the same behavior: the script does not recognize that the page in which it is running already has BokehJS loaded, and so tries to link to it locally, which fails. So the issue has nothing to do with the dynamic loading of the script.

Hi,

I'd definitely like to help you with this. Just to set expectations, I came back form a vacation briefly to help with the 0.12.5 release. I will be away for the next few days. So realistically, it will be early next week before I can look in any detail.

But I'd like to reiterate that this part:

  "the script does not recognize that the page in which it is running already has BokehJS loaded"

Does not make sense to me. If you are embedding with autoload_server, BokehJS should NOT already be loaded. It is precisely the responsibility of the script itself to "autoload" BokehJS. I suspect this has something to do with the problem, and again I'd suggest it's worth figuring out what else is embedding these CDN links that should not be present.

Thanks,

Bryan

···

On Apr 5, 2017, at 12:10, Carl Hostetter <[email protected]> wrote:

One further point, for anyone wondering: if I disable the script-tag loading on page-load, and instead embed the script tag statically in my HTML:

<div id="coronModel" class="bk-root">
   <script
       src="https://127.0.0.1:8101/coron_model/autoload.js?bokeh-autoload-element=0e2366ed-0312-4d5f-a15a-3ec98f4bf8c8&quot;
       id="0e2366ed-0312-4d5f-a15a-3ec98f4bf8c8"
       data-bokeh-model-id=""
   data-bokeh-doc-id=""
   ></script>
</div>

I still have exactly the same behavior: the script does not recognize that the page in which it is running already has BokehJS loaded, and so tries to link to it locally, which fails. So the issue has nothing to do with the dynamic loading of the script.

--
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/45ed23f1-4191-4289-a8de-b626c87e5b01%40continuum.io\.
For more options, visit https://groups.google.com/a/continuum.io/d/optout\.

Much appreciated, Bryan!

Re: your comment: “If you are embedding with autoload_server, BokehJS should NOT already be loaded.”

This confuses me. When I say that BokehHS is already loaded, what I mean is (simply) that in my HTML I have the following:

<link href="https://cdn.pydata.org/bokeh/release/bokeh-0.12.4.min.css" rel="stylesheet" type="text/css">

<link href="https://cdn.pydata.org/bokeh/release/bokeh-widgets-0.12.4.min.css" rel="stylesheet" type="text/css">

<script src="https://cdn.pydata.org/bokeh/release/bokeh-0.12.4.min.js"></script>

<script src="https://cdn.pydata.org/bokeh/release/bokeh-widgets-0.12.4.min.js"></script>

``

I do this because of the instructions here which states that: “Using these components assumes that BokehJS has already been loaded, for instance either inline in the document text, or from CDN. To load BokehJS from CDN, add the following lines in your HTML text or template with the appropriate version replacing x.y.z:”

Now, perhaps embedding the script tag returned by autoload_server(…) in HTML is a completely different thing from embedding the script tag returned by components(…), but if so, that’s not at all apparent from the linked documentation.

In any event, this is what I mean when I say that BokehJS is already loaded before I execute the script linked to by the result of autoload_server(…).

If it would help for you to see the code of the Bokeh app which I’m attempting to embed, you can do so here: Coronagraph

Now, perhaps embedding the script tag returned by autoload_server(...) in HTML is a completely different thing from embedding the script tag returned by components(...), but if so, that's not at all apparent from the linked documentation.

This is in fact the case. The bokeh.embed.components and bokeh.embed.autoload_server function are independent and applicable to different use-cases, and I would say probably never (or exceedingly rarely) useful or appropriate to use together.

Can you open a GitHub issue regarding making this somehow more explicit in the docs? I think it is evident, but it's also certainly the case that my perspective is "too close" to realize otherwise. Perhaps simply a note at the top explaining that every subsection refers to an independent and stand-alone mechanism for embedding, independent of all the other sections.

Thanks,

Bryan

···

On Apr 5, 2017, at 17:41, Carl Hostetter <[email protected]> wrote:

Much appreciated, Bryan!

Re: your comment: "If you are embedding with autoload_server, BokehJS should NOT already be loaded."

This confuses me. When I say that BokehHS is already loaded, what I mean is (simply) that in my HTML <head> I have the following:

  <link href="https://cdn.pydata.org/bokeh/release/bokeh-0.12.4.min.css&quot; rel="stylesheet" type="text/css">
  <link href="https://cdn.pydata.org/bokeh/release/bokeh-widgets-0.12.4.min.css&quot; rel="stylesheet" type="text/css">

  <script src="https://cdn.pydata.org/bokeh/release/bokeh-0.12.4.min.js&quot;&gt;&lt;/script&gt;
  <script src="https://cdn.pydata.org/bokeh/release/bokeh-widgets-0.12.4.min.js&quot;&gt;&lt;/script&gt;

I do this because of the instructions here which states that: "Using these components assumes that BokehJS has already been loaded, for instance either inline in the document text, or from CDN. To load BokehJS from CDN, add the following lines in your HTML text or template with the appropriate version replacing x.y.z:"

Now, perhaps embedding the script tag returned by autoload_server(...) in HTML is a completely different thing from embedding the script tag returned by components(...), but if so, that's not at all apparent from the linked documentation.

In any event, this is what I mean when I say that BokehJS is already loaded before I execute the script linked to by the result of autoload_server(...).

If it would help for you to see the code of the Bokeh app which I'm attempting to embed, you can do so here: Coronagraph

--
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/97fc4abd-6396-49b0-aa0f-cf01c8599e7c%40continuum.io\.
For more options, visit https://groups.google.com/a/continuum.io/d/optout\.

One more data point:

If I take my HTML, put it on my Mac (i.e., outside the Docker container), disable the JavaScript that dynamically loads the autoload_server(…) script, place the generated tag statically in it, and change the URL to use HTTP (not HTTPS) and the port to 5100, everything works as expected.

It does indeed still load BokehJS, with the injections performed to “http://127.0.0.1:5100/static/js/…”; so I certainly concede that point!

The problem, then, seems to be that, for whatever reason, the script when run in my Docker + Nginx proxy setup is attempting to find/inject BokehJS at https://127.0.0.1:443, instead of https:127.0.0.1:8100 (which I could proxy as necessary) or http://127.0.0.1:5100; and as a result the request is being handled by my host computer, NOT by the Docker container.

Carl

P.S. Here is the JavaScript console output:

[Log] Bokeh: BokehJS not loaded, scheduling load and callback at – Wed Apr 05 2017 18:46:07 GMT-0400 (EDT) (autoload.js, line 34)

Wed Apr 05 2017 18:46:07 GMT-0400 (EDT)No Properties.Date Prototype

[Log] Bokeh: injecting script tag for BokehJS library: – “http://127.0.0.1:5100/static/js/bokeh.min.js?v=9d3af13f493d36073a89714f6a5240c6” (autoload.js, line 51)

[Log] Bokeh: injecting script tag for BokehJS library: – “http://127.0.0.1:5100/static/js/bokeh-widgets.min.js?v=1af1302b8bd7fcc88c7bcafb8771497b” (autoload.js, line 51)

[Log] Bokeh: all BokehJS libraries loaded (autoload.js, line 44)

[Log] Bokeh: BokehJS plotting callback run at – Wed Apr 05 2017 18:46:07 GMT-0400 (EDT) (autoload.js, line 102)

Wed Apr 05 2017 18:46:07 GMT-0400 (EDT)

[Log] [bokeh] setting log level to: ‘info’ (bokeh.min.js, line 7)

[Info] [bokeh] – "Will inject Bokeh script tag with params {“elementid”:“8217da2c-9253-4819-a57e-b9ba64d0e03f”,“sessionid”:“HDA89Z0KnSaN952E5s5Z5SJuwJVXu7prr7…” (bokeh.min.js, line 9)

“Will inject Bokeh script tag with params {“elementid”:“8217da2c-9253-4819-a57e-b9ba64d0e03f”,“sessionid”:“HDA89Z0KnSaN952E5s5Z5SJuwJVXu7prr7X4yMArSMS7”,“use_for_title”:false}”

[Log] Bokeh: injecting CSS: http://127.0.0.1:5100/static/css/bokeh.min.css?v=7246afcfffc127faef7c138bce4742e9 (autoload.js, line 82)

[Log] Bokeh: injecting CSS: http://127.0.0.1:5100/static/css/bokeh-widgets.min.css?v=d9cb9322d940f107727b091ff98d9c70 (autoload.js, line 84)

[Info] Bokeh: all callbacks have finished (autoload.js, line 21)

[Info] [bokeh] – “Websocket connection 0 is now open” (bokeh.min.js, line 1)

[Info] [bokeh] – “WidgetBox mode is fixed, but no width specified. Using default of 300.” (bokeh.min.js, line 17)

[Info] [bokeh] – “WidgetBox mode is fixed, but no width specified. Using default of 300.” (bokeh.min.js, line 17)

[Info] [bokeh] – “WidgetBox mode is fixed, but no width specified. Using default of 300.” (bokeh.min.js, line 17, x3)

[Info] [bokeh] – “WidgetBox mode is fixed, but no width specified. Using default of 300.” (bokeh.min.js, line 17)

[Info] [bokeh] – “WidgetBox mode is fixed, but no width specified. Using default of 300.” (bokeh.min.js, line 17)

[Info] [bokeh] – “WidgetBox mode is fixed, but no width specified. Using default of 300.” (bokeh.min.js, line 17, x12)

[Info] [bokeh] – “WidgetBox mode is fixed, but no width specified. Using default of 300.” (bokeh.min.js, line 17)

[Log] Bokeh items were rendered successfully (bokeh.min.js, line 30)

Hi Carl,

Ok that's good info, I'm sure there is a proper configuration and figuring it out will help inform our docs. I can dive into it more on Monday. In case it is useful in the mean time, you can also study the "real" deployment of demo.bokehplots.com (which is behind NGinx/SSL) here:

  GitHub - bokeh/demo.bokeh.org: Hosted Bokeh App Demos

Thanks,

Bryan

···

On Apr 5, 2017, at 17:53, Carl Hostetter <[email protected]> wrote:

One more data point:

If I take my HTML, put it on my Mac (i.e., outside the Docker container), disable the JavaScript that dynamically loads the autoload_server(...) script, place the generated <script> tag statically in it, and change the URL to use HTTP (not HTTPS) and the port to 5100, everything works as expected.

It does indeed still load BokehJS, with the injections performed to "http://127.0.0.1:5100/static/js/\.\.\.&quot;; so I certainly concede that point!

The problem, then, seems to be that, for whatever reason, the script when run in my Docker + Nginx proxy setup is attempting to find/inject BokehJS at https://127.0.0.1:443, instead of https:127.0.0.1:8100 (which I could proxy as necessary) or http://127.0.0.1:5100; and as a result the request is being handled by my host computer, NOT by the Docker container.

Carl

P.S. Here is the JavaScript console output:

[Log] Bokeh: BokehJS not loaded, scheduling load and callback at – Wed Apr 05 2017 18:46:07 GMT-0400 (EDT) (autoload.js, line 34)
Wed Apr 05 2017 18:46:07 GMT-0400 (EDT)No Properties.Date Prototype
[Log] Bokeh: injecting script tag for BokehJS library: – "http://127.0.0.1:5100/static/js/bokeh.min.js?v=9d3af13f493d36073a89714f6a5240c6&quot; (autoload.js, line 51)
[Log] Bokeh: injecting script tag for BokehJS library: – "http://127.0.0.1:5100/static/js/bokeh-widgets.min.js?v=1af1302b8bd7fcc88c7bcafb8771497b&quot; (autoload.js, line 51)
[Log] Bokeh: all BokehJS libraries loaded (autoload.js, line 44)
[Log] Bokeh: BokehJS plotting callback run at – Wed Apr 05 2017 18:46:07 GMT-0400 (EDT) (autoload.js, line 102)
Wed Apr 05 2017 18:46:07 GMT-0400 (EDT)
[Log] [bokeh] setting log level to: 'info' (bokeh.min.js, line 7)
[Info] [bokeh] – "Will inject Bokeh script tag with params {\"elementid\":\"8217da2c-9253-4819-a57e-b9ba64d0e03f\",\"sessionid\":\"HDA89Z0KnSaN952E5s5Z5SJuwJVXu7prr7…" (bokeh.min.js, line 9)
"Will inject Bokeh script tag with params {\"elementid\":\"8217da2c-9253-4819-a57e-b9ba64d0e03f\",\"sessionid\":\"HDA89Z0KnSaN952E5s5Z5SJuwJVXu7prr7X4yMArSMS7\",\"use_for_title\":false}"
[Log] Bokeh: injecting CSS: http://127.0.0.1:5100/static/css/bokeh.min.css?v=7246afcfffc127faef7c138bce4742e9 (autoload.js, line 82)
[Log] Bokeh: injecting CSS: http://127.0.0.1:5100/static/css/bokeh-widgets.min.css?v=d9cb9322d940f107727b091ff98d9c70 (autoload.js, line 84)
[Info] Bokeh: all callbacks have finished (autoload.js, line 21)
[Info] [bokeh] – "Websocket connection 0 is now open" (bokeh.min.js, line 1)
[Info] [bokeh] – "WidgetBox mode is fixed, but no width specified. Using default of 300." (bokeh.min.js, line 17)
[Info] [bokeh] – "WidgetBox mode is fixed, but no width specified. Using default of 300." (bokeh.min.js, line 17)
[Info] [bokeh] – "WidgetBox mode is fixed, but no width specified. Using default of 300." (bokeh.min.js, line 17, x3)
[Info] [bokeh] – "WidgetBox mode is fixed, but no width specified. Using default of 300." (bokeh.min.js, line 17)
[Info] [bokeh] – "WidgetBox mode is fixed, but no width specified. Using default of 300." (bokeh.min.js, line 17)
[Info] [bokeh] – "WidgetBox mode is fixed, but no width specified. Using default of 300." (bokeh.min.js, line 17, x12)
[Info] [bokeh] – "WidgetBox mode is fixed, but no width specified. Using default of 300." (bokeh.min.js, line 17)
[Log] Bokeh items were rendered successfully (bokeh.min.js, line 30)

--
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/cea3ed16-f858-4777-9a18-da6703cebcf9%40continuum.io\.
For more options, visit https://groups.google.com/a/continuum.io/d/optout\.

I decided to rewrite the autoload_server(…)-provided script (not the script tag, but the script the tag links to) to change all occurrences of port 443 to my port 8101 (note: in places where I’ve written 8100 before, I meant 8101).* And that definitely gets me further! Still not successful, but further along.

  • Note that this is not an ideal solution, because in addition to having to rewrite the script, it requires my HTML to “know” what port mediates it, which I’d prefer to avoid…

The BokehJS injection now succeeds, but the attempt to link to the injected .js fails, as you can see from the following JavaScript console output:

[Log] Bokeh: BokehJS not loaded, scheduling load and callback at – Wed Apr 05 2017 19:04:13 GMT-0400 (EDT) (localhost, line 34)

[Log] Bokeh: injecting script tag for BokehJS library: – “https://127.0.0.1:8101/static/js/bokeh.min.js?v=9d3af13f493d36073a89714f6a5240c6” (localhost, line 51)

[Log] Bokeh: injecting script tag for BokehJS library: – “https://127.0.0.1:8101/static/js/bokeh-widgets.min.js?v=1af1302b8bd7fcc88c7bcafb8771497b” (localhost, line 51)

[Log] Bokeh: all BokehJS libraries loaded (localhost, line 44)

[Log] Bokeh: BokehJS plotting callback run at – Wed Apr 05 2017 19:04:13 GMT-0400 (EDT) (localhost, line 102)

[Log] [bokeh] setting log level to: ‘info’ (bokeh.min.js, line 7)

[Info] [bokeh] – "Will inject Bokeh script tag with params {“elementid”:“72d48203-8f5b-4f19-bc41-a3abb01d59b0”,“sessionid”:“xT5kPtfqKrYSyjz9SZduWYmrnYpJyHRmmw…” (bokeh.min.js, line 9)

“Will inject Bokeh script tag with params {“elementid”:“72d48203-8f5b-4f19-bc41-a3abb01d59b0”,“sessionid”:“xT5kPtfqKrYSyjz9SZduWYmrnYpJyHRmmwkTdL5mu8kv”,“use_for_title”:false}”

[Log] Bokeh: injecting CSS: https://127.0.0.1:8101/static/css/bokeh.min.css?v=7246afcfffc127faef7c138bce4742e9 (localhost, line 82)

[Log] Bokeh: injecting CSS: https://127.0.0.1:8101/static/css/bokeh-widgets.min.css?v=d9cb9322d940f107727b091ff98d9c70 (localhost, line 84)

[Info] Bokeh: all callbacks have finished (localhost, line 21)

[Info] [bokeh] – “Lost websocket 0 connection, 1006 ()” (bokeh.min.js, line 1)

[Info] [bokeh] – “Websocket connection 0 disconnected, will not attempt to reconnect” (bokeh.min.js, line 1)

and from the error log:

2017/04/05 23:15:07 [error] 19#0: *25 open() “/var/www/static/css/bokeh.min.css” failed (2: No such file or directory), client: 172.18.0.1, server: , request: “GET /static/css/bokeh.min.css?v=7246afcfffc127faef7c138bce4742e9 HTTP/1.1”, host: “127.0.0.1:8101”, referrer: “https://localhost:8101/

2017/04/05 23:15:07 [error] 19#0: *26 open() “/var/www/static/css/bokeh-widgets.min.css” failed (2: No such file or directory), client: 172.18.0.1, server: , request: “GET /static/css/bokeh-widgets.min.css?v=d9cb9322d940f107727b091ff98d9c70 HTTP/1.1”, host: “127.0.0.1:8101”, referrer: “https://localhost:8101/

Sorry, that should have been “attempt to link to the injected .css” (it appears that bokeh.min.js is indeed executing).

What is the “websocket 0” connection referred to? Do I need to open another port in my Docker container?

One final post (hopefully) for this evening. I noticed one further error in my console:

[Error] WebSocket network error: OSStatus Error -9807: Invalid certificate chain

This I can explain, I think: I’m using the certificate generated specifically for the target server on which all this will eventually run, so naturally it isn’t valid for my Mac (or the Docker container). Not sure why this poses a problem only at the stage where the Bokeh app is (attempting to) run, but that’s my guess.

I’ll move all this over to the target server and give it a try sometime tomorrow, and will let you know the result.

(BTW, I apologize if all this detail is overwhelming to you or others, but my hope is that this might help someone else down the line. I certainly won’t be the last person to embed a Bokeh app in an HTTPS web page served from a Docker container!)

Carl

OK, I moved everything over to the target server, but the Bokeh app still isn’t loading properly. I’m still getting the certificate error (which leads me to think that the problem isn’t with my certificate after all), and the CSS injection is failing:

Error log:

[Error] WebSocket network error: OSStatus Error -9807: Invalid certificate chain

[Error] Failed to load resource: the server responded with a status of 404 (Not Found) (bokeh.min.css, line 0)

[Error] Failed to load resource: the server responded with a status of 404 (Not Found) (bokeh-widgets.min.css, line 0)

Console:

[Log] Bokeh: BokehJS not loaded, scheduling load and callback at – Thu Apr 06 2017 11:26:14 GMT-0400 (EDT) (emac.gsfc.nasa.gov, line 34)

[Log] Bokeh: injecting script tag for BokehJS library: – “https://127.0.0.1:8101/static/js/bokeh.min.js?v=9d3af13f493d36073a89714f6a5240c6” (emac.gsfc.nasa.gov, line 51)

[Log] Bokeh: injecting script tag for BokehJS library: – “https://127.0.0.1:8101/static/js/bokeh-widgets.min.js?v=1af1302b8bd7fcc88c7bcafb8771497b” (emac.gsfc.nasa.gov, line 51)

[Log] Bokeh: all BokehJS libraries loaded (emac.gsfc.nasa.gov, line 44)

[Log] Bokeh: BokehJS plotting callback run at – Thu Apr 06 2017 11:26:14 GMT-0400 (EDT) (emac.gsfc.nasa.gov, line 102)

[Log] [bokeh] setting log level to: ‘info’ (bokeh.min.js, line 7)

[Info] [bokeh] – "Will inject Bokeh script tag with params {“elementid”:“1e12227c-9def-492b-a28c-08997553e65b”,“sessionid”:“6PVYMTz0qfOz8uyJamUVHX3mvVBPRZ9vVR…” (bokeh.min.js, line 9)

“Will inject Bokeh script tag with params {“elementid”:“1e12227c-9def-492b-a28c-08997553e65b”,“sessionid”:“6PVYMTz0qfOz8uyJamUVHX3mvVBPRZ9vVRTUNuKqeUJO”,“use_for_title”:false}”

[Log] Bokeh: injecting CSS: https://127.0.0.1:8101/static/css/bokeh.min.css?v=7246afcfffc127faef7c138bce4742e9 (emac.gsfc.nasa.gov, line 82)

[Log] Bokeh: injecting CSS: https://127.0.0.1:8101/static/css/bokeh-widgets.min.css?v=d9cb9322d940f107727b091ff98d9c70 (emac.gsfc.nasa.gov, line 84)

[Info] Bokeh: all callbacks have finished (emac.gsfc.nasa.gov, line 21)

[Info] [bokeh] – “Lost websocket 0 connection, 1006 ()” (bokeh.min.js, line 1)

[Info] [bokeh] – “Websocket connection 0 disconnected, will not attempt to reconnect” (bokeh.min.js, line 1)

I’m happy to report some progress (not alas a full success, but definitely closer)!

In short, I’ve managed to get the Bokeh app to actually display within my web page. The chiefly required rewriting (in JavaScript) the script tag returned by autoload_server(), and the script pointed to by the src attribute of that tag, to make them “respect” (i.e., use) the host (domain + port) passed as the URL parameter of the autoload_server() call. Before this rewriting, both script and script tag instead pointed unfailingly to 127.0.0.1:443; whereas on my target server, these need to point instead of emac.gsfc.nasa.gov:8101.

The one(?) remaining issue is that the embedded Bokeh app is not interactive, apparently because the web socket connection back to the app fails:

[Error] WebSocket connection to ‘wss://emac.gsfc.nasa.gov:8101/coron_model/ws?bokeh-protocol-version=1.0&bokeh-session-id=pHXfhBiTCNHWFYIX2qg8DCCeetpBdGPX5kl5ArvcgGeb’ failed: Failed to send WebSocket frame.

send (bokeh.min.js:1:2064)

send (bokeh.min.js:1:5536)

_trigger_on_change (bokeh.min.js:9:8681)

which results in hundreds of subsequent errors of the form:

[Error] [bokeh] (3)

"Error sending message "Error: not connected so cannot send [object Object] — bokeh.min.js:1:5487send — bokeh.min.js:1:5487_trigger_on_change —

I added a rule to proxy all attempted connections to …/coron_model/ws to the Bokeh server (on port 5100), but this doesn’t seem to make any difference.

Does bokeh.min.js use some other form of websocket request that I should similarly proxy?

If I can just get the embedded app to work interactively, I can declare success!

Carl,

When you run "bokeh serve" are you setting --allow-websocket-origin and --host to be the name/URL of the public address of the page you are embedding into? (Note, you would only need --host for Bokeh 0.12.4 or earlier). By default Bokeh server is very conservative and will not allow cross-origin connections unless explicitly whitelisted using the options above.

Thanks,

Bryan

···

On Apr 7, 2017, at 17:13, Carl Hostetter <[email protected]> wrote:

I'm happy to report some progress (not alas a full success, but definitely closer)!

In short, I've managed to get the Bokeh app to actually display within my web page. The chiefly required rewriting (in JavaScript) the script tag returned by autoload_server(), and the script pointed to by the src attribute of that tag, to make them "respect" (i.e., use) the host (domain + port) passed as the URL parameter of the autoload_server() call. Before this rewriting, both script and script tag instead pointed unfailingly to 127.0.0.1:443; whereas on my target server, these need to point instead of emac.gsfc.nasa.gov:8101.

The one(?) remaining issue is that the embedded Bokeh app is not interactive, apparently because the web socket connection back to the app fails:

[Error] WebSocket connection to 'wss://emac.gsfc.nasa.gov:8101/coron_model/ws?bokeh-protocol-version=1.0&bokeh-session-id=pHXfhBiTCNHWFYIX2qg8DCCeetpBdGPX5kl5ArvcgGeb' failed: Failed to send WebSocket frame.
  send (bokeh.min.js:1:2064)
  send (bokeh.min.js:1:5536)
  _trigger_on_change (bokeh.min.js:9:8681)
       <trace truncated>

which results in hundreds of subsequent errors of the form:

[Error] [bokeh] (3)
"Error sending message "Error: not connected so cannot send [object Object] — bokeh.min.js:1:5487send — bokeh.min.js:1:5487_trigger_on_change —
    <trace truncated>

I added a rule to proxy all attempted connections to .../coron_model/ws to the Bokeh server (on port 5100), but this doesn't seem to make any difference.

Does bokeh.min.js use some other form of websocket request that I should similarly proxy?

If I can just get the embedded app to work interactively, I can declare success!

--
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/0bcb4025-7f94-4325-85f8-3d7b4efe1250%40continuum.io\.
For more options, visit https://groups.google.com/a/continuum.io/d/optout\.

I had not had --allow-websocket-origin set, but I do now (to emac.gsfc.nasa.gov:8101).

Unfortunately, I get the same behavior: the sliders and pop-up lists work in the browser, but (apparently) cannot communicate with the app:

Errors:

[Error] WebSocket connection to ‘wss://emac.gsfc.nasa.gov:8101/coron_model/ws?bokeh-protocol-version=1.0&bokeh-session-id=JbEuOy97gBYf3MR1lSHmTYCAIR1Diq2m01JGmMhlBR8t’ failed: Failed to send WebSocket frame.

send (bokeh.min.js:1:2064)

send (bokeh.min.js:1:5536)

_trigger_on_change (bokeh.min.js:9:8681)

Followed by hundreds of:

[Error] [bokeh] (3)

"Error sending message "

Error: not connected so cannot send [object Object] — bokeh.min.js:1:5487

t {header: {msgid: “0B5E25C0907040609F5F7EB06A919288”, msgtype: “PATCH-DOC”}, metadata: {}, content: Object, buffers: , send: function, …}

error

_trigger_on_change (bokeh.min.js:9:8681)

Console:

[Log] Bokeh: BokehJS not loaded, scheduling load and callback at – Mon Apr 10 2017 15:36:06 GMT-0400 (EDT) (emac.gsfc.nasa.gov, line 34)

[Log] Bokeh: injecting script tag for BokehJS library: – “https://emac.gsfc.nasa.gov:8101/static/js/bokeh.min.js?v=9d3af13f493d36073a89714f6a5240c6” (emac.gsfc.nasa.gov, line 51)

[Log] Bokeh: injecting script tag for BokehJS library: – “https://emac.gsfc.nasa.gov:8101/static/js/bokeh-widgets.min.js?v=1af1302b8bd7fcc88c7bcafb8771497b” (emac.gsfc.nasa.gov, line 51)

[Log] Bokeh: all BokehJS libraries loaded (emac.gsfc.nasa.gov, line 44)

[Log] Bokeh: BokehJS plotting callback run at – Mon Apr 10 2017 15:36:06 GMT-0400 (EDT) (emac.gsfc.nasa.gov, line 102)

[Log] [bokeh] setting log level to: ‘info’ (bokeh.min.js, line 7)

[Info] [bokeh] – "Will inject Bokeh script tag with params {“elementid”:“14f64c6a-c9a2-4a1a-b6fd-b52018f3c41d”,“sessionid”:“JbEuOy97gBYf3MR1lSHmTYCAIR1Diq2m01…” (bokeh.min.js, line 9)

“Will inject Bokeh script tag with params {“elementid”:“14f64c6a-c9a2-4a1a-b6fd-b52018f3c41d”,“sessionid”:“JbEuOy97gBYf3MR1lSHmTYCAIR1Diq2m01JGmMhlBR8t”,“use_for_title”:false}”

[Log] Bokeh: injecting CSS: https://emac.gsfc.nasa.gov:8101/static/css/bokeh.min.css?v=7246afcfffc127faef7c138bce4742e9 (emac.gsfc.nasa.gov, line 82)

[Log] Bokeh: injecting CSS: https://emac.gsfc.nasa.gov:8101/static/css/bokeh-widgets.min.css?v=d9cb9322d940f107727b091ff98d9c70 (emac.gsfc.nasa.gov, line 84)

[Info] Bokeh: all callbacks have finished (emac.gsfc.nasa.gov, line 21)

[Info] [bokeh] – “Websocket connection 0 is now open” (bokeh.min.js, line 1)

[Info] [bokeh] – “Lost websocket 0 connection, 1006 ()” (bokeh.min.js, line 1)

[Log] Bokeh items were rendered successfully (bokeh.min.js, line 30)

[Info] [bokeh] – “Websocket connection 0 disconnected, will not attempt to reconnect” (bokeh.min.js, line 1)

Is there any output from the bokeh server itself? What version of Bokeh are you using currently? Is NGinx configured to proxy/forward websockets? Looking at your original config below it seems maybe not? I can't remember if you'd already updated that though, if not docs are here:

  Bokeh server — Bokeh 3.3.2 Documentation

Thanks,

Bryan

···

On Apr 10, 2017, at 14:43, Carl Hostetter <[email protected]> wrote:

I had not had --allow-websocket-origin set, but I do now (to emac.gsfc.nasa.gov:8101).

Unfortunately, I get the same behavior: the sliders and pop-up lists work in the browser, but (apparently) cannot communicate with the app:

Errors:

[Error] WebSocket connection to 'wss://emac.gsfc.nasa.gov:8101/coron_model/ws?bokeh-protocol-version=1.0&bokeh-session-id=JbEuOy97gBYf3MR1lSHmTYCAIR1Diq2m01JGmMhlBR8t' failed: Failed to send WebSocket frame.
  send (bokeh.min.js:1:2064)
  send (bokeh.min.js:1:5536)
  _trigger_on_change (bokeh.min.js:9:8681)
       <rest of trace truncated>

Followed by hundreds of:

[Error] [bokeh] (3)
"Error sending message "
Error: not connected so cannot send [object Object] — bokeh.min.js:1:5487
t {header: {msgid: "0B5E25C0907040609F5F7EB06A919288", msgtype: "PATCH-DOC"}, metadata: {}, content: Object, buffers: , send: function, …}
  error
  _trigger_on_change (bokeh.min.js:9:8681)
       <rest of trace truncated>

Console:

[Log] Bokeh: BokehJS not loaded, scheduling load and callback at – Mon Apr 10 2017 15:36:06 GMT-0400 (EDT) (emac.gsfc.nasa.gov, line 34)
[Log] Bokeh: injecting script tag for BokehJS library: – "https://emac.gsfc.nasa.gov:8101/static/js/bokeh.min.js?v=9d3af13f493d36073a89714f6a5240c6&quot; (emac.gsfc.nasa.gov, line 51)
[Log] Bokeh: injecting script tag for BokehJS library: – "https://emac.gsfc.nasa.gov:8101/static/js/bokeh-widgets.min.js?v=1af1302b8bd7fcc88c7bcafb8771497b&quot; (emac.gsfc.nasa.gov, line 51)
[Log] Bokeh: all BokehJS libraries loaded (emac.gsfc.nasa.gov, line 44)
[Log] Bokeh: BokehJS plotting callback run at – Mon Apr 10 2017 15:36:06 GMT-0400 (EDT) (emac.gsfc.nasa.gov, line 102)
[Log] [bokeh] setting log level to: 'info' (bokeh.min.js, line 7)
[Info] [bokeh] – "Will inject Bokeh script tag with params {\"elementid\":\"14f64c6a-c9a2-4a1a-b6fd-b52018f3c41d\",\"sessionid\":\"JbEuOy97gBYf3MR1lSHmTYCAIR1Diq2m01…" (bokeh.min.js, line 9)
"Will inject Bokeh script tag with params {\"elementid\":\"14f64c6a-c9a2-4a1a-b6fd-b52018f3c41d\",\"sessionid\":\"JbEuOy97gBYf3MR1lSHmTYCAIR1Diq2m01JGmMhlBR8t\",\"use_for_title\":false}"
[Log] Bokeh: injecting CSS: https://emac.gsfc.nasa.gov:8101/static/css/bokeh.min.css?v=7246afcfffc127faef7c138bce4742e9 (emac.gsfc.nasa.gov, line 82)
[Log] Bokeh: injecting CSS: https://emac.gsfc.nasa.gov:8101/static/css/bokeh-widgets.min.css?v=d9cb9322d940f107727b091ff98d9c70 (emac.gsfc.nasa.gov, line 84)
[Info] Bokeh: all callbacks have finished (emac.gsfc.nasa.gov, line 21)
[Info] [bokeh] – "Websocket connection 0 is now open" (bokeh.min.js, line 1)
[Info] [bokeh] – "Lost websocket 0 connection, 1006 ()" (bokeh.min.js, line 1)
[Log] Bokeh items were rendered successfully (bokeh.min.js, line 30)
[Info] [bokeh] – "Websocket connection 0 disconnected, will not attempt to reconnect" (bokeh.min.js, line 1)

--
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/d7287a9b-e523-468d-b622-ec4d6644c4ab%40continuum.io\.
For more options, visit https://groups.google.com/a/continuum.io/d/optout\.

I’m using bokeh 0.12.4 (0.12.5 broke the app I’m trying to import, which uses a deprecated class, I forget which, that was removed in 0.12.5).

Yes, I’ve configured Nginx to proxy web socket calls. Here is my complete config:

server

{

root /var/www;

index index.html;

add_header X-Frame-Options "SAMEORIGIN";

add_header Strict-Transport-Security max-age=31536000;

add_header X-Content-Type-Options nosniff;

server_tokens off;

listen 443;

<ssl config redacted>

location ~ ^\/(coron_model\/ws|static\/js\/bokeh|coron_model|bokeh)

{

	add_header 'Access-Control-Allow-Origin' '*';

	add_header 'Access-Control-Allow-Methods' 'GET';

	proxy_pass http://127.0.0.1:5100;

	proxy_set_header X-Real-IP $remote_addr;

	proxy_set_header X-Forwarded-Proto $scheme;

	proxy_set_header Host $host:$server_port;

	proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

	proxy_buffering off;

	# WebSocket support (nginx 1.4)

	proxy_http_version 1.1;

	proxy_set_header Upgrade $http_upgrade;

	proxy_set_header Connection "upgrade";
}

}

The only other messages logged are:

2017-04-10 19:36:03,888 /coronagraph/apps/coron_model.py: call to show() ignored when running scripts with the ‘bokeh’ command.

2017-04-10 19:36:03,967 200 GET /coron_model/autoload.js?bokeh-autoload-element=14f64c6a-c9a2-4a1a-b6fd-b52018f3c41d (128.154.224.24) 1488.75ms

2017-04-10 19:36:04,302 WebSocket connection opened

2017-04-10 19:36:04,302 ServerConnection created

2017-04-10 19:36:05,480 WebSocket connection closed: code=None, reason=None