How to solve error when opening image from URL

I want create image classification app using plotly Dash. I use reference from here dash-sample-apps/apps/dash-deit at main · plotly/dash-sample-apps · GitHub. But i got a problem when opening image from url.

@app.callback(
    [Output("image-display", "figure"), Output("stats-display", "figure")],
    [Input("btn-run", "n_clicks"), Input("input-url", "n_submit")],
    [State("input-url", "value")],
)
def run_model(n_clicks, n_submit, url):
    try:
        im = Image.open(requests.get(url, stream=True).raw)
    except Exception as e:
        print(e)
        return px.scatter(title="Error: " + e)

    fig = px.imshow(im, title="Original Image")

    im_pt = transform(im).unsqueeze(0)
    with torch.no_grad():
        preds = torch.softmax(model(im_pt), dim=1)
        scores = preds.numpy().squeeze()

    topk_idx = scores.argsort()[::-1][:10]
    top_classes = CLASSES[topk_idx][::-1]
    top_scores = scores[topk_idx][::-1]

    scores_fig = px.bar(
        x=top_scores,
        y=top_classes,
        labels=dict(x="Confidence", y="Classes"),
        title="ImageNet predictions by DEiT-base",
        orientation="h",
    )

    return fig, scores_fig

Error code in the part below this:

try:
        im = Image.open(requests.get(url, stream=True).raw)
    except Exception as e:
        print(e)
        return px.scatter(title="Error: " + e)

Does anyone know how to solve this? Thankyou.

Hi @liandanisa

add a print(url) at the begining of the callback to understand when and why the url get the value "none"

I got the error message like this. What does this mean?

Hey @liandanisa

if your callback is:

@app.callback(
    [Output("image-display", "figure"), Output("stats-display", "figure")],
    [Input("btn-run", "n_clicks"), Input("input-url", "n_submit")],
    [State("input-url", "value")],
)
def run_model(n_clicks, n_submit, url):
       print(url)

the print(url) will give you the value inside the 3rd element of the function, that represents the value of State(“input-url”, “value”)

The error showed means two possibilities:

  • Or you dont have the url as a 3rd value of your callback anymore.
  • Or you didn’t put the print(url) at the first line in the callback function as I said.

I con’t figure out any other possibilitie :thinking:

Sorry, I misplaced the code. After I followed as you said I got an error like this.

Hey Annisa,

Let’s go back :grinning:

Your first error message said that the “url” variable has a “none” value, this can be for at least two different reasons:

  • Or it’s beacuse when the app starts running the component “input-url” has no information, in this case you have to use prevent_update or no_update to prevent this kind of errors.

  • Or when the users select that “input-url” component (that I do not know which kind of component is, and how the value is selected), something wrong is happening and the Stete of this component still have a None value.

To find the reason, I sugested to print the value of the url variable before the callback use it. Then you can find if the variable are working as expected (printing the variable will not solve the problem, thus the error after printing will be the same). It’s just to have a better understandig of the process.

You need to try to find the problem or share more information about the component and how the user interact with it.

1 Like

I have tried various ways to display the image with the input link and it always fails. But I tried switching with displaying images using image upload and it worked. I have been successful in doing predictions, but I have a little problem when I want to display sample images from training data. The error showing “px.imshow only accepts 2D single-channel, RGB or RGBA images. An image of shape () was provided”. Do you know how to solve this?

The error is like below:

I want to display an image like this:

def display_examples(class_names, images, labels):
    fig = plt.figure(figsize=(20,20))
    for i in range(25):
        plt.subplot(5,5,i+1)
        plt.xticks([])
        plt.yticks([])
        plt.grid(False)
        plt.imshow(images[i], cmap=None)
        plt.xlabel(class_names[labels[i]])
@app.callback(Output('overview-train', 'figure')], 
             [Input('button-submit', 'n_clicks')])
def update_results(n_clicks):
    if n_clicks is None:
        raise PreventUpdate
    else:
        data = display_examples(class_names, train_images, train_labels)
        fig_train = px.imshow(data)
        return fig, fig_train

when I don’t use Dash and callback, the image output successfully appears. But when I use dash and callback an error occurs.

Hey @liandanisa

For displaying images I use this format:

html.Img(src=app.get_asset_url("image.jpg")

The image file must be located in the /assets folder