Black Lives Matter. Please consider donating to Black Girls Code today.

TypeError: Object of type 'DataFrame' is not JSON serializable

Hi, I am using dash to build a multipage app that basically does a correlation analysis with some variables pulled from a database using an API against user uploaded data.

I am trying to use the upload module and have a hidden layer in the app to have the user-uploaded dataset available across pages. But when I try to upload the dataset, it gives me JSON related errors.

The goal of this topic is to understand how to store a user-uploaded data for the session and have it available across pages. I’m also trying to display the data in a table after upload. Then, the “Analyze” button will serve as a callback to call a python script that would pull the API and perform the correlation analysis with the pulled data and user-uploaded data and store the result and display in graph/table format.

when I try to upload a simple csv file, it gives me an error. Code and error below:

from dash.dependencies import Input, Output, State
import dash_core_components as dcc
import dash_html_components as html
import base64
import io
import os
import dash
import pandas as pd
from datetime import datetime as dt
import dash_table_experiments as dte
import plotly
import json
import numpy as np
import flask

print(dcc.version) # 0.6.0 or above is required

app = dash.Dash()
app.config.suppress_callback_exceptions = True

app.layout = html.Div([
dcc.Location(id=‘url’, refresh=False),
# This is the ‘hidden div’ however its really a container for sub-divs, some hidden, some not
html.Div(id=‘output-data-upload’),
html.Br(),
html.Div(id=‘page-content’),

])

STARTING PAGE

home_page = html.Div([
dcc.Markdown(’’’
rules and guidelines for the tool
‘’’),
html.Br(),
dcc.Link(‘Upload My Data’, href=’/page-1’),
html.Br(),
dcc.Link(‘View Analysis’, href=’/page-2’),
])

#UPLOAD DATA PAGE
upload_page = html.Div([
html.H3(‘Select Data for Analysis’),
#UPLOAD DATA
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’
},
),
html.Div(id = ‘Target-File’, style={‘display’: ‘none’}),
html.Div(id=‘output-data-upload’),

SHOW THE UPLOADED DATA IN TABLE

how??

#DEFINE MIN DATE
html.Hr(), #horizontal line
html.H3(‘Select Minimum Date’),
html.Div([
dcc.DatePickerSingle(
id=‘min-date’,
min_date_allowed=dt(2010, 1, 1),
max_date_allowed=dt.now(),
initial_visible_month=dt.now(),
date=dt.now()
),
html.Div(id=‘min-date-value’)
]),
html.Br(),

#DEFINE MAX DATE
html.H3(‘Select Maximum Date’),
html.Div([
dcc.DatePickerSingle(
id=‘max-date’,
min_date_allowed=dt(2010, 1, 1),
max_date_allowed=dt.now(),
initial_visible_month=dt.now(),
date=dt.now()
),
html.Div(id=‘max-date-value’)
]),

#ANALYZE BUTTON
html.Hr(), #horizontal line
html.Div([
html.Button(id=‘analyze-button’, n_clicks=0, children=‘Analyze Data’),
html.Div(id=‘output-state’)
]),
html.Br(),
dcc.Link(‘View Analysis’, href=’/page-2’),
html.Br(),
dcc.Link(‘Go to Home’, href=’/’)
])

#WHERE TO VIEW THE CORRELATION RESULTS
analysis_page = html.Div([
html.Div(id=‘output-data-upload’),
html.Div(id=‘analysis-page-content’),
html.Br(),
dcc.Link(‘Back to upload page’, href=’/page-1’),
html.Br(),
dcc.Link(‘Go to Home’, href=’/’)
])

#FUNCTIONS
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
        target_df = pd.read_csv(
            io.StringIO(decoded.decode('utf-8')))
    elif 'xls' in filename:
        # Assume that the user uploaded an excel file
        target_df = pd.read_excel(io.BytesIO(decoded))
except Exception as e:
    print(e)
    return html.Div([
        'There was an error processing this file.'
    ])

return filename, target_df

