herrbert
herrbert

Reputation: 3

Using JSON in a request header

Trying to call an api with Python where a part of the headers contain "{}".

With Curl it works directly:

curl -X POST --header 'Content-Type: application/json' --header 'Accept: application/json' --header 'token: {"uid": "[email protected]","timestamp": 0,"token": "","client": "web","version": "","language": "zh-CN" }' -d '{ \ 
   "account": "[email protected]", \ 
   "pwd": "mypassword", \ 
   "is_local": true, \ 
   "agreement_agreement": 0 \ 
 }' 'http://globalapi.sems.com.cn:82/api/v1/Common/CrossLogin'

But with Python I cannot get it to work, the api throws an error. I suspect it is due to the format of the token in the header as it is a string containing {}. See the different variants commented out below - the api accepts none of them. It works fine to use {} in a dict with Python just using regular code:

sems_headers = {
    'Content-Type':'application/json',
    'Accept':'text/json',
    'token': '{"uid": "[email protected]","timestamp": 0,"token": "","client": "web","version": "","language": "en-GB"}' 
}
for c, d in sems_headers.items():
    print(c, d)

How can I call the api with the format required of the token in Python?

sems_headers = {
    'Content-Type':'application/json',
    'Accept':'text/json',
    #'token': "'uid':'[email protected]', 'timestamp':'0', 'token':'', 'client':'web', 'version':'', 'language':'en-GB'" 
    #'token': '{"uid": "[email protected]","timestamp": 0,"token": "","client": "web","version": "","language": "en-GB"}' 
    #'token': ''{{"uid": "[email protected]","timestamp": 0,"token": "","client": "web","version": "","language": "en-GB"}}' 
    #'token': "{""uid"": ""[email protected]"", ""timestamp"": 0, ""token"": "" "", ""client"": ""web"", ""version"": "" "", ""language"": ""en-GB"" }"
}

sems_post_data = {
    'account':'[email protected]',
    'pwd':'mypassword',
    'is_local':True,
    'agreement_agreement':0
}

post = requests.post("https://globalapi.sems.com.cn/api/v1/Common/CrossLogin", headers=sems_headers, data=sems_post_data)

print(post.text)

Upvotes: 0

Views: 1502

Answers (1)

awarrier99
awarrier99

Reputation: 3855

From the requests docs here it looks like your issue may actually be with how you're sending your JSON payload, as the data keyword argument sends form-encoded data rather than JSON-encoded. Try either explicitly JSON-encoding your payload, or using the json keyword argument instead:

post = requests.post("https://globalapi.sems.com.cn/api/v1/Common/CrossLogin", headers=sems_headers, json=sems_post_data)

or

import json
post = requests.post("https://globalapi.sems.com.cn/api/v1/Common/CrossLogin", headers=sems_headers, data=json.dumps(sems_post_data))

Also your Accept header should be changed to application/json and in order to parse the JSON response content, you should use post.json() rather than post.text

Altogether this would be:

sems_headers = {
    'Content-Type':'application/json',
    'Accept':'application/json',
    'token': '{"uid": "[email protected]","timestamp": 0,"token": "","client": "web","version": "","language": "en-GB"}' 
}

sems_post_data = {
    'account':'[email protected]',
    'pwd':'mypassword',
    'is_local':True,
    'agreement_agreement':0
}

post = requests.post("https://globalapi.sems.com.cn/api/v1/Common/CrossLogin", headers=sems_headers, json=sems_post_data)

print(post.json())

Upvotes: 1

Related Questions