Python
Multipart Form Data
HTTP Requests
Requests Library
Programming Tutorial

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

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Sending multipart/form-data with Python requests is the standard way to upload files alongside text fields. The library handles boundary generation automatically when you use the files argument correctly. Most issues come from incorrect payload shape, file handle management, or mixing JSON with multipart semantics.

Basic File Upload

Simple one-file upload:

python
1import requests
2
3url = "https://httpbin.org/post"
4
5with open("report.pdf", "rb") as f:
6    files = {"file": ("report.pdf", f, "application/pdf")}
7    data = {"user_id": "42", "category": "finance"}
8    resp = requests.post(url, files=files, data=data, timeout=30)
9
10print(resp.status_code)
11print(resp.json()["files"].keys())

requests sets proper multipart content type automatically.

Multiple Files in One Request

Use list of tuples for repeated field names.

python
1files = [
2    ("attachments", ("a.txt", open("a.txt", "rb"), "text/plain")),
3    ("attachments", ("b.txt", open("b.txt", "rb"), "text/plain")),
4]
5
6resp = requests.post(url, files=files, data={"ticket": "123"})

Remember to close file handles or use context managers for each file.

Raw Bytes Upload Without Disk File

You can upload generated bytes content.

python
content = b"hello from memory"
files = {"file": ("memory.txt", content, "text/plain")}
resp = requests.post(url, files=files)

Useful for generated reports or transformed content.

Authentication and Headers

Keep auth separate from multipart construction.

python
headers = {"Authorization": "Bearer TOKEN"}
resp = requests.post(url, headers=headers, files=files, data=data)

Do not manually set Content-Type to multipart with custom boundary unless you build body yourself.

Error Handling and Retries

Add timeout and handle transport failures.

python
1import requests
2from requests.exceptions import RequestException
3
4try:
5    resp = requests.post(url, files=files, data=data, timeout=20)
6    resp.raise_for_status()
7except RequestException as exc:
8    print("upload failed:", exc)

For critical workflows, add retry with backoff for transient errors.

Server Expectations

Server frameworks may require specific field names:

  • file field key such as file or attachments
  • metadata field names exactly matching backend parser

Always check API docs and inspect server error payloads if upload fails.

Sending File and JSON Metadata Together

Multipart requests carry text fields as form values, not JSON body.

python
1import json
2
3meta = {"source": "mobile", "priority": "high"}
4files = {"file": ("img.png", open("img.png", "rb"), "image/png")}
5data = {"meta": json.dumps(meta)}
6
7resp = requests.post(url, files=files, data=data)

Server can parse meta field as JSON string.

Streaming Large Uploads

For very large files, monitor memory and network timeouts. Keep chunked upload or resumable APIs in mind when simple multipart calls are insufficient for production limits.

Session Reuse and Connection Hygiene

Reuse a requests.Session for repeated multipart uploads to reduce connection overhead.

python
1session = requests.Session()
2with open("report.pdf", "rb") as f:
3    files = {"file": ("report.pdf", f, "application/pdf")}
4    r = session.post(url, files=files, timeout=30)

Server-Side Debugging Tip

If upload returns validation errors, inspect server expectation for field names and multipart parser configuration. Most failures are contract mismatches rather than transport issues.

Document this pattern for team consistency.

Validate with realistic test cases before deployment.

Log request ids for traceability.

Test thoroughly.

Consistently.

Use retries.

Common Pitfalls

  • Sending file path string instead of opened binary file.
  • Manually overriding multipart content type headers incorrectly.
  • Forgetting to include text fields in data alongside files.
  • Leaking file handles by not closing opened files.
  • Assuming JSON body and multipart body can be combined as one payload format.

Summary

  • Use files and data in requests.post for multipart uploads.
  • Let requests generate multipart boundaries automatically.
  • Manage file handles safely with context managers.
  • Include proper timeout and error handling for reliability.
  • Match server field names and authentication expectations precisely.

Course illustration
Course illustration

All Rights Reserved.