48
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?

1
  • Take a lookie Commented May 27, 2020 at 11:33

5 Answers 5

94

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']}
Sign up to request clarification or add additional context in comments.

2 Comments

@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')).
@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
14

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)

Comments

3

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

1 Comment

This one worked for me, and I could use it with the "files" function parameter .
1

curl command string presents data as -d 'product_ids[]=719&product_ids[]=107'. I was able to form the data array correctly by adding square brackets:

payload = [('product_ids[]', id) for id in ids_list]
response = requests.post(url, data=payload, headers=headers)

1 Comment

This has nothing to do with curl.
0

To post multiple values with the same key in Python requests, you need to use a list. For example, the following code will post the values football and basketball to the interests field:

import requests

url = "https://example.com/post"
data = {"interests": ["football", "basketball"]}

response = requests.post(url, data=data)

This will result in the following POST request:

POST /post HTTP/1.1
Host: example.com
Content-Type: application/x-www-form-urlencoded

interests=football&interests=basketball

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.