首页 > 解决方案 > Python Bokeh - 上传 zip 文件并更新数据源

问题描述

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

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

上传/读取 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)

标签: pythonfile-uploadbokehzipfile

解决方案


为了让您的 zip-extract Python 代码与 Bokeh 回调一起使用,您必须使用bokeh serveandcurdoc().add_root而不是show.

一些让你开始的例子。请注意,我不会Button在这里开始上传过程,因为当您选择一个文件时,它会立即自动上传,因为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,那么您必须找到一些适用于浏览器的用于 zip 档案提取的 JavaScript 库,将其附加到您的页面(可能通过可以传递给的自定义 Bokeh 模板save-show不现在不支持),并在传递给CustomJS.


推荐阅读