Search code examples
python-3.xpython-requestshtml-encode

Passing email with '+' character using python requests


I'm trying to pass a email to an endpoint that has a '+' character in it. The endpoint accepts application/x-www-form-urlencoded. For example, if I have username=test+user@gmail.com, Postman creates the following curl which has the '+' and '@' html encoded:

curl -X POST \
  http://myurl.com/test \
  -H 'Cache-Control: no-cache' \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  -H 'Postman-Token: 07181aad-f4a5-4ac5-1720-dcb59d7e8310' \
  -d username=test%2Buser%40gmail.com

This call works as expected

However, when using requests, it seems the field isn't being encoded.

import requests

if __name__ == "__main__":
    timeout = 10
    url = "https://myurl/test"
    header_data = {'Content-Type': 'application/x-www-form-urlencoded'}
    header_data = {}
    payload = "username=test+user@gmail.com"
    r = requests.request("POST", url, data=payload, headers=header_data, timeout=timeout)
    print (r.request.body)

The result of that final print isn't an encoded string, but instead:

username=test+user@gmail.com

Solution

  • If you pass in a string, requests will pass that payload on unmodified (see also the source). Use

    payload = {'username': "test+user@gmail.com"}
    

    to get form-encoding.