Reputation: 379
I have to use a webservice endpoint that needs both JSON and non-json in the query and I don't know how to do it with the requests package. the same code provided has http.client in it, and I don't have access to that package in this project for unrelated reasons
The example code is:
import http.client
conn=http.client.HTTPSConnection('some.url')
payload="{\"some_json_dict_key\": \"some_json_dict_value\"}"
headers={'content-type': "application/json", 'accept': "application/json"}
conn.request("POST", "/someEndpoint?param1=value_of_param1", payload, headers)
res = conn.getresponse()
data = res.read().decode('utf-8')
The code i have tried which doesnt work:
import requests
headers={'content-type': "application/json", 'accept': "application/json"}
params={'param1': 'value_of_param1'}
json_payload = "{\"some_json_dict_key\": \"some_json_dict_value\"}"
url = 'https://some.url/someEndpoint'
response = requests.post(url, headers=headers, data=params, json=json_payload)
however that doesn't seem to work i get the exception
{'httpMessage': 'Bad Request', 'moreInformation': 'The body of the request, which was expected to be JSON, was invalid, and could not be decoded. The start of an object { or an array [ was expected.'}
Upvotes: 1
Views: 1318
Reputation: 50220
You must realize that a POST request can pass information in two places: In the body (data) of the request, and in the URL string (the request parameters, like a GET request does). In the example you didn't fully emulate, the parameters are in the URL string, and the body, according to the error message you got back, must consist of a single JSON object. Therefore, use the params
dictionary for the URL parameters, like this:
response = requests.post(url, headers=headers, params=params, data=json_payload)
That ought to do it, unless there are other details to take care of.
Upvotes: 0
Reputation: 140286
According to the documentation:
Instead of encoding the dict yourself, you can also pass it directly using the json parameter (added in version 2.4.2) and it will be encoded automatically:
>>> url = 'https://api.github.com/some/endpoint'
>>> payload = {'some': 'data'}
>>> r = requests.post(url, json=payload)
but you're passing a string into the json
parameter (I admit that the error message could be clearer). All other parameters are json/dict objects. Make json_payload
an actual dictionary.
json_payload = {"some_json_dict_key": "some_json_dict_value"} # real dictionary, not a json string
url = 'https://some.url/someEndpoint'
response = requests.post(url, headers=headers, data=params, json=json_payload)
Upvotes: 1