I have some problems with my first dash app. What the app should do, is import data from excel or csv, display a datatable and be able to download the data. Basically it does what I want but the downloading part is bugged or slow. When I import a dataset the app displays the contents immediatelly in the datatable, but when I want to download the data it downloads a file which was uploaded before this upload. If I wait a couple of minutes it gets the new file. I checked in the folder and the file is there immediatelly when I run the app, but for some reason it downloads an old version of the file. I cut off the boring part of the script when the file is uploaded.
Any other opinion on how to download the dataframe final1 of simply the datatable would be beter?
My code:
import base64
import datetime
import io
import dash
from dash.dependencies import Input, Output, State
import dash_core_components as dcc
import dash_html_components as html
import dash_table
from flask import send_file
import pandas as pd
external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']
app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
app.layout = html.Div([
dcc.Upload(
id='upload-data',
children=html.Div([
'Drag and Drop or ',
html.A('Select Files')
]),
style={
'width': '100%',
'height': '60px',
'lineHeight': '60px',
'borderWidth': '1px',
'borderStyle': 'dashed',
'borderRadius': '5px',
'textAlign': 'center',
'margin': '10px'
},
# Allow multiple files to be uploaded
multiple=True
),
html.A("download excel", href="/download_excel/"),
html.Div(id='output-data-upload'),
])
def parse_contents(contents, filename, date):
content_type, content_string = contents.split(',')
decoded = base64.b64decode(content_string)
try:
if 'xls' in filename:
genraw = pd.read_excel(io.BytesIO(decoded))
vmes=list(genraw.columns.values)
for i in vmes:
vmes.remove(i)
namem=["csolfagus_31","FS1_15","sfc_0036","csolfagus_19","EEU75_A_0",
"DUKCT_A_0","EJV8T_A_0","EMILY_A_0","ERHBI_A_0",
"DZ447_A_0","DE576_A_0","Aag01","Aat01","Aat04",
"Aat06","Aat11","Aat15","NFF3","NFF7","NFH15",
"SF1","SFb4","NFH3","SF78","Aat02","Aat08",
"Aat09","Aat10","sfc_1143","csolfagus_05",
"csolfagus_06","csolfagus_29","concat_14_A_0"]
markerid=.......
..............
final1.to_excel("gen_raw.xlsx")
elif 'csv' in filename:
genraw = pd.read_csv(io.StringIO(decoded.decode('utf-8')))
vmes=list(genraw.columns.values)
....................
final1.to_excel("gen_raw.xlsx")
except Exception as e:
print(e)
return html.Div([
'There was an error processing this file.'
])
return html.Div([
html.H5(filename),
html.H6(datetime.datetime.fromtimestamp(date)),
dash_table.DataTable(
data=final1.to_dict('records'),
columns=[{'name': i, 'id': i} for i in final1.columns],
n_fixed_rows=1,
style_cell={'width': '150px'},
),
html.Hr(), # horizontal line
# For debugging, display the raw contents provided by the web browser
html.Div('Raw Content'),
html.Pre(contents[0:10] + '...', style={
'whiteSpace': 'pre-wrap',
'wordBreak': 'break-all'
})
])
@app.server.route("/download_excel/", methods = ["GET"])
def download_excel():
return send_file('gen_raw.xlsx')
@app.callback(Output('output-data-upload', 'children'),
[Input('upload-data', 'contents')],
[State('upload-data', 'filename'),
State('upload-data', 'last_modified')])
def update_output(list_of_contents, list_of_names, list_of_dates):
if list_of_contents is not None:
children = [
parse_contents(c, n, d) for c, n, d in
zip(list_of_contents, list_of_names, list_of_dates)]
return children
if __name__ == '__main__':
app.run_server(debug=True)