Hoe JSON-gegevens POST met Python-verzoeken?

Ik moet een JSON POST van een client naar een server. Ik gebruik Python 2.7.1 en simplejson. De klant gebruikt Verzoeken. De server is CherryPy. Ik kan een hard-coded JSON van de server KRIJGEN (code niet getoond), maar wanneer ik een JSON naar de server probeer te POST, krijg ik “400 Bad Request”.

Hier is mijn klantcode:

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)

Hier is de servercode.

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())

Enig idee?


Antwoord 1, autoriteit 100%

Vanaf Requests versie 2.4.2 kunt u de json=parameter(waarvoor een woordenboek nodig is) in plaats van data=(waarvoor een string nodig is) in de aanroep:

>>> 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'}

Antwoord 2, autoriteit 31%

Het bleek dat ik de header-informatie miste. De volgende werken:

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)

Antwoord 3, autoriteit 6%

Van verzoeken 2.4.2 (https://pypi.python.org/pypi/requests), de ” json”-parameter wordt ondersteund. Het is niet nodig om “Content-Type” op te geven. Dus de kortere versie:

requests.post('http://httpbin.org/post', json={'test': 'cheers'})

Antwoord 4, autoriteit 3%

De betere manier is:

url = "http://xxx.xxxx.xx"
data = {
    "cardno": "6248889874650987",
    "systemIdentify": "s08",
    "sourceChannel": 12
}
resp = requests.post(url, json=data)

5

Werkt perfect met python 3.5 +

client:

import requests
data = {'sender':   'Alice',
    'receiver': 'Bob',
    'message':  'We did it!'}
r = requests.post("http://localhost:8080", 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'}

Antwoord 6

Het is altijd aanbevolen dat we de mogelijkheid moeten hebben om het JSON-bestand te lezen en een object te ontleden als een verzoektekst. We gaan de onbewerkte gegevens in het verzoek niet ontleden, dus de volgende methode zal u helpen om het op te lossen.

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

Other episodes