- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在参数化我的 Bokeh 应用程序,方法是让我的 Flask 应用程序通过专用于对通过查询字符串参数传递的请求数据进行 json 化的路由公开模型数据。我知道数据发送路由有效,因为当我将其用作 AjaxDataSource 的 url 时,我得到了绘制的预期数据。然而,当我尝试使用 requests.get api 进行等效操作时,我得到了 503 响应代码,这让我觉得我违反了一些基本的东西,但凭借我有限的 webdev 经验,我无法完全理解。我做错了什么或违反了什么?
实际上,我需要比 AjaxDataSource
提供的列限制更多的数据检索灵 active 。我希望依靠 requests
模块来传递任意类实例以及通过序列化和反序列化 Json 来传递的内容。
这是我展示来自 flask_embed.html 的失败的最小示例。 ...
import requests
from flask import Flask, jsonify, render_template
import pandas
from tornado.ioloop import IOLoop
from bokeh.application import Application
from bokeh.application.handlers import FunctionHandler
from bokeh.embed import server_document
from bokeh.layouts import column
from bokeh.models import AjaxDataSource,ColumnDataSource
from bokeh.plotting import figure
from bokeh.server.server import Server
flask_app = Flask(__name__)
# Populate some model maintained by the flask application
modelDf = pandas.DataFrame()
nData = 100
modelDf[ 'c1_x' ] = range(nData)
modelDf[ 'c1_y' ] = [ x*x for x in range(nData) ]
modelDf[ 'c2_x' ] = range(nData)
modelDf[ 'c2_y' ] = [ 2*x for x in range(nData) ]
def modify_doc1(doc):
# get colum name from query string
args = doc.session_context.request.arguments
paramName = str( args['colName'][0].decode('utf-8') )
# get model data from Flask
url = "http://localhost:8080/sendModelData/%s" % paramName
source = AjaxDataSource( data = dict( x=[] , y=[] ) ,
data_url = url ,
polling_interval = 5000 ,
mode = 'replace' ,
method = 'GET' )
# plot the model data
plot = figure( )
plot.circle( 'x' , 'y' , source=source , size=2 )
doc.add_root(column(plot))
def modify_doc2(doc):
# get column name from query string
args = doc.session_context.request.arguments
colName = str( args['colName'][0].decode('utf-8') )
# get model data from Flask
url = "http://localhost:8080/sendModelData/%s" % colName
#pdb.set_trace()
res = requests.get( url , timeout=None , verify=False )
print( "CODE %s" % res.status_code )
print( "ENCODING %s" % res.encoding )
print( "TEXT %s" % res.text )
data = res.json()
# plot the model data
plot = figure()
plot.circle( 'x' , 'y' , source=data , size=2 )
doc.add_root(column(plot))
bokeh_app1 = Application(FunctionHandler(modify_doc1))
bokeh_app2 = Application(FunctionHandler(modify_doc2))
io_loop = IOLoop.current()
server = Server({'/bkapp1': bokeh_app1 , '/bkapp2' : bokeh_app2 }, io_loop=io_loop, allow_websocket_origin=["localhost:8080"])
server.start()
@flask_app.route('/', methods=['GET'] )
def index():
res = "<table>"
res += "<tr><td><a href=\"http://localhost:8080/app1/c1\">APP1 C1</a></td></tr>"
res += "<tr><td><a href=\"http://localhost:8080/app1/c2\">APP1 C2</a></td></tr>"
res += "<tr><td><a href=\"http://localhost:8080/app2/c1\">APP2 C1</a></td></tr>"
res += "<tr><td><a href=\"http://localhost:8080/app2/c2\">APP2 C2</a></td></tr>"
res += "<tr><td><a href=\"http://localhost:8080/sendModelData/c1\">DATA C1</a></td></tr>"
res += "<tr><td><a href=\"http://localhost:8080/sendModelData/c2\">DATA C2</a></td></tr>"
res += "</table>"
return res
@flask_app.route( '/app1/<colName>' , methods=['GET'] )
def bkapp1_page( colName ) :
script = server_document( url='http://localhost:5006/bkapp1' , arguments={'colName' : colName } )
return render_template("embed.html", script=script)
@flask_app.route( '/app2/<colName>' , methods=['GET'] )
def bkapp2_page( colName ) :
script = server_document( url='http://localhost:5006/bkapp2', arguments={'colName' : colName } )
return render_template("embed.html", script=script)
@flask_app.route('/sendModelData/<colName>' , methods=['GET'] )
def sendModelData( colName ) :
x = modelDf[ colName + "_x" ].tolist()
y = modelDf[ colName + "_y" ].tolist()
return jsonify( x=x , y=y )
if __name__ == '__main__':
from tornado.httpserver import HTTPServer
from tornado.wsgi import WSGIContainer
from bokeh.util.browser import view
print('Opening Flask app with embedded Bokeh application on http://localhost:8080/')
# This uses Tornado to server the WSGI app that flask provides. Presumably the IOLoop
# could also be started in a thread, and Flask could server its own app directly
http_server = HTTPServer(WSGIContainer(flask_app))
http_server.listen(8080)
io_loop.add_callback(view, "http://localhost:8080/")
io_loop.start()
这是一些调试输出...
C:\TestApp>python flask_embedJSONRoute.py
Opening Flask app with embedded Bokeh application on http://localhost:8080/
> C:\TestApp\flask_embedjsonroute.py(52)modify_doc2()
-> res = requests.get( url , timeout=None , verify=False )
(Pdb) n
> C:\TestApp\flask_embedjsonroute.py(53)modify_doc2()
-> print( "CODE %s" % res.status_code )
(Pdb) n
CODE 503
> C:\TestApp\flask_embedjsonroute.py(54)modify_doc2()
-> print( "ENCODING %s" % res.encoding )
(Pdb) n
ENCODING utf-8
> C:\TestApp\flask_embedjsonroute.py(55)modify_doc2()
-> print( "TEXT %s" % res.text )
(Pdb) n
TEXT
> C:\TestApp\flask_embedjsonroute.py(56)modify_doc2()
-> data = res.json()
(Pdb)
File "C:\Anaconda3\lib\json\decoder.py", line 357, in raw_decode
raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
最佳答案
这似乎不是 Bokeh 本身的问题,而是运行 Flask 应用程序的服务器中的线程和阻塞问题。
除了 Bokeh 之外,它完全可以重现......
import requests
from flask import Flask, jsonify, request
import pandas
import pdb
flask_app = Flask(__name__)
# Populate some model maintained by the flask application
modelDf = pandas.DataFrame()
nData = 100
modelDf[ 'c1_x' ] = range(nData)
modelDf[ 'c1_y' ] = [ x*x for x in range(nData) ]
modelDf[ 'c2_x' ] = range(nData)
modelDf[ 'c2_y' ] = [ 2*x for x in range(nData) ]
@flask_app.route('/', methods=['GET'] )
def index():
res = "<table>"
res += "<tr><td><a href=\"http://localhost:8080/sendModelData/c1\">SEND C1</a></td></tr>"
res += "<tr><td><a href=\"http://localhost:8080/sendModelData/c2\">SEND C2</a></td></tr>"
res += "<tr><td><a href=\"http://localhost:8080/RequestsOverFlaskNoProxy?colName=c1\">REQUEST OVER FLASK NO PROXY C1</a></td></tr>"
res += "<tr><td><a href=\"http://localhost:8080/RequestsOverFlaskNoProxy?colName=c2\">REQUEST OVER FLASK NO PROXY C2</a></td></tr>"
res += "<tr><td><a href=\"http://localhost:8080/RequestsOverFlask?colName=c1\">REQUEST OVER FLASK C1</a></td></tr>"
res += "<tr><td><a href=\"http://localhost:8080/RequestsOverFlask?colName=c2\">REQUEST OVER FLASK C2</a></td></tr>"
res += "</table>"
return res
@flask_app.route('/RequestsOverFlaskNoProxy')
def requestsOverFlaskNoProxy() :
print("RequestsOverFlaskNoProxy")
# get column name from query string
colName = request.args.get('colName')
# get model data from Flask
url = "http://localhost:8080/sendModelData/%s" % colName
print("Get data from %s" % url )
session = requests.Session()
session.trust_env = False
res = session.get( url , timeout=5000 , verify=False )
print( "CODE %s" % res.status_code )
print( "ENCODING %s" % res.encoding )
print( "TEXT %s" % res.text )
data = res.json()
return data
@flask_app.route('/RequestsOverFlask')
def requestsOverFlask() :
# get column name from query string
colName = request.args.get('colName')
# get model data from Flask
url = "http://localhost:8080/sendModelData/%s" % colName
res = requests.get( url , timeout=None , verify=False )
print( "CODE %s" % res.status_code )
print( "ENCODING %s" % res.encoding )
print( "TEXT %s" % res.text )
data = res.json()
return data
@flask_app.route('/sendModelData/<colName>' , methods=['GET'] )
def sendModelData( colName ) :
x = modelDf[ colName + "_x" ].tolist()
y = modelDf[ colName + "_y" ].tolist()
return jsonify( x=x , y=y )
if __name__ == '__main__':
print('Opening Flask app on http://localhost:8080/')
# THIS DOES NOT WORK
#flask_app.run( host='0.0.0.0' , port=8080 , debug=True )
# THIS WORKS
flask_app.run( host='0.0.0.0' , port=8080 , debug=True , threaded=True )
从屏幕截图中可以看出,直接从 sendModelData
提供数据会适本地呈现 JSon,但是当通过 requests.get
方法获取时,会由于以下原因而产生异常: Python 控制台中报告的 503 代码。
如果我做同样的尝试试图消除 proxies 的影响我已经通过环境变量启用了它,但这种方法永远不会完成,并且请求使浏览器无限期地旋转。
想一想,甚至可能完全没有必要使用 requests 作为中间人,我应该能够获取 json 字符串并自己进行反序列化。好吧,这在我的实际代码中是可行的,Bokeh 渲染是在与 Flask 应用程序完全不同的 python 模块中完成的,因此这些功能甚至不可用,除非我打乱应用程序的分层。
编辑事实证明我违反的根本是 Flask 的开发环境......
You are running your WSGI app with the Flask test server, which by default uses a single thread to handle requests. So when your one request thread tries to call back into the same server, it is still busy trying to handle that one request. https://stackoverflow.com/a/22878916/1330381
那么问题就变成了如何在原始 Bokeh 示例中应用这种 threaded=True 技术?由于flask_embed.py示例依赖于Tornado WSGI服务器,这可能是不可能的,从这个question表明 Tornado 在设计上是单线程的。鉴于上述发现,一个更尖锐的问题是,AjaxDataSource
如何一起避免 requests
模块面临的这些线程问题?
更新有关 Bokeh 和 Tornado 耦合的更多背景信息...
53:05 so they're actually are not very many, the question is about the dependencies for Bokeh and the Bokeh server. The new Bokeh server is built on tornado and that's pretty much the main dependency is it uses tornado. Beyond that there's not very many dependencies, runtime dependencies, for Bokeh. pandas is an optional dependency for Bokeh.charts. There's other dependencies, you know numpy is used. But there's only, the list of dependencies I think is six or seven. We've tried to pare it down greatly over the years and so, but the main dependency of the server is tornado. Intro to Data Visualization with Bokeh - Part 1 - Strata Hadoop San Jose 2016
关于python - Flask 中的代码 503 与嵌入式 Bokeh 服务器应用程序通过 requests.get() 获取 json 化数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44401185/
我用 bokeh.plotting.Figure.line 画了下面的图。我如何添加垂直引用线来强调 Feb/14 的一个点? 这是另一个情节。这是 bokeh.charts.Bar。我想添加水平指南
我使用 python 在 Bokeh 中创建了一个散点图。我想创建一个小部件,允许用户更改散点图中点的颜色。有没有简单的方法可以做到这一点?我找到了一个基于 JQuery 的颜色选择器小部件 ( ht
我有一个 bokeh 应用程序,我可以在其中读取各种文件(6 到 12 个)并生成 DataTable 来比较几个不同的变量。 所以我有一个生成 DataTable 的循环,将它们添加到列表中,然后最
典型的 Bokeh 散点图可能如下所示: 其中 x 和 y 限制均为 [0,1]。如何删除轴上 0 之前并延伸到 1 之外的额外空间?这样最终图的左角为坐标 (0,0),左上角和右下角分别为 (0,1
我正在尝试创建一个 Bokeh 图,它允许我通过单击复选框来切换图中线条的可见性。 我开始尝试对复选框组使用 js 回调,但不幸的是,实际上并没有为复选框组实现 js 回调。 任何人都可以提出另一种方
例如,我有 button = Button(label="0", type="success") 选择此按钮后,我想将标签更改为“1”,反之亦然。有没有简单的方法来实现这一目标? 编辑: RadioB
我团队中的一些人,包括我自己,发现在 Bokeh 散点图中使用 circle 非常令人迷惑。方法,对于图中数据的初始自动缩放拟合,我们可以为我们的数据拨入合理的大小,例如使用 plot.circle(
所以我想做的是一个带有线条和圆圈的简单图形 http://docs.bokeh.org/en/latest/docs/quickstart.html#getting-started 但带有在鼠标悬停在
考虑一个垂直堆积条形图,其中每一列都由多个条形(段)组成。是否可以在每个段上添加工具提示?目前,相同的工具提示附加到组成该列的所有段。 from bokeh.core.properties impor
In[21]: from bokeh.charts import Bar, output_file, show In[22]: dict = {'sec': {u'A': 10, u'B': 20}}
在 Bokeh 中实现树形图需要什么?类似于这个 DS 示例的东西会很好—— http://bl.ocks.org/robschmuecker/7880033 我只是想可视化一个数据结构,所以只需要平
我了解如何指定在 Bokeh 中显示的特定刻度,但我的问题是是否有一种方法可以分配特定的标签来显示与位置。例如 plot.xaxis[0].ticker=FixedTicker(ticks=[0,1]
有什么方法可以为图例添加标题,例如左侧为当前图例,右侧为带有标题的图例。这个特殊的图例被放置在情节之外,所以我不知道是否可以用文本字形来伪造它。 最佳答案 从最新版本的 Bokeh (1.2) 开始,
问题:我的 python 应用程序启动了一个 Bokeh 服务器,如本文所述: http://matthewrocklin.com/blog/work/2017/06/28/simple-bokeh-
我正在使用 Bokeh 图制作折线图,我想标记实际的点(用线穿过它们),而不是仅仅标记线本身。我怎样才能做到这一点?我浏览了文档和用户指南,但似乎找不到答案。谢谢! 最佳答案 假设您正在使用 boke
我将一个 Bokeh Figure 实例作为输入传递给另一个函数,我需要在那里修改它的源代码。 不知道该怎么做! 这就是我创建图形实例的方式: source = ColumnDataSource({'
据我所知,我可以通过设置 responsive=True 来使 Bokeh 图响应 div 的宽度。然而,我感兴趣的是让 Bokeh 图只在一定程度上做出响应。有没有一种方法可以让我设置 Bokeh
我有一个 Bokeh 服务器应用程序。我想在命令行上传递自定义选项: bokeh serve /path/to/script.py --my-option foo 这可能吗? Bokeh 会以某种方式
我有一个图,它使用来自一些原始数据的值(在 0-20 的 x/y 范围内),以及一些导致一些相当大的 x/y 值(例如 -1000 到 1000+)的最小化数据。因此,我所做的绘图需要我手动单击缩放以
在Web应用程序中,我想让用户使用bokeh的漂亮的框/套索选择工具来选择绘制图像中的感兴趣区域。我想接收选定的像素,以便在python中进行进一步的操作。 对于散点图,这类似于gallery,很容易
我是一名优秀的程序员,十分优秀!