Python Боке - загрузить zip-файл и обновить источник данных - PullRequest
0 голосов
/ 26 мая 2020

Я хочу использовать 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)

1 Ответ

1 голос
/ 27 мая 2020

Чтобы ваш zip-извлекающий код Python работал с обратными вызовами Bokeh, вам нужно будет использовать bokeh serve и curdoc().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 любой ценой, тогда вам нужно найти некоторую JavaScript библиотеку для извлечения zip-архивов, которая работает в браузерах, прикрепить ее к своей странице (возможно, с помощью специального шаблона Bokeh, который может быть передан в save - show прямо сейчас не поддерживает) и использовать его в коде JS, переданном в CustomJS.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...