Python requests can't send multiple headers with same key

requests stores the request headers in a dict, which means every header can only appear once. So without making changes to the requests library itself it won't be possible to send multiple headers with the same name.

However, if the server is HTTP1.1 compliant, it must be able to accept the same as one header with a comma separated list of the single values.


requests is using urllib2.urlencode under the hood (or something similar) in order to encode the headers.

This means that a list of tuples can be sent as the payload argument instead of a dictionary, freeing the headers list from the unique key constraint imposed by the dictionary. Sending a list of tuples is described in the urlib2.urlencode documentation. http://docs.python.org/2/library/urllib.html#urllib.urlencode

The following code will solve the problem without flattening or dirty hacks:

url = 'whatever'
headers = [('X-Attribute', 'A'),
           ('X-Attribute', 'B')]
requests.get(url, headers = headers)

Requests now stores all headers (sent and received) as case insensitively in dictionaries. Beyond even that, though, open up a python console and write:

headers = {'X-Attribute':'A', 'X-Attribute':'B'}

What you get is undefined behaviour. (It may seem reproducible but it is wholly undefined.) So what you're really sending to requests in that instance is this:

{'X-Attribute': 'A'}  # or {'X-Attribute': 'B'}, we can never be certain which it will be

What you could try (but won't work) is:

headers = [('X-Attribute', 'A'), ('X-Attribute', 'B')]

But at least this will be wholly defined behaviour (you'll always send B). As @mata suggested, if your server is HTTP/1.1 compliant, what you can do is this:

import collections

def flatten_headers(headers):
    for (k, v) in list(headers.items()):
        if isinstance(v, collections.Iterable):
           headers[k] = ','.join(v)

headers = {'X-Attribute': ['A', 'B', ..., 'N']}
flatten_headers(headers)
requests.get(url, headers=headers)

I hope this is helpful to you.