How to upload a file and some data through HTTP multipart in Python 3 using the requests library

Undeniably, the HTTP protocol had become the dominant communication protocol between computers.

Through the HTTP protocol, a HTTP client can send data to a HTTP server. For example, a client can upload a file and some data from to a HTTP server through a HTTP multipart request.

If you are building that client with Python 3, then you can use the requests library to construct the HTTP multipart request easily.

In case you need it, this is how we can upload a file and some data through HTTP multipart in Python 3 using the requests library.

1. Define the file upload scenario

First, let us define the file upload scenario.

Assume that we are building a Python 3 application for your Raspberry Pi 3. Whenever a button is pressed, an image will be captured with the camera on your Raspberry Pi along with temperature read from a DHT11 sensor.

Once we click the button, the Raspberry Pi 3 will snap a picture and make it available in its filesystem.

Given that, we will be building a function that will take a file path to an image and a float value for the temperature as input parameters. Given that, the function will upload the image file and the temperature to a server endpoint at http://www.example.com/api/v1/sensor_data.

2. Install the requests library

In order to use the requests library, we need to install it by running the following pip command inside your Python environment:

pip install requests

If you are using a virtual environment to run your Python application on your Raspberry Pi, then you can run the command after activating the virtual environment.

3. Write the Python 3 function to upload the image file and temperature to the server endpoint

After you had installed the requests library, we can use the following codes to upload the image file and temperature value via a HTTP multipart request:

import requests
import os

function send_data_to_server(image_path, temperature):
        
    image_filename = os.path.basename(image_path)

    multipart_form_data = {
        'image': (image_filename, open(image_path, 'rb')),
        'temperature': ('', str(temperature)),
    }

    response = requests.post('http://www.example.com/api/v1/sensor_data/',
                             files=multipart_form_data)

    print(response.status_code)

The send_data_to_server function accepts a path to an image and a temperature value as its input value. Once the function is being called, it first get the filename of the image from the path.

After that, it constructs a dictionary with two multipart variables - image and temperature. Both variables and their values are represented by 2-tuples. The image variable is assigned a filename and a file handle to the actual image. On the other hand, as temperature is a single value, the first element of the 2-tuple is empty while the second element contains the temperature as a string.

Once we had constructed the dictionary to represent the content, we call requests.post to send a HTTP multipart request to the server endpoint at http://www.example.com/api/v1/sensor_data/.

Lastly, the function prints the status of the HTTP response received from the server.

About Clivant

Clivant a.k.a Chai Heng enjoys composing software and building systems to serve people. He owns techcoil.com and hopes that whatever he had written and built so far had benefited people. All views expressed belongs to him and are not representative of the company that he works/worked for.