2012-03-16 19 views
288

Potrzebuję POST JSON od klienta do serwera. Używam Python 2.7.1 i simplejson. Klient korzysta z Żądań. Serwerem jest CherryPy. Mogę pobrać kod JSON z serwera (kod nie jest wyświetlany), ale kiedy próbuję POST JSON do serwera, otrzymuję "400 Bad Request".Wysyłanie JSON przy użyciu żądań Python

Oto mój kod klienta:

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) 

Oto kod serwera.

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

Wszelkie pomysły?

+0

Użyłem uproszczonej wersji przykładu prosto z [documentation] (http://docs.cherrypy.org/dev/progguide/REST.html). –

+0

Mój komentarz nadal się utrzymuje - CherryPy nie wywołuje metod klasy "__init__" z argumentem "content" (i nie roszczeń do linku, który podasz). W szczegółowym przykładzie, który ma, użytkownik dostarcza kod, który wywołuje '__init__' i dostarcza argumenty, których nie widzieliśmy tutaj, więc nie mam pojęcia, w jakim stanie jest twój obiekt, kiedy twój komentarz # # this works} jest istotny. –

+1

Czy chcesz wyświetlić wiersz, w którym tworzona jest instancja? –

Odpowiedz

434

Jak wniosków wersji 2.4.2 i dalej, można alternatywnie użyć parametru „json” w zaproszeniu, które sprawia, że ​​prostsze.

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

EDYCJA: Ta funkcja została dodana do oficjalnej dokumentacji. Możesz go zobaczyć tutaj: Requests documentation

+36

Nie mogę uwierzyć, ile czasu zmarnowałem przed potknięciem się o twoją odpowiedź. Dokumenty ** requests ** muszą zostać zaktualizowane, nie ma absolutnie nic w parametrze 'json'. Musiałem wejść na Github zanim zobaczyłem jakąkolwiek wzmiankę o tym: https://github.com/kennethreitz/requests/blob/76f7ce8a249e57df5ed1f2331a43e635895bdbba/requests/api.py – IAmKale

+1

Ustawienie tej opcji na zaakceptowaną odpowiedź, ponieważ jest bardziej idiomatyczna od wersji 2.4 .2. Pamiętaj, że w przypadku zwariowanego unicode może to nie działać. –

+0

Byłem w tych samych butach co @IAmale. Zmniejszyło to dość ból głowy jaki miałem z bramką API AWS. Wymaga to domyślnie danych POST w formacie JSON. – jstudios

250

Okazuje się, że brakowało mi informacji w nagłówku. Następujące prace:

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) 
+0

Dobry połów - widziałem twoje 'application/json' w' GET' i jakoś brakowało ci, że nie dostarczyłeś go na żądanie. Możesz również upewnić się, że zwrócisz coś z 'POST' lub otrzymasz' 500'. –

+0

Nie wydaje się konieczne. Kiedy wypisuję 'r', otrzymuję' '. –

+0

Jak mogę pobrać ten json po stronie serwera? – VaidAbhishek

35

Z żądań 2.4.2 (https://pypi.python.org/pypi/requests) jest obsługiwany parametr "json". Nie trzeba określać "Content-Type". Zatem krótsza wersja:

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

Działa to idealny dla Pythona w wersji 3.5, Jeśli adres URL zawiera Query String wartość/parametr

Zapytanie URL = https://bah2.com/ws/rest/v1/concept/

Wartość parametru = 21f6bb43-98a1- 419d-8f0c-8133669e40ca

import requests 
r = requests.post('https://bah2.com/ws/rest/v1/concept/21f6bb43-98a1-419d-8f0c-8133669e40ca',auth=('username', 'password'),verify=False, json={"name": "Value"}) 
headers = {'Content-type': 'application/json'} 
print(r.status_code) 
0

doskonale współpracuje z pytona 3.5+

klient:

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

Lepszym sposobem jest:

url = "http://xxx.xxxx.xx" 

datas = {"cardno":"6248889874650987","systemIdentify":"s08","sourceChannel": 12} 

headers = {'Content-type': 'application/json'} 

rsp = requests.post(url, json=datas, headers=headers) 
+0

'Content-type: application/json' jest nadmiarowy, ponieważ już to wskazuje na' json = '. – Moshe

0

Zmień swoją wersję PIP.

sudo pip3 install --upgrade requests 
+0

To nie uaktualnia wersji pip, to uaktualnia bibliotekę -U, --upgrade Uaktualnij wszystkie określone pakiety do najnowszej dostępnej wersji. Obsługa zależności zależy od zastosowanej strategii aktualizacji. –

Powiązane problemy