How to upload file with python requests?
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.
Introduction
Python's requests library uploads files via multipart/form-data POST requests using the files parameter. You pass a dictionary mapping field names to file objects or tuples of (filename, file_object, content_type). The library handles the multipart encoding, Content-Type header, and boundary generation automatically. For large files, use streaming uploads to avoid loading the entire file into memory.
Basic File Upload
The files parameter tells requests to use multipart/form-data encoding. The key "file" is the form field name expected by the server.
Specifying Filename and Content-Type
The tuple form lets you override the filename sent to the server (useful when the local filename differs from the desired upload name).
Uploading Multiple Files
Upload with Additional Form Data
The data parameter sends additional form fields alongside the file. Both are encoded in the same multipart/form-data request.
Upload with Authentication
Uploading In-Memory Data (No File on Disk)
Streaming Upload (Large Files)
Error Handling
Common Pitfalls
- Opening files in text mode instead of binary:
open("file.pdf", "r")opens in text mode, which corrupts binary files during upload. Always useopen("file.pdf", "rb")with the"rb"flag for file uploads. - Setting Content-Type header manually: When using the
filesparameter,requestsautomatically sets theContent-Typetomultipart/form-datawith the correct boundary. Manually settingheaders={"Content-Type": "multipart/form-data"}omits the boundary and breaks the upload. - Not closing file handles: Opening files without
withstatements orclose()calls leaks file descriptors. When uploading multiple files in a list, ensure you close all handles after the request completes, or use context managers. - Loading large files entirely into memory:
requests.post(files={"file": open("10gb.zip", "rb")})reads the entire file into memory for encoding. For files over 100MB, userequests-toolbelt'sMultipartEncoderfor streaming uploads. - Using data instead of files for file uploads: Passing file content via the
dataparameter sends it asapplication/x-www-form-urlencoded, notmultipart/form-data. Most servers expect multipart encoding for file uploads. Always use thefilesparameter.
Summary
- Use
requests.post(url, files={"field": file_object})for simple file uploads - Pass a tuple
(filename, file_object, content_type)to control the filename and MIME type - Combine
filesanddataparameters to send form fields alongside the file - Use
requests-toolbelt.MultipartEncoderfor streaming large files without loading them into memory - Always open files in binary mode (
"rb") and usewithstatements for proper cleanup - Do not manually set the
Content-Typeheader —requestshandles the multipart boundary automatically
Related reading
- How to use Charles Proxy on the Xcode 6 iOS 8 Simulator?
- How to use Consumer API of Kafka 0.8.2?
- How to use Dataset API to read TFRecords file of lists of variant length?
- How to use Firebase with Spring boot REST Application?
- How to Upload Many Files to Google Colab?
- How to urlencode a querystring in Python?
- How to use Google API Client Library for JavaScript gapi with async/await?
- How to use host network for docker compose?

System Design Fundamentals
Build a strong foundation in designing scalable, reliable distributed systems.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.