Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sending post request data nested object #2885

Closed
wiryonolau opened this issue Nov 17, 2015 · 11 comments
Closed

sending post request data nested object #2885

wiryonolau opened this issue Nov 17, 2015 · 11 comments

Comments

@wiryonolau
Copy link

Unable to send post data from nested object, some of the data is truncated

payload = {
   "config": {
      "data" : "test"
   }
}

r = request.post('http://httpbin.org/post', data=payload)
print(r.text)

{
  "args": {}, 
  "data": "", 
  "files": {}, 
  "form": {
    "config": "data"
  }, 
  "headers": {
    "Accept": "*/*", 
    "Accept-Encoding": "gzip, deflate", 
    "Content-Length": "11", 
    "Content-Type": "application/x-www-form-urlencoded", 
    "Host": "httpbin.org", 
    "User-Agent": "python-requests/2.8.1"
  }, 
  "json": null, 
  "origin": "xxx.xxx.xxx.xxx", 
  "url": "http://httpbin.org/post"
}
@Lukasa
Copy link
Member

Lukasa commented Nov 17, 2015

What are you expecting the result to be here?

@wiryonolau
Copy link
Author

the post data that send become config : data instead of the full object

@Lukasa
Copy link
Member

Lukasa commented Nov 17, 2015

I'm sorry, I wasn't clear enough.

When you use the data keyword, we encode the data using HTTP form-encoding. This is not capable of representing nested data structures, only flat ones. So my question is: what are you trying to achieve, exactly? Because what you're asking requests to do does not make any sense.

@wiryonolau
Copy link
Author

If I urlencode the payload it appear like this

config=%7B%27data%27%3A+%27test%27%7

which is what should I get on the server

@Lukasa
Copy link
Member

Lukasa commented Nov 17, 2015

So you literally want to represent the config as a urlencoded JSON string?

@wiryonolau
Copy link
Author

Ah sorry shouldn't use urlencode, in php they have http_build_query that convert the payload become like this

config%5Bdata%5D=test

@Lukasa
Copy link
Member

Lukasa commented Nov 17, 2015

@wiryono That does not match what the urlencoded payload you copied decodes to. In fact, your urlencoded payload corresponds to config={'data': 'test'}, which is a JSON-serialized representation of the nested data structure. To get that, you'd want to use:

import json

payload = {
   "config": json.dumps({
      "data" : "test"
   })
}

r = request.post('http://httpbin.org/post', data=payload)
print(r.text)

That will work appropriately.

@Lukasa
Copy link
Member

Lukasa commented Nov 17, 2015

Ok, so to represent that in requests you want to use:

payload = {
   "config[data]": 'test',
}

There is no consistent, standardised way to represent nested data in form-encoding, and PHP just happily invented one. Requests doesn't guess what you want here, you need to come up with a conversion function yourself I'm afraid.

@Lukasa Lukasa closed this as completed Nov 17, 2015
@sigmavirus24
Copy link
Contributor

See also requests/toolbelt#45 (which I hope to have time to tackle soon).

@martimlobao
Copy link

The solution is non-obvious, but all you have to do is change the data argument to json:

r = request.post('http://httpbin.org/post', json=payload)

It's not clear to me why the two arguments exist when they seem to be functionally identical. At least, a warning should be given to the user when trying to send a nested dictionary with the data argument (see #5058).

@sigmavirus24
Copy link
Contributor

They're not functionally identical in the slightest, otherwise both would just work. Please read the documentation.

@psf psf locked as resolved and limited conversation to collaborators Apr 18, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants