How to add both file and JSON Form in a FastAPI POST request?
You should not define the Content-Type multipart/form-data
header yourself. The requests
library takes care of this automatically by defining the boundary. If you set this header yourself, requests
will not do it and your server will not know what boundary to expect (unless you decide to also set the boundary yourself).
To work your header should be without the content-type:
headers = {
'Accept': 'application/json',
secret: header_secret
}
I need to send files and data through FastAPI. I'm trying to send requests but couldn't get it to work
You are getting Data
in JSON body.
If you want to do it you should do:
@app.post("/uploadfile/")
async def create_file(
test1: Optional[str] = Form(None),
test2: Optional[str] = Form(None),
test3: Optional[str] = Form(None),
image: bytes = File(...),
):
# Stuff here ...
PS: [How to use pydantic model with form data]
POST request to FastAPI using Python Requests with a file and query parameters
To pass query parameters in Python requests, you should use params
key instead. Hence:
response = requests.post(url='<your_url_here>', params=payload)
Additionally, there is no need to set the Content-type
in the headers, as it will automatically be added, based on the parameters you pass to requests.post()
. Doing so, the request will fail, as, in addition to multipart/form-data
,"Content-type
must include the boundary
value used to delineate the parts in the post body. Not setting the Content-Type
header ensures that requests sets it to the correct value" (ref). Have a look at this and this. Also, make sure that in files
you use the same key
name you gave in your endpoint, i.e., file
. Thus, in Python requests it should look something like the below:
files = {('file', open('my_file.txt', 'rb'))}
response = requests.post(url='<your_url_here>', files=files, params=payload)
You could also find more options as to how to send additional data along with files at this answer.
How to add multiple body params with fileupload in FastAPI?
From the FastAPI discussion thread--(#657)
if you are receiving JSON data, with
application/json
, use normal Pydantic models.This would be the most common way to communicate with an API.
If you are receiving a raw file, e.g. a picture or PDF file to store it in the server, then use
UploadFile
, it will be sent as form data (multipart/form-data
).If you need to receive some type of structured content that is not JSON but you want to validate in some way, for example, an Excel file, you would still have to upload it using
UploadFile
and do all the necessary validations in your code. You could use Pydantic in your own code for your validations, but there's no way for FastAPI to do it for you in that case.
So, in your case, the router should be as,
from fastapi import FastAPI, File, UploadFile, Form
app = FastAPI()
@app.post("/predict")
async def predict(
industry: str = Form(...),
file: UploadFile = File(...)
):
# rest of your logic
return {"industry": industry, "filename": file.filename}
Related Topics
How to Use an Image for the Background in Tkinter
Django Passing Custom Form Parameters to Formset
Function for Factorial in Python
Selecting a Row of Pandas Series/Dataframe by Integer Index
Plotting a 2D Heatmap with Matplotlib
Assigning to Variable from Parent Function: "Local Variable Referenced Before Assignment"
Load Data from Txt with Pandas
Combine Pool.Map with Shared Memory Array in Python Multiprocessing
What Is the Internal Precision of Numpy.Float128
How to Convert a Date String to Different Format
Converting String with Utc Offset to a Datetime Object
Is There a Math Ncr Function in Python
Replacing Few Values in a Pandas Dataframe Column with Another Value
How to Execute Python Code from Within Visual Studio Code
Returning the Product of a List
What's the Deal with Python 3.4, Unicode, Different Languages and Windows