How to Send "multipart/form-data" with Requests in Python

Introduction

If you've ever needed to send files or data to a server via a POST request, you've likely had to use multipart/form-data. In this Byte, we'll see how to send these requests using the requests library in Python.

What is "multipart/form-data"?

multipart/form-data is a media type that allows you to send binary or text data in parts within a single request. It's often used for things like uploading files to a server. For instance, when you upload a profile picture or a document on a website, the data is often sent as multipart/form-data.

The main advantage of multipart/form-data is its ability to bundle multiple parts, each with potentially different data types, into a single HTTP request. This is very efficient and can save a lot of bandwidth.

How to Send multipart/form-data with Requests

When it comes to HTTP requests in Python, the Requests library is a go-to tool. Its simplicity and functionality make it popular among Python developers. Let's see how we can use it to send multipart/form-data.

Setting Up your Environment

Before we start, make sure you have the Requests library installed. If not, you can add it to your Python environment using pip:

$ pip install requests

The Code

Let's say we need to upload a profile picture to a server. Here's a simple script that does that:

import requests

url = "http://example.com/upload"
file_path = "/path/to/your/file.jpg"

with open(file_path, "rb") as file:
    files = {'file': file}
    response = requests.post(url, files=files)

print(response.status_code)

In this script, we first import the requests library. We then define the url where we want to send the file and the file_path where our file is located locally.

We open the file in binary mode ('rb'), which allows us to read non-text files like images. We then create a dictionary files where the key is the string 'file' and the value is the file object.

Finally, we send a POST request to the server using requests.post(url, files=files). The files parameter in requests.post takes care of setting the Content-Type header to multipart/form-data.

After running the script, it will print the status code of the response. A status code of 200 means the request was successful.

Get free courses, guided projects, and more

No spam ever. Unsubscribe anytime. Read our Privacy Policy.

Note: Make sure to replace 'http://example.com/upload' with the actual URL you want to send the file to, and '/path/to/your/file.jpg' with the actual path of the file you want to upload before running this code.

Handling Possible Errors

When working with multipart/form-data and Python requests, there are a few potential errors you should check for and handle. Python's try-except block is the best way to handle these errors.

Consider the following code:

import requests

url = "http://example.com/upload"
file_path = "/path/to/your/file"

try:
    with open(file_path, "rb") as f:
        r = requests.post(url, files={'file': f})
except FileNotFoundError:
    print("The file was not found.")
except requests.exceptions.RequestException as e:
    print("There was an exception that occurred while handling your request.", e)

This code attempts to open a file and send it as a part of a multipart/form-data request. If the file does not exist, a FileNotFoundError will be raised. If requests could not connect, it'll raise a ConnectionError. All requests exceptions inherit from RequestException, so in our code we catch all of those errors with just one line.

Common Errors and Solutions

There are a few more errors when sending multipart/form-data than what we touched on above. Let's take a look at a few of them:

  1. requests.exceptions.TooManyRedirects: This occurs when the URL you point to keeps returning redirects. For example, if two URLs redirect to each other, you'll stuck in an infinite loop. If requests detects this, it'll raise this exception.

  2. requests.exceptions.MissingSchema: This occurs when you forget to include the protocol (http:// or https://) in your URL. Make sure your URL includes the protocol.

  3. requests.exceptions.ConnectionError: This error is raised when you're not able to connect to the server. It could be due to a wrong URL, network issues, or the server might be down.

  4. requests.exceptions.Timeout: This error is raised when a request times out. You can handle this by increasing the timeout or setting it to None (which means the request will wait indefinitely).

Alternative Methods

One alternative to sending a multipart/form-data request is to use the http.client library, which is a low-level HTTP protocol client. It's a bit more complex to use, but it gives you more control over your requests and doesn't require a third party library.

Here's an example of how you can send multipart/form-data using http.client:

import http.client
import os
import uuid

# Prepare the file content
file_path = "/path/to/your/file.jpg"
with open(file_path, "rb") as f:
    file_content = f.read()

# Define boundary and headers
boundary = str(uuid.uuid4())
headers = {
    'Content-Type': f"multipart/form-data; boundary={boundary}",
}

# Create HTTP connection
conn = http.client.HTTPConnection("example.com", 8000)

# Create multipart/form-data payload
payload = (
    f"--{boundary}\r\n"
    f"Content-Disposition: form-data; name=\"file\"; filename=\"file.jpg\"\r\n"
    "Content-Type: text/plain\r\n"
    "\r\n"
    f"{file_content.decode('utf-8')}\r\n"
    f"--{boundary}--\r\n"
)

# Send the request
conn.request("POST", "/upload", body=payload, headers=headers)

# Get the response
response = conn.getresponse()
data = response.read()

# Close the connection
conn.close()

# Print response
print(response.status, response.reason)
print(data.decode("utf-8"))

This code creates an HTTPS connection to "example.com", sends a POST request with our file as multipart/form-data, and then prints the response from the server.

Conclusion

In this Byte, you've seen how to send multipart/form-data with the Python requests library, handle potential errors, and also looked at some common errors and their solutions. We also discussed an alternative method for sending multipart/form-data using http.client.

Last Updated: September 19th, 2023
Was this helpful?

© 2013-2024 Stack Abuse. All rights reserved.

AboutDisclosurePrivacyTerms