Shery
Shery

Reputation: 1882

Python POST request with Nested Dictionary values/args

Already looked at here, here and here but still having issues. I have a POST data that looks like this:

{
   "config":{
             "param1": "param1 value",
             "param2": "param2 value",
             "param3": "param3 value"
            },
   "name": "Testing API",
   "url": "https://testingapi.my.own.com",
   "enabled": true
}

I have the following headers:

{
  "Content-Type": "application/json",
  "referer": "https://testingapi.my.own.com",
  "X-CSRFToken": "my token value here"
}

How do format this for the session.post?

I am keep getting the response code of 400 and logs are stating that I am not sending the required params in the post request.

Here is the code:

headers = {"Content-Type": "application/json",
           "referer": "https://testingapi.my.own.com",
           "X-CSRFToken": "my token"
}

request_data = {
   "config":{
             "param1": "param1 value",
             "param2": "param2 value",
             "param3": "param3 value"
            },
   "name": "Testing API",
   "url": "https://testingapi.my.own.com",
   "enabled": "true"
}

#tried the following:
r = session.post(url, data =  request_data, headers=headers)
r = session.post(url, json =  json.dumps(request_data), headers=headers)

Upvotes: 0

Views: 1924

Answers (1)

Chillie
Chillie

Reputation: 1485

When you do data = request_data your nested dictionary is not packaged into the request body as you expect. Try inspecting the body attribute of the request object:

import requests
s = requests.Session()
request_data = {
    "config":{
        "param1": "param1 value",
        "param2": "param2 value",
        "param3": "param3 value"
     },
    "name": "Testing API",
    "url": "https://testingapi.my.own.com",
    "enabled": True
}
r = s.post('https://httpbin.org/post/404', data=request_data )
r.request.body

returns

'url=https%3A%2F%2Ftestingapi.my.own.com&enabled=True&config=param3&config=param2&config=param1&name=Testing+API'

And when you json = json.dumps(request_data) you json-dump your data twice, so so the server (after unserializing the data one time) only sees a json string rather than an unserialized dict (see requests docs).

So you need to either serialize your data before passing it to data

r = s.post('https://httpbin.org/post/404', data=json.dumps(request_data), )

or as Paul has suggested, use the json parameter and pass your data dict to it:

r = s.post('https://httpbin.org/post/404', json=request_data)

Upvotes: 1

Related Questions