dcc.Upload max_size exceeded notification

I have a file upload form configured to limit the upload file size using the max_size parameter to dcc.Upload. If the file size is <= max_size the callback is called and the server receives the payload.

If the file size is > max_size, nothing happens. I want to be able to notify the user that the file is larger than allowed, but I cannot find a way to capture the validation. I have enable dash debug and look at the code execution in the browser, put a logging statement first in the callback (it is not called) but I can’t find a way to capture the validation. It just fails silently.

Is there a way to capture the max_size validation checked by dcc.Upload?

Thank you

Marcelo

1 Like

Hello @marceloli,

Welcome to the community!

Could you use the className_reject prop and just provide a style if it is too big?

@jinnyzor thank you for you quick reply. Sorry it took long to respond. I am having no luck figuring this out. If the file is within max_size it loads, crickets if not. I tried using style_reject. I expect the dcc.Upload style to change if the files is bigger than max_size, but it does not.

from dash import Dash, dcc, html, dash_table, Input, Output, State, callback

import base64
import datetime

app = Dash(__name__)

app.layout = html.Div(
    [
        dcc.Upload(
            id="upload-data",
            children=html.Div(["Drag and Drop or ", html.A("Select Files")]),
            max_size=4,
            style={
                "width": "100%",
                "height": "60px",
                "lineHeight": "60px",
                "borderWidth": "1px",
                "borderStyle": "dashed",
                "borderRadius": "5px",
                "textAlign": "center",
            },
            style_reject={
                "borderStyle": "solid",
                "borderColor": "#8B4513",
                "backgroundColor": "#FF0000",
            },
            style_active={
                "borderWidth": "1px",
            },
            # Allow multiple files to be uploaded
            multiple=False,
        ),
        html.Div(id="output-data-upload"),
    ]
)


def parse_contents(contents, filename, date):

    data_received = base64.decodebytes(
        contents.encode("utf8").split(b";base64,")[1]
    )
    return html.Div(
        [
            html.H5(filename),
            html.H6(datetime.datetime.fromtimestamp(date)),
            html.P(f"Data: {data_received}"),
            html.Hr(),  # horizontal line
            # For debugging, display the raw contents provided by the web browser
            html.Div("Raw Content"),
        ]
    )


@callback(
    Output("output-data-upload", "children"),
    Input("upload-data", "contents"),
    State("upload-data", "filename"),
    State("upload-data", "last_modified"),
)
def update_output(contents, filename, modified):
    if contents is not None:
        return parse_contents(contents, filename, modified)
    else:
        return None


if __name__ == "__main__":
    app.run(debug=True, port=8090, host="0.0.0.0")

Hello @marceloli,

I dont think there is a way to catch this, it looks like the underlying input doesnt even see it as a valid file to even decide if it is rejected or approved.

The underlying Dropzone looks like it has this ability, but Upload currently doesnt have a onDropRejected function getting passed to the Dropzone.

Agree that this is a big issue! I’m experiencing the same thing. There is no control in the document finder to restrict the user from picking a large file (like there is for accept), and also no feedback that the callback isn’t actually being triggered.