Search code examples
pdffile-uploadfastapistreamlit

Post request with parameter as a streamlit file_uploader object for a pdf throws `422 Unprocessable Entity` on FastAPI


Summary

I am trying to send a streamlit file_uploader object for a pdf as a post request to a FastAPI based server. However, the server throws 422 Unprocessable Entity error. My server side code looks like the following.

@app.post("/file/upload")
async def upload_file(username: str, uploaded_file: UploadFile = File(...)):
    path_to_save_file = Path.home() / username / "saved_files"
    path_to_save_file.mkdir(parents=True, exist_ok=True)
    file_location = f"{path_to_save_file}/{uploaded_file.filename}"
    with open(file_location, "wb+") as file_object:
        file_object.write(uploaded_file.file.read())
    return {"INFO": f"File '{uploaded_file.filename}' saved to your profile."}

Client side code looks the following

uploaded_pdf = st.file_uploader('Upload a file', type="pdf")
    
url = "http://localhost:8000/file/upload"
if st.button("Upload PDF"):
    payload = {"username": username, "uploaded_file": uploaded_pdf.getvalue()}
    response = requests.post(url, payload)
    st.write(response)

The relevant API endpoint works correctly with a pdf on http://localhost:8000/docs#. I also tried just passing uploaded_pdf instead of uploaded_pdf.getvalue() but to no avail.

Would appreciate any insight on how to fix it. Thank!!


Solution

  • Found answer to the question. All I did is change the client side code to accept file-based parameters separately through files param. It begun to look like the following.

    url = "http://localhost:8000/file/upload"
    if st.button("Upload PDF"):
        payload = {"username": username, "filename": uploaded_pdf.name}
        response = requests.post(url, params=payload, files={"uploaded_file": uploaded_pdf.getvalue()})
        st.write(response)