#DATA UPLOAD
@app.callback(Output(‘output-data-upload’, ‘children’),
[Input(‘upload-data’, ‘contents’),
Input(‘upload-data’, ‘filename’),
Input(‘upload-data’, ‘last_modified’)])
def update_output(contents, filename, date):
if contents is not None:
filename, target_df = parse_contents(contents, filename, date)
target_json = target_df.to_json(orient = “split”)
# This is the key to the hidden div formatting
return html.Div([
html.Div(['Uploaded file to analyze: ’ + filename]),
html.Div([target_json], id=‘Target-File’, style={‘display’: ‘none’})
], style={‘padding-top’: ‘20px’,‘align’: “center”})

@app.callback(Output(‘output-state’, ‘children’),
[Input(‘analyze-button’, ‘n_clicks’)],
[State(‘Target-File’, ‘children’),
State(‘max-date-value’, ‘date’),
State(‘min-date-value’, ‘date’)])
def analysis_function(n_clicks,tankStats):
if n_clicks is not None:
# ALL THE API & ANALYSIS SCRIPTS
return ‘Analysis was successful!’

#MIN DATE SETTING
@app.callback(
dash.dependencies.Output(‘min-date-value’, ‘children’),
[dash.dependencies.Input(‘min-date’, ‘date’)])
def update_mindate(date):
string_prefix = ‘Minimum date: ’
if date is not None:
date = dt.strptime(date, ‘%Y-%m-%d’)
date_string = date.strftime(’%B %d, %Y’)
return string_prefix + date_string

#MAX DATE SETTING
@app.callback(
dash.dependencies.Output(‘max-date-value’, ‘children’),
[dash.dependencies.Input(‘max-date’, ‘date’)])
def update_maxdate(date):
string_prefix = ‘Maximum date: ’
if date is not None:
date = dt.strptime(date, ‘%Y-%m-%d’)
date_string = date.strftime(’%B %d, %Y’)
return string_prefix + date_string

Update the index

@app.callback(Output(‘page-content’, ‘children’), [Input(‘url’, ‘pathname’)])
def display_page(pathname):
if pathname == ‘/page-1’:
return upload_page
elif pathname == ‘/page-2’:
return analysis_page
elif pathname == ‘/’:
return home_page
else:
return “This page is invalid”

app.css.append_css({‘external_url’:“https://codepen.io/chriddyp/pen/bWLwgP.css”})

if name == ‘main’:
app.run_server(debug=True)

Thanks for the help!

Here is the error:

127.0.0.1 - - [22/Jun/2018 17:37:06] “POST /_dash-update-component HTTP/1.1” 200 -
127.0.0.1 - - [22/Jun/2018 17:37:06] “POST /_dash-update-component HTTP/1.1” 500 -
Traceback (most recent call last):
File “/Users/joopark1/anaconda3/lib/python3.6/site-packages/flask/app.py”, line 1997, in call
return self.wsgi_app(environ, start_response)
File “/Users/joopark1/anaconda3/lib/python3.6/site-packages/flask/app.py”, line 1985, in wsgi_app
response = self.handle_exception(e)
File “/Users/joopark1/anaconda3/lib/python3.6/site-packages/flask/app.py”, line 1540, in handle_exception
reraise(exc_type, exc_value, tb)
File “/Users/joopark1/anaconda3/lib/python3.6/site-packages/flask/_compat.py”, line 33, in reraise
raise value
File “/Users/joopark1/anaconda3/lib/python3.6/site-packages/flask/app.py”, line 1982, in wsgi_app
response = self.full_dispatch_request()
File “/Users/joopark1/anaconda3/lib/python3.6/site-packages/flask/app.py”, line 1614, in full_dispatch_request
rv = self.handle_user_exception(e)
File “/Users/joopark1/anaconda3/lib/python3.6/site-packages/flask/app.py”, line 1517, in handle_user_exception
reraise(exc_type, exc_value, tb)
File “/Users/joopark1/anaconda3/lib/python3.6/site-packages/flask/_compat.py”, line 33, in reraise
raise value
File “/Users/joopark1/anaconda3/lib/python3.6/site-packages/flask/app.py”, line 1612, in full_dispatch_request
rv = self.dispatch_request()
File “/Users/joopark1/anaconda3/lib/python3.6/site-packages/flask/app.py”, line 1598, in dispatch_request
return self.view_functionsrule.endpoint
File “/Users/joopark1/anaconda3/lib/python3.6/site-packages/dash/dash.py”, line 558, in dispatch
return self.callback_map[target_id]‘callback’
File “/Users/joopark1/anaconda3/lib/python3.6/site-packages/dash/dash.py”, line 526, in add_context
cls=plotly.utils.PlotlyJSONEncoder),
File “/Users/joopark1/anaconda3/lib/python3.6/json/init.py”, line 238, in dumps
**kw).encode(obj)
File “/Users/joopark1/anaconda3/lib/python3.6/site-packages/plotly/utils.py”, line 161, in encode
encoded_o = super(PlotlyJSONEncoder, self).encode(o)
File “/Users/joopark1/anaconda3/lib/python3.6/json/encoder.py”, line 199, in encode
chunks = self.iterencode(o, _one_shot=True)
File “/Users/joopark1/anaconda3/lib/python3.6/json/encoder.py”, line 257, in iterencode
return _iterencode(o, 0)
File “/Users/joopark1/anaconda3/lib/python3.6/site-packages/plotly/utils.py”, line 229, in default
return _json.JSONEncoder.default(self, obj)
File “/Users/joopark1/anaconda3/lib/python3.6/json/encoder.py”, line 180, in default
o.class.name)
TypeError: Object of type ‘DataFrame’ is not JSON serializable

Side note - we’re making these errors easier to debug in https://github.com/plotly/dash/pull/273