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("", 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?

6

10 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(' 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': ' 
5

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

import requests url = "" 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) 
7

From requests 2.4.2 (), the "json" parameter is supported. No need to specify "Content-Type". So the shorter version:

requests.post(' json={'test': 'cheers'}) 

Which parameter between data / json / files you need to use depends on a request header named Content-Type (you can check this through the developer tools of your browser).

When the Content-Type is application/x-www-form-urlencoded, use data=:

requests.post(url, data=json_obj) 

When the Content-Type is application/json, you can either just use json= or use data= and set the Content-Type yourself:

requests.post(url, json=json_obj) 
requests.post(url, data=jsonstr, headers={"Content-Type":"application/json"}) 

When the Content-Type is multipart/form-data, it's used to upload files, so use files=:

requests.post(url, files=xxxx) 
2

The better way is:

url = "" data = { "cardno": "6248889874650987", "systemIdentify": "s08", "sourceChannel": 12 } resp = requests.post(url, json=data) 
0
headers = {"charset": "utf-8", "Content-Type": "application/json"} url = ' r = requests.post(url, json=YOUR_JSON_DATA, headers=headers) print(r.text) 

Works perfectly with python 3.5+

client:

import requests data = {'sender': 'Alice', 'receiver': 'Bob', 'message': 'We did it!'} r = requests.post("", json={'json_payload': data}) 

server:

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) @cherrypy.tools.json_in() @cherrypy.tools.json_out() def POST(self): self.content = cherrypy.request.json return {'status': 'success', 'message': 'updated'} 
1

I solved it this way:

from flask import Flask, request from flask_restful import Resource, Api req = request.json if not req : req = request.form req['value'] 

It always recommended that we need to have the ability to read the JSON file and parse an object as a request body. We are not going to parse the raw data in the request so the following method will help you to resolve it.

def POST_request(): with open("FILE PATH", "r") as data: JSON_Body = data.read() response = requests.post(url="URL", data=JSON_Body) assert response.status_code == 200 

With current requests you can pass in any data structure that dumps to valid JSON , with the json parameter, not just dictionaries (as falsely claimed by the answer by Zeyang Lin).

import requests r = requests.post(' json=[1, 2, {"a": 3}]) 

this is particularly useful if you need to order elements in the response.