Non Ascii characters are escaped when posting JSON

When using 

    import requests 
    requests.post('https://httpbin.org/post', json={'data': 'My Päload'})

the non asci characters (like 'ä' in this case),
are getting escaped, resulting in wron data beeing received by the endpoint.

I had to help myself by doing all this stuff manually:

    import requests
    import json
    
    json_string = json.dumps({'data': 'My Päload'}, ensure_ascii=False)
    requests.post('https://httpbin.org/post', data=json_string.encode('utf-8'), headers={'Content-Type': 'application/json'})

## Expected Result

Payload should retain special characters:

    {"data": "My Päload"}"

## Actual Result

Special characters are getting encoded:

    {"data": "My P\\u00e4load"}

## Reproduction Steps

See summary

## System Information

`{
    "chardet": {    
    "version": "3.0.4"
  },
  "cryptography": {
    "version": ""
  },
  "idna": {
    "version": "2.10"
  },
  "implementation": {
    "name": "CPython",
    "version": "3.8.0"
  },
  "platform": {
    "release": "10",
    "system": "Windows"
  },
  "pyOpenSSL": {
    "openssl_version": "",
    "version": null
  },
  "requests": {
    "version": "2.24.0"
  },
  "system_ssl": {
    "version": "1010104f"
  },
  "urllib3": {
    "version": "1.25.9"
  },
  "using_pyopenssl": false
}`


I'd recommend having an additional parameter for JSON encoding options, something like that:

    requests.post('https://httpbin.org/post', json={'data': 'My Päload'}, json_args={
      ensure_ascii=False,
      sort_keys=True,
      indent=4
    })

You can always encode your own JSON and pass it to data= with a content-encoding set.

> You can always encode your own JSON and pass it to data= with a content-encoding set.

Yes, but one has to be aware of this fact and i hat to spend 1 hour to even locate the origin of this problem.
I think it should be at least be mentioned in the docts

Also you have to manually encode the JSON string to UTF-8 bytes, which is another pitfall you can step into, after you figured out the JSON encodign problem

@sethmlarson 
Is it okay if I work on this? I was thinking, I can run a check to see if passed data is not ASCII compliant right before the 
`body = complexjson.dumps(json)` block in the PreparedStatement's **prepare_body** function

Something like this to check for ascii
```
def is_ascii(json:dict):
    for k, v in json.items():
        if isinstance(v, dict):
            #nested dict
            return is_ascii(v)
        else if isinstance(v, str):
            return v.isascii()         
    return True
```
then 
```
body = complexjson.dumps(json) if is_ascii(json) else complexjson.dumps(json, ensure_ascii=False)
```
Let me know if that's a-okay! :smile: 

Thanks!



@hpca01 Your code appears to be pretty specific to your use-case and thus shouldn't live in the Requests code base.

The way things are now work for most people and if you need something else you can encode yourself as is recommended in this thread. 

Ah okay, sorry just saw this come up on the first contribution tracker, didn't know it wasn't needed anymore.

The text `{"data": "My P\u00e4load"}` (via `print(json.dumps({'data': 'My Päload'}))`) is a perfectly valid JSON encoding for the dict you've described, @martyglaubitz.

If your receiving end can not decode that into something like `{'data': 'My Päload'}`, it is at fault.

Going to close as there's been a recommended work-around and we can't make changes to this code path.