简体   繁体   中英

FastAPI image POST and resize

I'm creating an app using a FastAPI that is supposed to generate resized version of uploaded images. The upload should be done through POST/images and after calling a path /images/800x400 it should show an image with 800x400 size. This is what I have so far:

from fastapi import FastAPI, File, UploadFile

app = FastAPI()

@app.post("/images/")
async def create_upload_file(file: UploadFile = File(...)):
    return {"filename": file.photo.jpg}

(photo.jpg is an image that is in the same location as the app file)

How can I see this uploaded image? When I call http://127.0.0.1:8000/images/ I get: {"detail":"Method Not Allowed"}

How is it possible to POST more than one image and after that making a resizing on a random one by calling /images/800x400 to see it in a version 800x400? I was thinking about using Pillow. Is it fine in this case?

EDIT

I'm now a step forward but still getting an error while trying to display an image.

from fastapi.responses import FileResponse
import uuid

app = FastAPI()

db = []

@app.post("/images/")
async def create_upload_file(file: UploadFile = File(...)):
    
    file.filename = f"{uuid.uuid4()}.jpg"
    contents = await file.read() # <-- Important!

    db.append(file)

# example of how you can save the file
    with open(file.filename, "wb") as f:
        f.write(contents)

    return {"filename": file.filename}

@app.get("/images/")
async def show_image():  
    return db[0]```

As a response I get:
{
  "filename": "70188bdc-923c-4bd3-be15-8e71966cab31.jpg",
  "content_type": "image/jpeg",
  "file": {}
}

I would like to use: return FileResponse(some_file_path)
and in the file path put the filename from above. Is it right way of thinking? 

I believe you need to look into what HTTP methods are used for.

POST

The POST method is used to submit an entity (your image) to the specified resource, often causing a change in state or side effects on the server.

So, use POST to upload the image to your backend.

GET

The GET method requests a representation of the specified (image) resource. Requests using GET should only retrieve data.

GET is the default method when navigating to a site with a browser. So, if you want to see an image when you navigate to http://127.0.0.1:8000/images/ you need a function (with FastAPI's decorator) defined for that endpoint.

Understanding these you can define the endpoints required to achieve your goal.

EDIT

For reference, here is a working implementation of uploading and saving an image. I used Postman to perform the actual request.

from fastapi import FastAPI, File, UploadFile
from fastapi.responses import FileResponse
import uuid

app = FastAPI()


@app.post("/images/")
async def create_upload_file(file: UploadFile = File(...)):
    
    file.filename = f"{uuid.uuid4()}.jpg"
    contents = await file.read() # <-- Important!

    # example of how you can save the file
    with open(file.filename, "wb") as f:
        f.write(contents)

    return {"filename": file.filename}

This saves the image uploaded with a random ID as the file name in the directory where the application is running. Of course, you should use a proper data store but I think it should get you in the right direction.

References

https://www.starlette.io/requests/#request-files

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM