Correct way to make a Python HTTPS request using requests module?

Your code is fighting the Requests library: you're doing a lot of stuff yourself that Requests will do for you.

Firstly, don't form-encode your data yourself, let Requests do it by providing a dictionary to data, like @flyer's answer suggested.

When you do this, Requests will also correctly set the Content-Type header, so you don't have to. Also, please don't send a Connection header: Requests will manage it for you. The same applies to Host headers: sending a Host header can only cause problems.

Finally, don't set the Authorization header yourself, let Requests do it by providing it with your authentication credentials. The idiomatic Requests code would be:

payload = {
    'grant_type': 'authorization_code', 
    'code': request.args['code'],
    'state': request.args['state'],
    'redirect_uri': 'http://xxx.xyz.com/request_listener',
}

url = 'https://serviceprovider.xxx.com/auth/j_oauth_resolve_access_code'

response = requests.post(url, data=payload, verify=False)

If that doesn't work, then I would suspect your payload data is bad.


It seems that there are two mistakes.

The first one:
When you want to post data, the data format should be like this:

payload = {
    'grant_type': 'authorization_code', 
    'code': request.args['code'],
    'state': request.args['state'],
    'redirect_uri': 'http://xxx.xyz.com/request_listener',
}

The second:
Requests could verify SSL certificates for https requests automatically and it sets verify=True as default. You set verify=False and that means that you want to ignore the ssl verification. That maybe not what you want. Here is the doc