I'm trying to upload a file to a FastAPI server using requests.
I've boiled the problem down to its simplest components.
The client using requests:
import requests
files = {'file': ('foo.txt', open('./foo.txt', 'rb'))}
response = requests.post('http://127.0.0.1:8000/file', files=files)
print(response)
print(response.json())
The server using fastapi:
from fastapi import FastAPI, File, UploadFile
import uvicorn
app = FastAPI()
@app.post('/file')
def _file_upload(my_file: UploadFile = File(...)):
print(my_file)
if __name__ == "__main__":
uvicorn.run("main:app", host="0.0.0.0", port=8000, log_level="debug")
Packages installed:
Client Output: <Response [422]> {'detail': [{'loc': ['query', 'my_file'], 'msg': 'field required', 'type': 'value_error.missing'}]}
Server Output: INFO: 127.0.0.1:37520 - "POST /file HTTP/1.1" 422 Unprocessable Entity
What am I missing here?
Use the Request object directly For that you need to access the request directly. By declaring a path operation function parameter with the type being the Request FastAPI will know to pass the Request in that parameter.
You are able to get request body with request. json() , which will give you the parsed JSON as dictionary. In the edit history of this answer it seems that request. body() has been replaced by request.
FastAPI (Async) - Python FastAPI in asynchronous mode clocks in at ~228 requests per second.
To create a POST request in Python, use the requests. post() method. The requests post() method accepts URL. data, json, and args as arguments and sends a POST request to a specified URL.
Technical Details Data from forms is normally encoded using the "media type" application/x-www-form-urlencoded when it doesn't include files. But when the form includes files, it is encoded as multipart/form-data. If you use File, FastAPI will know it has to get the files from the correct part of the body.
The files will be uploaded as "form data". If you declare the type of your path operation function parameter as bytes, FastAPI will read the file for you and you will receive the contents as bytes. Have in mind that this means that the whole contents will be stored in memory.
This API is used to create web applications in python and works with Uvicorn and Gunicor web servers. FastAPI supports asynchronous programming, pydantic, and the most impressive of all OpenAPI Specification. These are a few of the many features that FastAPI holds; we will be using the above-listed features in this article.
See documentation here: You can declare multiple File and Form parameters in a path operation, but you can't also declare Body fields that you expect to receive as JSON, as the request will have the body encoded using multipart/form-data instead of application/json. This is not a limitation of FastAPI, it's part of the HTTP protocol.
FastAPI expecting the file in the my_file
field and you are sending it to the file
field.
it should be as
import requests
url = "http://127.0.0.1:8000/file"
files = {'my_file': open('README.md', 'rb')}
res = requests.post(url, files=files)
Also, you don't need a tuple to manage the upload file (we're dealing with a simple upload, right?)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With