AttributeError: 'FileUpload' object has no attribute 'data'

When I try to upload the image of a bear and click classify. I get this


error

Your post doesn’t show where/how btn_upload is set, which makes it hard to even guess and the issue. Can you link to the whole notebook?

What do you get from…

type(btn_upload)

and…

dir(btn_upload)

I just encountered the same situation. After some tests, here’s my solution:

import matplotlib.pyplot as plt
from PIL import Image
from io import BytesIO
img = Image.open(BytesIO(btn_upload.value[-1].content))
plt.imshow(img)

The type of btn_upload.value[-1].content is a memoryview and therefore I searched for how to load images from memory and then came up with above code snippet.

Edit: For prediction in the later code block, the image format will cause problem and I had to convert it using img = np.array(img).

1 Like

Share how did I find the solution.

As you mentioned, I used dir(btn_upload) to find value and then the content. Also, type is a great tool to work along with dir. :grinning:

1 Like

Now my notebook is running but ,I am getting this error can you help me resolve it. If you need any more information please let me know




I can share my notebook as well

It’s the same problem as indicated by the error message.

Original code:

def on_click_classify(change):
    img = PILImage.create(btn_upload.data[-1])
    out_pl.clear_output()
    with out_pl: display(img.to_thumb(128,128))
    pred,pred_idx,probs = learn_inf.predict(img)
    lbl_pred.value = f'Prediction: {pred}; Probability: {probs[pred_idx]:.04f}'

Modify it as the follows:

def on_click_classify(change):
    img = Image.open(BytesIO(btn_upload.value[-1].content))  # change this
    out_pl.clear_output()
    with out_pl: display(img.to_thumb(128,128))
    img = np.array(img)                                      # and add this
    pred,pred_idx,probs = learn_inf.predict(img)
    lbl_pred.value = f'Prediction: {pred}; Probability: {probs[pred_idx]:.04f}'
2 Likes

Thanks a lot it worked can you please tell me what caused it, why it was not working properly and how can i deploy it using voila

You could remove that line and check the error message.

I can’t remember the details but it’s something about the image format for the learn_inf.predict() function. The img = np.array(img) convert the image to a numpy array which is acceptable to the learn_inf.predict() function.

Yes. Somehow the kernel still takes old ‘on_click_classify’ function into account and hence the error. Try shutting down the kernel, restart it and then run all the code. The error should disapper.

I encountered the same issue when I run the notebook locally. However, the same notebook works fine with the Google colab. Thus I suppose it is somehow related to the version of ipywidgets.
Checking the doc of ipywidgets, it says

 Changes in *ipywidgets 8*:

 The `FileUpload` changed significantly in ipywidgets 8:

*The `.value` traitlet is now a list of dictionaries, rather than a dictionary mapping the uploaded name to the content. To retrieve the original form, use `{f["name"]: f.content.tobytes() for f in uploader.value}`.
*  The `.data` traitlet has been removed. To retrieve it, use `[f.content.tobytes() for f in uploader.value]`.

Thus, I changed the one signle line, now it works perfert. Hope such info is useful for others

#img = PILImage.create(btn_upload.data[-1])
img = PILImage.create(btn_upload.value[0].content.tobytes())
3 Likes