0

I am trying to run this code from a directory, C:\users\user1\plant_app\main.py Edit: I am able to start the server, but I can't get the numpy array.

from fastapi import FastAPI, File, UploadFile
import uvicorn
from io import BytesIO
import numpy as np
from PIL import Image


def read_image(data):
    return np.array(Image.open(BytesIO(data)))

app=FastAPI()
@app.get('/check')
async def check():
     return {'message':'hello world'}
@app.post('/predict')
async def predict(file: UploadFile = File(...)):
     image=read_image(await file.read())
     return image


if __name__=='__main__':
    uvicorn.run(app,host='localhost',port=8000)

I am getting this error.

PS C:\Users\user1\plant_app> python -u "c:\Users\user1\plant_app\main.py"
INFO:     Started server process [21740]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
INFO:     Uvicorn running on http://localhost:8000 (Press CTRL+C to quit)
INFO:     127.0.0.1:58115 - "GET / HTTP/1.1" 404 Not Found

What am I doing wrong here?

  • 3
    It looks like your code only defines urls for `/check` and `/predict`. There is no `/` url. – John Gordon Jun 25 '23 at 21:22
  • You might also find [this](https://stackoverflow.com/a/73240097/17865804) and [this](https://stackoverflow.com/a/73264904/17865804) helpful – Chris Jun 26 '23 at 05:05

5 Answers5

0
@app.get('/')
dуf root():
    return {'message':'FastAPI app'}

you should define / url

  • 1
    That seems to start the server, but when I upload an image using docs I am getting `null` and `{"detail":"Not Found"}` with postman @Baktybek Baiserkeev – ihatecoding Jun 25 '23 at 21:42
0
@app.get('/')
async def root():
    return {'message': 'test'}

Try adding this because it seems like the GET route to '/' hasn't been declared.

  • That seems to start the server, but when I upload an image using docs I am getting `null` and `{"detail":"Not Found"}` with postman @Kionling – ihatecoding Jun 25 '23 at 21:46
0

We can access the API from http://localhost:8000/check or http://localhost:8000/predict. Or we can also use SwaggerUI which is integrated with FastAPI to interact with API.

0

Try this. I think the problem is returning the image. You need to create a response with a type of image (here image/png as my test case was a png file). I wasn't sure of what output you wanted. So, I made three services: one returns the np array, the other returns the shape of the array, and finally the one returns the image itself. Check the following links for more info:

from fastapi import FastAPI, File, UploadFile
import uvicorn
from io import BytesIO
import numpy as np
from PIL import Image
from fastapi.responses import Response
import json

def read_image(data):
    return np.array(Image.open(BytesIO(data)))

app=FastAPI()

@app.get('/')
async def check():
     return {'message':'hello world'}


@app.post('/array')
async def predict_array(file: UploadFile = File(...)):
     content = await file.read()
     image = read_image(content)
     return json.dumps(image.tolist())


@app.post('/shape')
async def predict_shape(file: UploadFile = File(...)):
     content = await file.read()
     image = read_image(content)
     return {'shape': image.shape}

@app.post('/image')
async def return_image(file: UploadFile = File(...)):
     content = await file.read()
     return Response(content=content, media_type="image/png")

if __name__=='__main__':
    uvicorn.run(app,host='localhost', port=8000)
Ehsan Hamzei
  • 339
  • 2
  • 8
-2

The error you are encountering indicates that the route you are trying to access is not found. In your code, you have defined two routes: /check and /predict. However, when you make a GET request to the root URL http://localhost:8000/, it returns a 404 Not Found error because you haven't defined a route for the root URL.

To fix this issue, you can add a route for the root URL / in your FastAPI application.

from fastapi import FastAPI, File, UploadFile
import uvicorn
from io import BytesIO
import numpy as np
from PIL import Image


def read_image(data):
    return np.array(Image.open(BytesIO(data)))


app = FastAPI()


@app.get('/')
async def root():
    return {'message': 'Welcome to the API'}


@app.get('/check')
async def check():
    return {'message': 'Hello, world'}


@app.post('/predict')
async def predict(file: UploadFile = File(...)):
    image = read_image(await file.read())
    # Perform your prediction or processing here using the image
    # Return the result or perform further actions as needed
    return {'message': 'Prediction successful', 'image_shape': image.shape}


if __name__ == '__main__':
    uvicorn.run(app, host='localhost', port=8000)

In this updated code, the root URL / is defined with the @app.get('/') decorator, and it returns a simple welcome message. Now, when you access http://localhost:8000/, you should see the response from the root route.

Additionally, I uncommented the code inside the /predict route so that it reads the uploaded image, converts it to a NumPy array, and performs further processing or prediction tasks as required.