Python İsteklerini kullanarak JSON yayınlayın


633

Bir istemciden bir sunucuya bir JSON POST gerekir. Python 2.7.1 ve simplejson kullanıyorum. İstemci İstekleri kullanıyor. Sunucu CherryPy'dir. Sabit kodlu bir JSON sunucudan (kod gösterilmiyor) GET, ancak sunucuya bir JSON POST çalıştığınızda, "400 Hatalı İstek" olsun.

İşte müşteri kodum:

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)

İşte sunucu kodu.

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

Herhangi bir fikir?


Ben doğrudan bir belge çıktı elden bir örnek kullanıyordum .
Charles R

Benim yorumum hala duruyor - CherryPy __init__bir contentargümanla sınıf yöntemlerini çağırmıyor (ve sağladığınız bağlantıda iddia etmiyor). Sahip oldukları ayrıntılı örnekte, kullanıcı __init__, burada görmediğimiz argümanları çağıran ve sağlayan kodu sağlar, böylece # this worksyorumunuz alakalı olduğunda nesnenizin hangi durumda olduğunu bilmiyorum .
Nick Bastin

1
Örneğin oluşturulduğu satırı görmek istiyor musunuz?
Charles R

evet, test etmek için örneğinizi başlatmaya çalışıyordum ve nasıl örneklediğinizden emin değildim.
Nick Bastin

Kod değişti. Şimdi bunu ekstra argüman olmadan oluşturuyorum. cherrypy.quickstart(Root(), '/', conf).
Charles R

Yanıtlar:


1053

İstekler sürüm 2.4.2 ve sonrası için, alternatif olarak çağrıda 'json' parametresini kullanabilirsiniz.

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

EDIT: Bu özellik resmi belgelere eklendi. Burada görüntüleyebilirsiniz: Talep belgeleri


114
Cevabınızı tökezlemeden önce ne kadar zaman harcadığımıza inanamıyorum. İstekleri dokümanlar üzerinde kesinlikle hiçbir şey yok, yükseltilmesi gerekir jsonparametresi. Bundan bahsetmeden önce Github'a
IAmKale

1
2.4.2 itibarıyla daha deyimsel olduğu için bunu kabul edilen cevaba ayarlamak. Unutmayın, çılgın unicode için bu işe yaramayabilir.
Charles R

@IAmKale ile aynı ayakkabılardaydım. Bu AWS'nin API Ağ Geçidi ile yaşadığım baş ağrısını hafifletti. Varsayılan olarak, POST verilerini JSON biçiminde gerektirir.
jstudios

1
Aptal gibi data parametresini application / json ile içerik türünü kullanmaya çalıştım :(
Yasadışı Operatör

Dict nesnesini alan ve göndermeden önce json.dumps (nesne) gerçekleştiren bir örnek gördüm. Bunu yapma ... JSON'unu bozar. Yukarıdaki mükemmel .. bir python nesnesi geçebilir ve mükemmel json dönüşür.
MydKnight

376

Başlık bilgisini kaçırdığım ortaya çıktı. Aşağıdaki işler:

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)

İyi yakalamak - Ben senin gördüğünü application/jsonin GETve bir şekilde istek üzerine sağlanan olmadığını kaçırdı. Ayrıca, bir şeyleri iade ettiğinizden emin POSTolmanız gerekebilir veya a 500.
Nick Bastin

Gerekli görünmüyor. Ben yazdırırken r, benim hemen <Response [200]>.
Charles R

Sunucu tarafında bu json nasıl alabilirim?
VaidAbhishek

r = requests.get (' localhost: 8080' ) c = r.içerik sonucu = simplejson.loads (c)
Charles R

1
json.dumpsBurada kullanmadan önce küçük kafalar . dataParametre requestssözlükleri eserler cezası. Bir dizeye dönüştürmeye gerek yoktur.
Advait S

71

2.4.2 isteklerinden ( https://pypi.python.org/pypi/requests ), "json" parametresi desteklenir. "İçerik Türü" belirtmeye gerek yoktur. Yani daha kısa versiyon:

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

29

Daha iyi bir yol :

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)

18
Content-type: application/jsonolarak gereksiz json=zaten ima etmektedir.
Moshe

1
@Moshe tamamen katılıyorum, ancak daha yeni bir versiyon talep etmek için Content-type
Elasticsearch

@Moshe, Ne içerik türü ise text/html; charset=UTF-8. O zaman yukarıdaki işe yaramaz mı?
Anu

2
" Daha iyi yol " , doğru bir cevaptan 3 yıl sonra YANLIŞ cevaplar göndermemektir . -1
CONvid19

3

Python 3.5+ ile mükemmel çalışır

müşteri:

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

sunucu:

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

3

(Data / json / files) arasındaki hangi parametre kullanılmalıdır, aslında ContentType adlı bir istek başlığına bağlıdır (genellikle bunu tarayıcınızın geliştirici araçlarıyla kontrol edin),

İçerik Türü application / x-www-form-urlencoded olduğunda kod şöyle olmalıdır:

requests.post(url, data=jsonObj)

İçerik Türü application / json olduğunda, kodunuzun aşağıdakilerden biri olması gerekir:

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

İçerik Türü çok bölümlü / form verileri olduğunda, dosya yüklemek için kullanılır, bu nedenle kodunuz şöyle olmalıdır:

requests.post(url, files=xxxx)

Tanrım, teşekkürler. Birkaç dakika önce saçlarımı fırlatıyordum.
Vahagn Tumanyan

size yardımcı olabilir sevindim
:)
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.