1

As described here, it is possible to send multiple files with one request: Uploading multiple files in a single request using python requests module

However, I have a problem generating these multiple filehandlers from a list. So let's say I want to make a request like this:

sendfiles = {'file1': open('file1.txt', 'rb'), 'file2': open('file2.txt', 'rb')}
r = requests.post('http://httpbin.org/post', files=sendfiles)

How can I generate sendfiles from the list myfiles?

myfiles = ["file1.txt", "file20.txt", "file50.txt", "file100.txt", ...]
Community
  • 1
  • 1
AndiPower
  • 853
  • 10
  • 20

1 Answers1

4

Use a dictionary comprehension, using os.path.splitext() to remove those extensions from the filenames:

import os.path

sendfiles = {os.path.splitext(fname)[0]: open(fname, 'rb') for fname in myfiles}

Note that a list of 2-item tuples will do too:

sendfiles = [(os.path.splitext(fname)[0], open(fname, 'rb')) for fname in myfiles]

Beware; using the files parameter to send a multipart-encoded POST will read all those files into memory first. Use the requests-toolbelt project to build a streaming POST body instead:

from requests_toolbelt import MultipartEncoder
import requests
import os.path

m = MultipartEncoder(fields={
    os.path.splitext(fname)[0]: open(fname, 'rb') for fname in myfiles})
r = requests.post('http://httpbin.org/post', data=m,
                  headers={'Content-Type': m.content_type})
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • apparently there is a little something in the format of the dict: in the question the filenames don't have their extensions, for some reason. – njzk2 Apr 07 '14 at 17:23