Python Bokeh - 上传 zip 文件并更新数据源

Python Bokeh - upload a zip file and update the data source

我想使用 Bokeh FileInput 和一个按钮来上传 zip 文件,从 cvs 中提取数据并更新数据源。我有用于从本地目录上传 zip 文件、提取和读取 csv 文件的代码;但我正在努力使用 Bokeh 创建回调以获得与使用以下代码获得的结果相同的结果。

拜托,欢迎任何帮助。我不知道如何解决这个问题。谢谢!

upload/read zip 文件的代码(有效):

import zipfile
import os
import pandas as pd
import glob

file_name = 'somefile.zip'
path = os.path.abspath(os.getcwd())

def upload():   
    with zipfile.ZipFile(file_name, 'r') as file:
        file.extractall(path = path)
        file.close()
if __name__ == '__main__': upload()

path = os.path.abspath(os.getcwd())+'/' + file_name[:-4] + '/*.csv'
for fname in glob.glob(path):
   df=pd.read_csv(fname, encoding='latin1', sep='\t')

散景实现(回调待定义):

from bokeh.io import curdoc, output_file, show
from bokeh.models import CustomJS, ColumnDataSource, Div, Button, FileInput
from bokeh.layouts import layout, widgetbox

callbackUpload = CustomJS(args=dict(source=source), code="""
    ???

    }
    source.change.emit();
""")
#Div: heading
h_input = Div(text="""<h2>Upload your zip file</h2> """, max_height=40)

#File input
file_input = FileInput()

#Button: upload a new zip achive
button = Button(label="Upload", button_type="danger")
button.js_on_event(events.ButtonClick, callbackUpload)

source = ColumnDataSource(df)

layout = widgetbox(h_input, file_input, button)
show(layout)

要使您的压缩 Python 代码与 Bokeh 回调一起使用,您必须使用 bokeh servecurdoc().add_root 而不是 show

一些帮助您入门的示例。请注意,我在这里不使用 Button 来开始上传过程,因为当您 select 一个文件时,它会立即自动上传,因为 FileInput.value 属性 已更改.

import zipfile
from base64 import b64decode
from io import BytesIO

from bokeh.io import show
from bokeh.layouts import column
from bokeh.models import ColumnDataSource, Div, FileInput

h_input = Div(text="""<h2>Upload your zip file</h2> """, max_height=40)

file_input = FileInput()
source = ColumnDataSource(dict())


def value_changed(attr, old, new):
    data = b64decode(new)
    with zipfile.ZipFile(BytesIO(data)) as zf:
        # No need to call `zf.close()` - the `with` block does that for you.
        ...


file_input.on_change('value', value_changed)

show(column(h_input, file_input))

如果您想坚持使用 CustomJS 并不惜一切代价避免使用 bokeh serve,那么您必须找到一些 JavaScript 可以在浏览器中提取 zip 存档的库,附上它到您的页面(可能通过可以传递给 save 的自定义 Bokeh 模板 - show 现在不支持它),并在传递给 CustomJS 的 JS 代码中使用它.