My issue is similar to the following two issues that I found, but not quite the same, in that I’m not serving a standalone app or embedding in Django. Rather, I’m trying to serve a Tornado app with an embedded inline Bokeh server. (The bokeh code and some of the other code need to share resources
bokeh-serve-error-404-for-js-ressources/5708
serving-bokeh-apps-embedded-in-django-from-subpath/8359
I was able to build and test the app on my computer, but I am now trying to host it as a web app, and it looks like it’s pulling the static resources from the wrong place. It’s probably a configuration issue. Here is a minimal example using one of the stock Bokeh examples in the gallery. It works just fine when I run locally in the command line and browse to localhost:8888
but not when I try to host it. (tearlant.com is my domain so this is what I see when I try to host there)
My main.py
import os
import nest_asyncio
import tornado.httpserver
import tornado.ioloop
import tornado.websocket
import tornado.web
import tornado.options
import numpy as np
from bokeh.client import pull_session
from bokeh.embed import server_session
from bokeh.plotting import figure
from bokeh.server.server import Server
def bokeh_app(doc):
N = 4000
x = np.random.random(size=N) * 100
y = np.random.random(size=N) * 100
radii = np.random.random(size=N) * 1.5
colors = np.array([[r, g, 150] for r, g in zip(50 + 2 * x, 30 + 2 * y)], dtype="uint8")
TOOLS = "hover,crosshair,pan,wheel_zoom,zoom_in,zoom_out,box_zoom,undo,redo,reset,tap,save,box_select,poly_select,lasso_select,examine,help"
p = figure(tools=TOOLS)
p.scatter(x, y, radius=radii,
fill_color=colors, fill_alpha=0.6,
line_color=None)
doc.add_root(p)
# Tornado handlers
class BaseHandler(tornado.web.RequestHandler):
def data_received(self, chunk):
pass
def get(self):
ioloop = tornado.ioloop.IOLoop.current()
with pull_session(url="https://www.tearlant.com/ts-bokeh/bokeh_app", io_loop=ioloop) as mysession:
script = server_session(session_id=mysession.id, url="https://www.tearlant.com/ts-bokeh/bokeh_app")
self.render("bokeh_app.html", scr=script, username='', api_call_successful=False, api_call_data=None, distance=None, airport_code=None)
class TornadoApplication(tornado.web.Application):
def __init__(self):
handlers = [
(r"/", BaseHandler)
]
settings = dict(
template_path=os.path.join(os.path.dirname(__file__), "templates"),
static_path=os.path.join(os.path.dirname(__file__), "static"),
#xsrf_cookies=True,
#cookie_secret="YOUR SECRET HERE",
debug=True
)
super().__init__(handlers, **settings)
if __name__ == '__main__':
nest_asyncio.apply()
tornado.options.define("port", default=8888, help="run on the given port", type=int)
http_server = tornado.httpserver.HTTPServer(TornadoApplication())
http_server.listen(tornado.options.options.port)
io_loop = tornado.ioloop.IOLoop.current()
bokeh_server = Server({'/bokeh_app': bokeh_app},
io_loop=io_loop,
allow_websocket_origin=['localhost:8888'],
check_unused_sessions_milliseconds=1000,
unused_lifetime_milliseconds=1000
)
print("App initialized.")
io_loop.start()
The template file (I just changed the background colour so that I can confirm it’s being served to the browser, even if the bokeh app is not properly embedded)
bokeh_app.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Prototype</title>
<style>
body {background-color: powderblue;}
</style>
</head>
<body>
<div class="columns">
<div class="column">
{% raw scr %}
</div>
</div>
</body>
</html>
And the following is added to my nginx configuration file.
location /troubleshooting-bokeh/ {
rewrite ^/troubleshooting-bokeh(/.*)$ $1 break;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_pass http://localhost:8888;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
location /ts-bokeh/ {
rewrite ^/ts-bokeh(/.*)$ $1 break;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_pass http://localhost:5006;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
I would expect the app to be served at www.tearlant.com/troubleshooting-bokeh, and I can tell the nginx configuration is correct, because I changed the background colour of the HTML file. I’m essentially seeing an empty blue page with a blue background, with the above messages in the console.
This is probably a configuration issue. When running locally, if I replace the URL root in pull_session
and server_session
with localhost:5006
, it renders just fine.