पायथन अनुरोधों का उपयोग करके JSON पोस्ट करें


632

मुझे क्लाइंट से सर्वर तक एक JSON पोस्ट करने की आवश्यकता है। मैं पायथन 2.7.1 और सिंपलसन का उपयोग कर रहा हूं। क्लाइंट अनुरोधों का उपयोग कर रहा है। सर्वर चेरी है। मैं सर्वर से एक हार्ड-कोडेड JSON प्राप्त कर सकता हूं (कोड नहीं दिखाया गया है), लेकिन जब मैं सर्वर पर JSON पोस्ट करने की कोशिश करता हूं, तो मुझे "400 खराब अनुरोध" मिलता है।

यहाँ मेरा ग्राहक कोड है:

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)

यहाँ सर्वर कोड है।

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

कोई विचार?


मैं प्रलेखन से सीधे एक उदाहरण के एक छीन लिया गया संस्करण का उपयोग कर रहा था ।
चार्ल्स आर

मेरी टिप्पणी अभी भी खड़ी है - चेरीपी __init__एक contentतर्क के साथ वर्ग के तरीकों को नहीं बुलाता है (और आपके द्वारा आपूर्ति की गई लिंक में दावा नहीं करता है)। उनके पास विस्तृत उदाहरण में, उपयोगकर्ता उस कोड की आपूर्ति करता है जो कॉल __init__करता है और तर्क प्रदान करता है, जिसे हमने यहां नहीं देखा है इसलिए मुझे नहीं पता कि आपकी # this worksटिप्पणी प्रासंगिक होने पर आपकी वस्तु किस स्थिति में है।
निक बैस्टिन

1
क्या आप उस लाइन को देखने के लिए कह रहे हैं जहां इंस्टेंस बनाया गया है?
चार्ल्स आर

हाँ, मैं इसे परखने के लिए आपके उदाहरण को शुरू करने की कोशिश कर रहा था, और मुझे यकीन नहीं था कि आप इसे कैसे शुरू कर रहे हैं।
निक बैस्टिन

कोड बदल गया है। मैं अब इसे बिना अतिरिक्त तर्क के बना रहा हूं। cherrypy.quickstart(Root(), '/', conf)
चार्ल्स आर

जवाबों:


1051

अनुरोध संस्करण 2.4.2 और उसके बाद, आप वैकल्पिक रूप से कॉल में 'json' पैरामीटर का उपयोग कर सकते हैं जो इसे सरल बनाता है।

>>> 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: इस फीचर को आधिकारिक दस्तावेज में जोड़ा गया है। आप इसे यहाँ देख सकते हैं: अनुरोध प्रलेखन


114
मैं विश्वास नहीं कर सकता कि आपके जवाब पर ठोकर खाने से पहले मैंने कितना समय बर्बाद किया। अनुरोध डॉक्स, उन्नत करने की जरूरत वहाँ बिल्कुल पर कुछ भी नहीं है jsonपैरामीटर। इससे पहले कि मैं इसके बारे में कोई उल्लेख करता, मुझे Github में जाना पड़ता: github.com/kennethreitz/requests/blob/…
IAmKale

1
2.4.2 के रूप में अधिक मुहावरेदार होने के कारण इसे स्वीकृत उत्तर पर सेट करना। ध्यान रखें, पागल यूनिकोड के लिए, यह काम नहीं कर सकता है।
चार्ल्स आर

मैं @IAmKale के समान जूते में था। इससे मुझे AWS के एपीआई गेटवे के साथ होने वाले सिरदर्द से काफी राहत मिली है। यह डिफ़ॉल्ट रूप से JSON प्रारूप में POST डेटा की आवश्यकता है।
jstudios 3

1
एक मूर्ख की तरह मैंने आवेदन / डेटा के साथ डेटा पैरामीटर का उपयोग करने की कोशिश की सामग्री प्रकार :(
अवैध ऑपरेटर

मैंने इसका एक उदाहरण देखा कि तानाशाह वस्तु ले गए और भेजने से पहले json.dumps (ऑब्जेक्ट) का प्रदर्शन किया। ऐसा मत करो ... यह आपके JSON को गड़बड़ करता है। उपरोक्त एकदम सही है..आप इसे एक अजगर वस्तु के रूप में पारित कर सकते हैं और यह पूर्ण जसन में बदल जाता है।
MydKnight

376

यह पता चला कि मुझे हेडर की जानकारी याद आ रही थी। निम्नलिखित कार्य:

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)

अच्छा पकड़ - मैं अपने देखा application/jsonमें GETऔर किसी भी तरह याद है कि आप इसे अनुरोध पर नहीं दिया था। आपको यह भी सुनिश्चित करने की आवश्यकता हो सकती है कि आप कुछ वापस POSTकर दें या आपको मिल जाए 500
निक बैस्टिन

आवश्यक प्रतीत नहीं होता है। जब मैं प्रिंट करता हूं r, मुझे मिलता है <Response [200]>
चार्ल्स आर

मैं सर्वर पर इस json को कैसे पुनः प्राप्त करूँ?
वैद्यभिषेक

r = request.get (' लोकलहोस्ट: 8080' ) c = r.content रिजल्ट = simplejson.loads (c)
चार्ल्स आर

1
json.dumpsयहाँ उपयोग करने से पहले छोटे सिर । dataके पैरामीटर requestsशब्दकोशों के साथ काम करता है ठीक। स्ट्रिंग में परिवर्तित करने के लिए कोई ज़रूरत नहीं है।
अद्वैत एस

71

अनुरोध 2.4.2 ( https://pypi.python.org/pypi/requests ) से, "json" पैरामीटर समर्थित है। "सामग्री-प्रकार" निर्दिष्ट करने की आवश्यकता नहीं है। तो छोटा संस्करण:

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

29

बेहतर तरीका है :

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/jsonके रूप में अनावश्यक है json=पहले से ही है कि संकेत।
मोशे

1
@Moshe पूरी तरह से सहमत हैं, लेकिन नए संस्करण के लिए अनुरोध करने के लिए Content-type
एलेस्टिक्स

@Moshe, अगर कंटेंट टाइप हो तो क्या होगा text/html; charset=UTF-8। फिर ऊपर काम नहीं करेगा?
अनु

2
" बेहतर तरीका है " सही उत्तर के 3 साल बाद गलत जवाब पोस्ट नहीं करना है । -1
कॉन्विड

3

अजगर 3.5+ के साथ पूरी तरह से काम करता है

ग्राहक:

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

सर्वर:

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

(डेटा / json / files) के बीच कौन से पैरामीटर का उपयोग किया जाना चाहिए, यह वास्तव में ContentType नामक अनुरोध शीर्षलेख पर निर्भर करता है (आमतौर पर इसे अपने ब्राउज़र के डेवलपर टूल के माध्यम से जांचें)

जब सामग्री-प्रकार अनुप्रयोग / x-www-form-urlencoded है, तो कोड होना चाहिए:

requests.post(url, data=jsonObj)

जब सामग्री-प्रकार अनुप्रयोग / json है, तो आपका कोड नीचे एक होना चाहिए:

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

जब सामग्री-प्रकार मल्टीपार्ट / फ़ॉर्म-डेटा है, इसका उपयोग फ़ाइलों को अपलोड करने के लिए किया जाता है, इसलिए आपका कोड होना चाहिए:

requests.post(url, files=xxxx)

यीशु मसीह, धन्यवाद। मैं कुछ पल पहले अपने बालों को बाहर निकाल रही थी।
वाह्गन तुम्येन

खुशी है कि आप मदद कर सकते हैं
:)
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.