43
requests.post(url, data={'interests':'football','interests':'basketball'})

I tried this, but it is not working. How would I post football and basketball in the interests field?

Christopher Nuccio
  • 596
  • 1
  • 9
  • 21
Jasonyi
  • 501
  • 1
  • 4
  • 10

3 Answers3

85

Dictionary keys must be unique, you can't repeat them. You'd use a sequence of key-value tuples instead, and pass this to data:

requests.post(url, data=[('interests', 'football'), ('interests', 'basketball')])

Alternatively, make the values of the data dictionary lists; each value in the list is used as a separate parameter entry:

requests.post(url, data={'interests': ['football', 'basketball']})

Demo POST to http://httpbin.org:

>>> import requests
>>> url = 'http://httpbin.org/post'
>>> r = requests.post(url, data=[('interests', 'football'), ('interests', 'basketball')])
>>> r.request.body
'interests=football&interests=basketball'
>>> r.json()['form']
{u'interests': [u'football', u'basketball']}
>>> r = requests.post(url, data={'interests': ['football', 'basketball']})
>>> r.request.body
'interests=football&interests=basketball'
>>> r.json()['form']
{u'interests': [u'football', u'basketball']}
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • @Bethlee: not sure why you'd ever do that. That's just being extra verbose, there is no advantage to using `files` here unless you __must__ send a multipart/form request, **and** you must strictly control the order of the fields **and** you have actual file data to send. Otherwise just use `data=(('worker_ids[]', '66'), ('worker_ids[]', '67'))`. – Martijn Pieters Feb 02 '21 at 12:54
  • @Martjin: Yes. You're right. I know it's not a good way but In my case the server-side was wrongfully coded. I used the answer without any choice. I just want to share the other ways. Thank you for your advice. I will delete the comment – Bethlee Feb 03 '21 at 13:28
13

It is possible to use urllib3._collections.HTTPHeaderDict as a dictionary that has multiple values under a key:

from urllib3._collections import HTTPHeaderDict
data = HTTPHeaderDict()
data.add('interests', 'football')
data.add('interests', 'basketball')
requests.post(url, data=data)
Sjoerd
  • 74,049
  • 16
  • 131
  • 175
2

Quoting from the docs directly:

The data argument can also have multiple values for each key. This can be done by making data either a list of tuples or a dictionary with lists as values. This is particularly useful when the form has multiple elements that use the same key:

>>> payload_tuples = [('key1', 'value1'), ('key1', 'value2')]
>>> r1 = requests.post('https://httpbin.org/post', data=payload_tuples)
>>> payload_dict = {'key1': ['value1', 'value2']}
>>> r2 = requests.post('https://httpbin.org/post', data=payload_dict)
>>> print(r1.text)
{
  ...
  "form": {
    "key1": [
      "value1",
      "value2"
    ]
  },
  ...
}
>>> r1.text == r2.text
True
Mooncrater
  • 4,146
  • 4
  • 33
  • 62