2011-12-15 3 views
8

के साथ कच्चे डेटा पोस्ट करना मैं Google Checkout API के साथ खेल रहा हूं और मैं इसे Django ऐप में खींचना चाहता हूं। मुझे बुनियादी http प्रमाणीकरण का उपयोग करके Google को डेटा पोस्ट करने की आवश्यकता है। मैं curl इस तरह के साथ इस परीक्षण किया गया है:पायथन

curl -d "$(cat mytest.xml)" -u username:password https://url 

और वह पदों गूगल के अपने परीक्षण एक्सएमएल फ़ाइल की सामग्री। और यह ठीक काम करता है!

लेकिन मुझे पाइथन के लिए उस साधारण रेखा को पोर्ट करने में समस्याएं आ रही हैं। मैंने पासवर्ड से कनेक्ट करने और कुछ पोस्ट करने के कई अलग-अलग तरीकों (httplib2, urllib2, pycurl) प्रबंधित किए हैं लेकिन राहत हमेशा 400 बीएडी अनुरोध है।

क्या HTTP मूल ऑथ सर्वर पर पाठ के ब्लॉक को पोस्ट करने के लिए कोई अजगर बराबर है? मैं अपने सिर को धक्का देने के लिए दीवारों से बाहर भाग रहा हूं।


कोई कोड जोड़ने के लिए क्षमा नहीं। यहां मेरी कुछ सबसे बड़ी हिट हैं। प्रत्येक में, DATA एक एक्सएमएल स्ट्रिंग है। URL, USERNAME और PASSWORD स्थिर हैं।

req = urllib2.Request(URL) 
req.add_header("Authorization", "Basic %s" % base64.encodestring('%s:%s'%(USERNAME, PASSWORD))) 
u = urllib2.urlopen(req, DATA) 

मुझे देता है एक सुंदर HTTP Error 400: Bad Request


passman = urllib2.HTTPPasswordMgrWithDefaultRealm() 
passman.add_password(None, URL, USERNAME, PASSWORD) 
authhandler = urllib2.HTTPBasicAuthHandler(passman) 
opener = urllib2.build_opener(authhandler) 
urllib2.install_opener(opener) 
pagehandle = urllib2.urlopen(URL, DATA) 

देता HTTP Error 401: Unauthorized


pycurl.global_init(pycurl.GLOBAL_DEFAULT) 
c = pycurl.Curl() 
c.setopt(pycurl.URL, URL) 
c.setopt(pycurl.USERPWD, "%s:%s" % (USERNAME,PASSWORD)) 
c.setopt(pycurl.POST, 1) 
c.setopt(pycurl.HTTPHEADER, ["Content-type: text/xml"]) 
c.setopt(pycurl.POSTFIELDS, DATA) 
b = StringIO.StringIO() 
c.setopt(pycurl.WRITEFUNCTION, b.write) 
c.perform() 

एक POSTFIELD रूप DATA स्ट्रिंग गुजर के साथ संघर्ष लगता है । मैं कोशिश की है कई अलग अलग तरीकों urllib.urlencode() आईएनजी डेटा लेकिन


h = httplib2.Http() 
h.add_credentials(USERNAME, PASSWORD) 
print = h.request(URL, "POST", body=base64.encodestring(DATA)) 

साख कुछ भी करने को नहीं है - मैं एक अनाधिकृत संदेश Google से वापस मिलता है।

और भी कुछ हैं लेकिन वे सभी इन पर आधारित हैं।

उत्तर

12

मुझे stdlib संकुल के साथ समान उथल-पुथल हो रही है, जब तक कि सोमोन ने भयानक requests की ओर इशारा किया जो मूल एचटीपी प्रमाणीकरण और अन्य प्रमाणीकरण का समर्थन करता है, सीधे बाहर के बॉक्स का मतलब है! और यह एक सुंदर और सरल एपीआई है दर्द होता है!

requests.post(url, data=DATA, headers=HEADERS_DICT, auth=(username, password)) 

यह अन्य आवश्यक सुविधाओं के एक मेजबान का समर्थन करता है (उदाहरण, HTTPS, डाइजेस्ट प्रमाणीकरण, आदि) यदि u चाहिए कृपया इसकी जांच करें बाहर ...

2

वॉयडस्पेस में urllib2 के साथ मूल लेख का उपयोग करने पर an excellent article है। मैंने नीचे उचित कोड स्निपेट की प्रतिलिपि बनाई है, पोस्ट का उपयोग करने के लिए बदल दिया है।

import urllib2 

theurl = 'http://www.someserver.com/toplevelurl/somepage.htm' 
username = 'johnny' 
password = 'XXXXXX' 

passman = urllib2.HTTPPasswordMgrWithDefaultRealm() 
passman.add_password(None, theurl, username, password) 

authhandler = urllib2.HTTPBasicAuthHandler(passman) 

opener = urllib2.build_opener(authhandler) 

urllib2.install_opener(opener) 

pagehandle = urllib2.urlopen(theurl, open("mytext.xml").read()) 

अपना कोड देखे बिना यह कहना मुश्किल है कि आपको 400 प्रतिक्रिया क्यों मिल जाएगी।

+0

मैं मानता हूँ! अगर मैं आपको नहीं बताता तो मैंने यह जानना बहुत मुश्किल है कि मैंने क्या किया है। मैं क्षमाप्रार्थी हूं। मेरे पास अब विधियों के मुख्य समूह हैं (मुझे शायद प्रत्येक "विधि" के लिए लगभग 5 क्रमपरिवर्तन मिले हैं)। इस विधि के साथ यह अधिकृत नहीं था। ऐसा नहीं लगता था कि पासवर्ड मैनेजर कुछ भी कर रहा था। लेकिन मैंने अब 'httplib2' तय किया है (जैसा कि पोस्ट किया गया है) तो उम्मीद है कि इसके लिए किसी अन्य विधि का उपयोग नहीं करना पड़ेगा। – Oli

2

मेरी पोस्ट को संपादित करने के लिए कुछ स्रोत शामिल करने के लिए करते हैं, मैंने सोचा कि मैं में एक और दरार होगा (यह अपेक्षाकृत छोटा और बहुत दूसरों की तुलना है जिसका मुख्य कारण) और पाया है कि इसके add_credentials(..) विधि वास्तव में नहीं है में a gaping bug यह है कि कुछ भी करो। आप इस तरह हैडर निर्दिष्ट करके इस के आसपास काम कर सकते हैं (जैसा कि मैंने urllib2 के साथ किया था):

resp, content = httplib2.Http().request(URL, "POST", body=DATA, headers={ 
    "Authorization": "Basic %s" % base64.encodestring('%s:%s' %(USERNAME, PASSWORD) 
}) 

और यह काम करता है।