User upload data, manipulate and download data

Hi,

I have made reference to several threads, including the code to upload a csv as well as downloading the data. I have a similar need. I want my user to upload a csv data and in turn return a csv based on some function’s manipulation. I have combined both the solutions from various threads but i cannot seem to make it work.

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_experiments as dt

import pandas as pd
import numpy as np
import urllib

external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']

app = dash.Dash(__name__, external_stylesheets=external_stylesheets)

app.scripts.config.serve_locally = True

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.Div(id='output-data-upload'),
html.A(
    'Download Data',
    id='download-link',
    download="rawdata.csv",
    href="",
    target="_blank"
)
])


def parse_contents(contents, filename, date):
content_type, content_string = contents.split(',')

decoded = base64.b64decode(content_string)
try:
    if 'csv' in filename:
        # Assume that the user uploaded a CSV file
        df = pd.read_csv(
            io.StringIO(decoded.decode('utf-8')))
    elif 'xls' in filename:
        # Assume that the user uploaded an excel file
        df = pd.read_excel(io.BytesIO(decoded))
except Exception as e:
    print(e)
    return html.Div([
        'There was an error processing this file.'
    ])

return df


@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[0]





def some_function(df):
df['d'] = np.nan
return df






@app.callback(
dash.dependencies.Output('download-link', 'href'),
[dash.dependencies.Input('output-data-upload', 'children')])
def update_download_link(df):
dff = some_function(df)
csv_string = dff.to_csv(index=False, encoding='utf-8')
csv_string = "data:text/csv;charset=utf-8," + urllib.quote(csv_string)
return csv_string







if __name__ == '__main__':
app.run_server()

my downloaded file is:

It will be good if someone can correct the mistakes

regards
germ

If you are using Python 3, use

from urllib.parse import quote

and

csv_string = "data:text/csv;charset=utf-8," + quote(csv_string)

Also this callback :point_down: looks similar to what was used to create image in https://dash.plot.ly/dash-core-components/upload. Obviously it won’t work if you want css file instead of image.

@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[0]

thanks caiyij. The issue is due to the urllib. Guess i need to use .parse instead!

Does the function (some_function) iterate through all of the sheets if I import an excel file?

Hey

I am getting the same error. Can you explain a bit more in detail about how you solved it?