我试图在龙卷风中嵌入散景服务器并使用散景身份验证功能。但是,bokeh.util.session_id.py模块下的函数check_session_id_signature调用python标准库函数hmac而不将第二个参数作为utf-8进行插入。 hmac函数要求两个参数具有相同的格式,因此,tornado会引发以下错误:
TypeError:' unicode'没有缓冲接口
要重现此问题,我运行代码并粘贴http://localhost:5006/bkapp/?bokeh-session-id= ...,其中会话ID来自生成会话ID后执行的打印。
我很清楚用户/密码验证需要在散景服务器之外完成,但这仅仅是一个概念验证。
您是否知道上述问题的任何可能解决方案?
我使用的代码如下:
from jinja2 import Environment, FileSystemLoader
import pandas as pd
import yaml
from tornado.ioloop import IOLoop
from tornado.web import RequestHandler
from bokeh.application import Application
from bokeh.application.handlers import FunctionHandler
from bokeh.embed import autoload_server
from bokeh.layouts import column
from bokeh.models import ColumnDataSource, Slider
from bokeh.plotting import figure
from bokeh.server.server import Server
from bokeh.themes import Theme
from bokeh.util.session_id import generate_session_id
env = Environment(loader=FileSystemLoader('templates'))
class IndexHandler(RequestHandler):
def get(self):
template = env.get_template('embed.html')
script = autoload_server(url="http://localhost:5006/?bokeh-session-id={}".format(id))
self.write(template.render(script=script, template="Tornado"))
def modify_doc(doc):
data_url = "http://www.neracoos.org/erddap/tabledap/B01_sbe37_all.csvp?time,temperature&depth=1&temperature_qc=0&time>=2016-02-15&time<=2017-03-22"
df = pd.read_csv(data_url, parse_dates=True, index_col=0)
df = df.rename(columns={'temperature (celsius)': 'temperature'})
df.index.name = 'time'
source = ColumnDataSource(data=df)
plot = figure(x_axis_type='datetime', y_range=(0, 25),
y_axis_label='Temperature (Celsius)',
title="Sea Surface Temperature at 43.18, -70.43")
plot.line('time', 'temperature', source=source)
def callback(attr, old, new):
if new == 0:
data = df
else:
data = df.rolling('{0}D'.format(new)).mean()
source.data = ColumnDataSource(data=data).data
slider = Slider(start=0, end=30, value=0, step=1, title="Smoothing by N Days")
slider.on_change('value', callback)
doc.add_root(column(slider, plot))
bokeh_app = Application(FunctionHandler(modify_doc))
io_loop = IOLoop.current()
id = generate_session_id('cQcDfBwdwjpsPxGIth2ynud2mQcbXLQH8LQ4251OJca4', signed=True)
print "/bkapp/?bokeh-session-id={}".format(id)
server = Server({"/bkapp": bokeh_app}, io_loop=io_loop, extra_patterns=[('/', IndexHandler)],secret_key='cQcDfBwdwjpsPxGIth2ynud2mQcbXLQH8LQ4251OJca4', sign_sessions=True,generate_session_ids=False)
server.start()
if __name__ == '__main__':
from bokeh.util.browser import view
print('Opening Tornado app with embedded Bokeh application on http://localhost:5006/')
io_loop.add_callback(server.show, "/")
io_loop.start()