Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Send and receive file using Python: FastAPI and requests

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:

  • fastapi
  • python-multipart
  • uvicorn
  • requests

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?

like image 885
prometheanSun Avatar asked Dec 02 '20 05:12

prometheanSun


People also ask

How can I send request in FastAPI?

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.

How do I get request body in FastAPI?

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.

How many requests can FastAPI handle?

FastAPI (Async) - Python FastAPI in asynchronous mode clocks in at ~228 requests per second.

How do you send data in a Python request?

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.

How is form data encoded in fastapi?

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.

How will the files be uploaded to fastapi?

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.

What is the fastapi API in Python?

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.

Why can't I declare multiple file and form parameters in fastapi?

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.


Video Answer


1 Answers

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?)

like image 75
JPG Avatar answered Oct 02 '22 17:10

JPG