Я добавляю некоторые подробности в ответ @ bigreddot.
Код тоже не работает для меня. Я даже нашел именно этот код в каком-то учебном пособии, и основная проблема заключалась в том, что он использовал nginx
, который преобразовывал /bokeh
в http://127.0.0.1/bokeh
. Но на локальном компьютере без nginx
я должен изменить все URL.
РЕДАКТИРОВАТЬ: Я нашел учебник с этим кодом https://rbtechblog.com/blog/deploy_bokeh_app
Я начинаю изменять код и сокращать его, чтобы создать минимальный код, который работает. Я внес изменения, аналогичные изменениям, упомянутым bigreddot.
Bokeh
Я поместил код непосредственно в файл без def
и без Server
filename.py
from numpy.random import random
from bokeh.io import curdoc
from bokeh.plotting import figure
from bokeh.layouts import column, widgetbox
from bokeh.models import Button, ColumnDataSource
def click(n=100):
source.data = {'x': range(n), 'y': random(n)}
fig = figure(title='random data', width=800, height=400, tools='pan,box_zoom,reset,save')
source = ColumnDataSource(data={'x': [], 'y': []}) # place for data
fig.line('x', 'y', source=source) # draw plot
button = Button(label='update', button_type='success') # create button
button.on_click(click) # assign function to button
layout = column(fig, widgetbox(button)) # create layout
curdoc().add_root(layout) # add all to document
click() # generate random data at start
Теперь я могу запустить его в консоли
bokeh serve filename.py
, и я могу видеть его в веб-браузере, используя url
http://localhost:5006/filename
(bokeh
должен отображать этот URL в консоли после запуска - если вы будете использовать другой файл или опции, вы можете увидеть другой URL)
В данный момент мне не нужны никакие другие опции, но позже мне понадобятся --allow-websocket-origin
, но я опишу это позже.
Кстати: Я не использую имя bokeh.py , потому что это может создать проблемы при импорте оригинала bokeh
.
Flask
Поскольку я не использую nginx
, который может конвертировать /bokeh
в http://localhost:5006/filename
, поэтому я должен использовать полный URL в serve_document
Для теста я использовал render_template_string
вместо render_template
, поэтому мне не нужно создавать templates/index.html
, чтобы было проще копировать и тестировать код.
Я удалил try/except
, чтобы получить больше Detai ls, если будет ошибка.
app.py
from flask import Flask, render_template, render_template_string
from bokeh.embed import server_document
app = Flask(__name__)
@app.route("/")
def index():
tag = server_document(url='http://localhost:5006/filename')
#return render_template('index.html', tag=tag)
return render_template_string('''<div>{{ tag|safe }}</div>''', tag=tag)
if __name__ == '__main__':
app.run(debug=True)
Теперь я могу запустить его
python app.py
и открыть страницу в веб-браузере, используя стандартный URL-адрес
http://localhost:5000/
, но я не вижу графика, и bokeh
отобразит
Refusing websocket connection from Origin 'http://127.0.0.1:5000';
use --allow-websocket-origin=127.0.0.1:5000
or set BOKEH_ALLOW_WS_ORIGIN=127.0.0.1:5000 to permit this;
currently we allow origins {'localhost:5006'}
, поэтому мне нужно перезапустить bokeh
с этой опцией
bokeh serve filename.py --allow-websocket-origin=127.0.0.1:5000
(как упомянул bigreddot, оно должно быть 127.0.0.1
, а не localhost
)
И теперь flask
должен отображать график.
Кстати: если я использую шаблон без тега HTML
render_template_string('''{{ tag|safe }}''', tag=tag)
, то браузер может обрабатывать весь код (<script ...></scrip>
) как часть <head></head>
и не будет отображать его, потому что браузер никогда не отображает элементы, которые находятся в <head></head>
, даже если есть правильные изображения или графики.