TypeError: path should be path-like or io.BytesIO, not <class 'shiny.reactive._reactives.Value'>

380 Views Asked by At

I am creating a simple shiny app for a dog breed classifier. The user would be able to upload a picture of a dog, and then have the shiny app display the predicted breed.

A simplified version of the app code is as follows:

from shiny import App, Inputs, Outputs, Session, reactive, render, ui
import keras
import tensorflow as tf
import numpy as np
import pickle

app_ui = ui.page_fluid(
    ui.input_file("dog_pic", "Upload your dog picture!", accept=[".jpeg"], multiple=False),
    ui.output_text("txt")

)

def server(input, output, session):

    # PROCESSING IMAGE:
    @reactive.Calc
    def parsed_file():
         image = tf.keras.preprocessing.image.load_img(input.dog_pic, target_size=(224, 224))
         input_arr = tf.keras.preprocessing.image.img_to_array(image)
         input_arr = np.array([input_arr])
         input_arr = input_arr.astype('float32') / 255.
         return input_arr

    # PARSING IMAGE THROUGH TO MODEL
    @output
    @render.text
    def txt():

        model = tf.keras.models.load_model('model')
        dog_prediction = model.predict(parsed_file())
        return f"Predicted dog breed is {dog_prediction}!"

app = App(app_ui, server)

The error I am getting is: enter image description here

What does this mean? Thanks!

3

There are 3 best solutions below

0
Cornelia On

Your functions parsed_file() and txt() are called as soon as you start the shiny app. But at that time your file is not yet loaded. You have to add something like "if file available then ... else ...".

0
UDAY REDDY KAIPA On

Here, the input.dog_pic does not return a string or path type. So need to typecast accordingly to a string.

0
shebdon On

The error says you're giving a shiny object instead of a path. Calling input.dog_pic gives the shiny object handle/function, but calling input.dog_pic() gives the value stored by that object. Since you want the path stored inside, use input.dog_pic() as the path to import your image.

See for example your use of parsed_file() in your render text function. The parentheses tell shiny to evaluate the function and return just the value.

If you still have problems, you may need to add some calls to shiny's req function. Include it as one of the things you import from shiny and add req(input.dog_pic()) as the first line in your parse_file function. Do the same for req(parsed_file()) in your txt function. These will tell your functions to require those values before they attempt the calculation. Fixing the parentheses as stated above still seems necessary to me.