Clientside upload and processing

My below code works fine if I run it locally but not within a corporate network on IIS server (returns Error processing).

Any ideas how to make upload and processing happen on clientside only?

Minimal example:

import pandas as pd
import plotly.graph_objects as go
from dash import Dash, html, dcc, Input, Output, callback, clientside_callback
from scipy.stats import gaussian_kde
import numpy as np
import base64
import io

# Global variable to store the uploaded data
global_uploaded_data = None

# Initialize the Dash app
app = Dash(__name__)

# Define the layout of the app
app.layout = html.Div([
    dcc.Upload(
        id='upload-data',
        children=html.Button('Upload'),
        multiple=False
    ),
    html.Div(id='output-data-upload'),
    dcc.Store(id='uploaded-data-store'),
])

clientside_callback(
    """
    function(contents, filename) {
        if (!contents || !filename) {
            return null;
        }
        return {'contents': contents, 'filename': filename};
    }
    """,
    Output('uploaded-data-store', 'data'),
    [Input('upload-data', 'contents'),
     Input('upload-data', 'filename')]
)


# Callback for handling the file upload and creating the Plotly KDE plot
@callback(
    Output('output-data-upload', 'children'),
    [Input('uploaded-data-store', 'data')],
    prevent_initial_call=True
)
def update_output(data):
    global global_uploaded_data  # Use the global variable

    if data is not None:
        contents = data['contents']
        filename = data['filename'] if data['filename'] is not None else ''
        content_type, content_string = contents.split(',')

        decoded = base64.b64decode(content_string)
        try:
            if filename.endswith('.xlsx'):
                # Assume that the user uploaded an Excel file
                df = pd.read_excel(io.BytesIO(decoded))
                global_uploaded_data = df  # Update the global variable

                # Initialize a Plotly graph object figure for KDE
                fig = go.Figure()

                # Calculating KDE and plotting for each column
                for column in df.columns:
                    kde = gaussian_kde(df[column].dropna())
                    x_range = np.linspace(df[column].min(), df[column].max(), 500)
                    y_range = kde(x_range)

                    fig.add_trace(go.Scatter(x=x_range, y=y_range, mode='lines', name=column))


                return dcc.Graph(id='psd-graph', figure=fig)

            else:
                return html.Div([
                    'Unsupported format.'
                ])

        except Exception as e:
            print(e)
            return html.Div([
                'Error processing.'
            ])
    return html.Div([
        'No file.'
    ])



# Run the app
if __name__ == '__main__':
    app.run_server(debug=True)

Sample xlsx data:

ABC1 ABC2 ABC3 ABC4
2,9 1,1 3,9 3,9
3,4 0,8 0,3 2,4
2,1 1,0 1,7 2,7
2,7 0,9 1,8 2,6
0,8 1,7 2,0 3,1

Got it to work with:

    """
    function(contents) {
        if (!contents) {
            return null;
        }
    
        // Split the contents into the MIME type and the data itself
        var splitContents = contents.split(',');
        if (splitContents.length < 2) {
            console.error("Invalid content format");
            return null;
        }
    
        var mimeType = splitContents[0];
        var base64Data = splitContents[1];
    
        // Decode the Base64 string to binary
        var binaryData = atob(base64Data);
    
        try {
            var workbook = XLSX.read(binaryData, {type: 'binary'});
            var firstSheetName = workbook.SheetNames[0];
            var worksheet = workbook.Sheets[firstSheetName];
            var json = XLSX.utils.sheet_to_json(worksheet);
            return json;
        } catch (error) {
            return null;
        }
    }
    """,
2 Likes