Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to POST JSON data with Python Requests?

I need to POST a JSON from a client to a server. I'm using Python 2.7.1 and simplejson. The client is using Requests. The server is CherryPy. I can GET a hard-coded JSON from the server (code not shown), but when I try to POST a JSON to the server, I get "400 Bad Request".

Here is my client code:

data = {'sender':   'Alice',     'receiver': 'Bob',     'message':  'We did it!'} data_json = simplejson.dumps(data) payload = {'json_payload': data_json} r = requests.post("http://localhost:8080", data=payload) 

Here is the server code.

class Root(object):      def __init__(self, content):         self.content = content         print self.content  # this works      exposed = True      def GET(self):         cherrypy.response.headers['Content-Type'] = 'application/json'         return simplejson.dumps(self.content)      def POST(self):         self.content = simplejson.loads(cherrypy.request.body.read()) 

Any ideas?

like image 260
Charles R Avatar asked Mar 16 '12 07:03

Charles R


People also ask

How do I send a JSON POST request in Python?

To post a JSON to the server using Python Requests Library, call the requests. post() method and pass the target URL as the first parameter and the JSON data with the json= parameter. The json= parameter takes a dictionary and automatically converts it to a JSON string.

How do you send data in the body of POST request in Python?

You'll want to adapt the data you send in the body of your request to the specified URL. Syntax: requests. post(url, data={key: value}, json={key: value}, headers={key:value}, args) *(data, json, headers parameters are optional.)


2 Answers

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'} 
like image 88
Zeyang Lin Avatar answered Oct 10 '22 09:10

Zeyang Lin


It turns out I was missing the header information. The following works:

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) 
like image 35
Charles R Avatar answered Oct 10 '22 10:10

Charles R