5

If you know how to send a file to FastAPI server and access it in /predict endpoint for prediction using my models please help me out.

I have deployed the model using /predict endpoint and done uvicorn main:app and it's deployed but the only thing is input that is a document is in my local pc so how can I sent it to FastAPI?

I have went through the documentation of FastAPI and I have found this example code there, but the challenge is that this code creates an UI for uploading file which is not what I"m looking for.

from typing import Optional
from fastapi import FastAPI
from fastapi import FastAPI, File, UploadFile
from pydantic import BaseModel
from typing import List
from fastapi.responses import HTMLResponse


app = FastAPI()

class User(BaseModel):
    user_name: dict

@app.post("/files/")
async def create_files(files: List[bytes] = File(...)):
    return {"file_sizes": [len(file) for file in files]}


@app.post("/uploadfiles/")
async def create_upload_files(files: List[UploadFile] = File(...)):
    return {"filenames": [file.filename for file in files]}


@app.get("/")
async def main():
    content = """
<body>
<form action="/files/" enctype="multipart/form-data" method="post">
<input name="files" type="file" multiple>
<input type="submit">
</form>
</body>
    """
    return HTMLResponse(content=content)
user_12
  • 1,778
  • 7
  • 31
  • 72
  • You need to upload one file or multiple files at once? – lsabi Oct 02 '20 at 09:44
  • @Isabi Currently I just need to know how to send one file at once without UI page and access that file in /predict endpoint. – user_12 Oct 02 '20 at 10:08
  • Future readers may also find [this answer](https://stackoverflow.com/a/71711008/17865804), as well as [this answer](https://stackoverflow.com/a/70689003/17865804) and [this answer](https://stackoverflow.com/a/74507628/17865804) helpful. – Chris Mar 18 '23 at 07:00

1 Answers1

8

FASTAPI CODE

This will be your endpoint.

from fastapi import FastAPI, UploadFile, File


app = FastAPI()


@app.post("/file")
async def upload_file(file: UploadFile = File(...)):
    # Do here your stuff with the file
    return {"filename": file.filename}

JAVASCRIPT CODE

This is your javascript code (assuming you are using javascript for uploading the file)

form = new FormData();
form.append("file", myFile);
let response = await fetch('/file', {
      method: 'POST',
      body: form
    });

    let result = await response.json();

EDIT: Python file upload

I'm using httpx, but technically it should be fully compatible with requests.

import httpx
# Create a dict with a key that has the same name as your file parameter and the file in binary form (the "b" in "rb")
f = {'file': open('foo.png', 'rb')}
r = httpx.post("your_url/file", files=f)

You can see more configurations/examples on the official documentation of httpx at https://www.python-httpx.org/quickstart/#sending-multipart-file-uploads.

Again, I did not test the code, since I'm tight with time at the moment.

END OF EDIT

Be aware that the parameter name of the file, MUST match the one used for sending the file.

In case, there is also another answer from me on how to test it with POSTMAN. See How to send file to fastapi endpoint using postman

NOTE

I did not test the code as I don't have time right now. In case, there is also a link with a previous answer of mine that works (unless FASTAPI introduced breaking changes).

lsabi
  • 3,641
  • 1
  • 14
  • 26
  • Thank you so much for helping out. I'll test it out with my code. – user_12 Oct 02 '20 at 10:24
  • 1
    Take my code with a grain of salt, it's not perfect, but should be enough for you to get the idea of what and how your code could look like. FastAPI docs are good, keep an eye on them – lsabi Oct 02 '20 at 10:32
  • The docs are a good source to be checked first. You can simply use uploadedFile.file to access the file content. See reference https://fastapi.tiangolo.com/tutorial/request-files/#uploadfile – lsabi Oct 02 '20 at 12:08
  • Thank you `uploadedFile.file` worked for me but that is not the main issue for me, I have an another endpoint called `@app.post("/predict")` predict function so how can I access the output from /file endpoint in predict function – user_12 Oct 02 '20 at 12:13
  • 1
    You have to save the uploaded file and then read it when the "predict" endpoint gets called. Although my suggestion is to not defer the ML training and to do it immediately. Also, if you still have questions different from the currently asked one, please open another question with details – lsabi Oct 02 '20 at 12:17
  • Thanks so much, this was extremely helpful! – Shivam Sahil Nov 13 '21 at 17:51