Explain Codes LogoExplain Codes Logo

How to send a "multipart/form-data" with requests in Python?

python
multipart
requests
file-uploads
Nikita BarsukovbyNikita Barsukov·Feb 21, 2025
TLDR

To send a multipart/form-data with requests in Python, you use the requests.post() method together with the files parameter, as shown below:

import requests url = 'YOUR_URL' files = {'file': open('file.txt', 'rb')} # 'rb' because it's reading time, not file.txt's bedtime response = requests.post(url, files=files) print(response.text) # The server's sweet whispers

This piece of code uploads the file 'file.txt' to your specified URL. You should replace url and files according to your configuration and needs.

Catering for form fields without associated files

In some instances, you may need to transmit form fields that do not involve files. In such a case, you use a tuple (None, data) in the files parameter:

fields = { ('field1', (None, 'value1')), ('field2', (None, 'value2')) } response = requests.post(url, files=fields) # Who needs files, anyway?

This way, you can adequately handle form fields without files.

Controlling the filename and content type in HTTP headers

You might need to control the filename and content type via the HTTP headers. This can be easily achieved by utilizing a tuple while using the files dictionary:

files = { 'file': ('report.csv', open('report.csv', 'rb'), 'text/csv') # .csv because we care for the datatype } response = requests.post(url, files=files) # Snail mail has evolved

This bit of code sends 'report.csv' as a text/csv file to the URL.

Getting complex with advanced multipart encoding

At times, you might encounter scenarios that necessitate streaming uploads or setting additional HTTP headers. In these cases, requests_toolbelt can come in handy:

from requests_toolbelt import MultipartEncoder multipart_data = MultipartEncoder( fields={ 'field1': 'value1', 'file': ('passwords.txt', open('passwords.txt', 'rb'), 'text/plain') # Totally safe password transferring } ) response = requests.post(url, data=multipart_data, headers={'Content-Type': multipart_data.content_type})

Using the requests_toolbelt module allows you to handle more complex scenarios involving multipart form data.

SSL verification

While you might find some suggesting using verify=False when they encounter SSL errors, doing so is NOT secure. It's essential to properly resolve SSL errors rather than ignoring them.

Managing large file uploads - Time for streaming

For large file uploads, you should consider using streaming uploads:

with open('huge_file.iso', 'rb') as f: requests.post(url, data=f) # Uploading ISO files like a pro

This method prevents loading the entire file into memory, saving you from a potential memory overload.

Integrating with FastAPI for file uploads

If you're working with FastAPI, receiving file uploads can be handled like this:

from fastapi import FastAPI, File, UploadFile app = FastAPI() @app.post("/upload/") async def upload_file(file: UploadFile = File(...)): return {"filename": file.filename} # Look at me, I'm a server-side developer now!

This approach shows how you can manage file uploads on the server side using FastAPI.

Payload naming and formatting - Because details matter

When constructing your payload, ensure that your field and file names are consistent with what the server expects. Correct naming is critical, as it allows the server to parse the multipart data correctly.