Starting with Requests version 2.4.2, you can use the json= parameter (which takes a dictionary) instead of data= (which takes a string) in the call:
>>> import requests
>>> r = requests.post('http://httpbin.org/post', json={"key": "value"})
>>> r.status_code
200
>>> r.json()
{'args': {},
'data': '{"key": "value"}',
'files': {},
'form': {},
'headers': {'Accept': '*/*',
'Accept-Encoding': 'gzip, deflate',
'Connection': 'close',
'Content-Length': '16',
'Content-Type': 'application/json',
'Host': 'httpbin.org',
'User-Agent': 'python-requests/2.4.3 CPython/3.4.0',
'X-Request-Id': 'xx-xx-xx'},
'json': {'key': 'value'},
'origin': 'x.x.x.x',
'url': 'http://httpbin.org/post'}
Answer from Zeyang Lin on Stack OverflowHow can I POST JSON data with Python's Requests library? - Stack Overflow
Why is the json information not loading in from the request ?
APIs: Params= vs json= whats the difference?
PSA: Latest Tautulli update crashes on startup with simplejson errors -- easy fix though
What is the difference between data and json parameters in Python requests?
data is for form-encoded (default) or raw data (when Content-Type header is overriden). While json is specifically for JSON format data and automatically sets Content-Type to application/json.
Does the Python requests library support asynchronous POST requests?
Unfortunately, the requests library does not support asynchronous requests. However, the httpx library is an alternative that provides async capabilities, making it suitable for applications requiring concurrency. See our guide to Python httpx for details.
How can I include custom headers in using Python requests?
Pass headers as a dictionary using the headers parameter. Note that requests automatically generates some headers like User-Agent, Content-Length and Content-Type, so be cautious when overriding them.
Videos
Starting with Requests version 2.4.2, you can use the json= parameter (which takes a dictionary) instead of data= (which takes a string) in the call:
>>> import requests
>>> r = requests.post('http://httpbin.org/post', json={"key": "value"})
>>> r.status_code
200
>>> r.json()
{'args': {},
'data': '{"key": "value"}',
'files': {},
'form': {},
'headers': {'Accept': '*/*',
'Accept-Encoding': 'gzip, deflate',
'Connection': 'close',
'Content-Length': '16',
'Content-Type': 'application/json',
'Host': 'httpbin.org',
'User-Agent': 'python-requests/2.4.3 CPython/3.4.0',
'X-Request-Id': 'xx-xx-xx'},
'json': {'key': 'value'},
'origin': 'x.x.x.x',
'url': 'http://httpbin.org/post'}
It turns out I was missing the header information. The following works:
import requests
url = "http://localhost:8080"
data = {'sender': 'Alice', 'receiver': 'Bob', 'message': 'We did it!'}
headers = {'Content-type': 'application/json', 'Accept': 'text/plain'}
r = requests.post(url, data=json.dumps(data), headers=headers)