2011-12-15 41 views
8

Tôi đang phát xung quanh với API Google Checkout và tôi muốn kéo nó vào một ứng dụng Django. Tôi cần đăng dữ liệu lên Google bằng cách sử dụng xác thực http cơ bản. Tôi đã thử nghiệm điều này với curl như thế này:Đăng dữ liệu thô với Python

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

Và đăng nội dung của tệp XML thử nghiệm của tôi lên Google. Và nó hoạt động tốt!

Nhưng tôi đang gặp sự cố khi chuyển dòng đơn giản đó sang Python. Tôi đã quản lý một số cách khác nhau (httplib2, urllib2, pycurl) của kết nối với một mật khẩu và gửi một cái gì đó nhưng respose luôn luôn là 400 BAD YÊU CẦU.

Có tương đương python để đăng khối văn bản lên máy chủ auth HTTP cơ bản không? Tôi đang chạy ra khỏi tường để đập đầu vào.


Xin lỗi vì không thêm bất kỳ mã nào. Đây là một số hit lớn nhất của tôi. Trong mỗi, DATA là một chuỗi XML. URL, USERNAMEPASSWORD là hằng số.

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

Cung cấp cho tôi một đáng yêu 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) 

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

vẻ đấu tranh với đi qua các chuỗi DATA như một POSTFIELD . Tôi đã thử urllib.urlencode() ing DATA trong nhiều cách khác nhau nhưng


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

Các thông tin dường như không làm gì cả - tôi nhận được một thông báo không được phép trở lại từ Google.

Có nhiều hơn nhưng tất cả đều dựa trên những điều này.

Trả lời

12

Tôi đã có các turmoils tương tự với các gói stdlib, cho đến khi người nào đó trỏ đến tuyệt vời requests hỗ trợ Xác thực HTTP cơ bản và xác thực khác có nghĩa là thẳng ra khỏi hộp! Và nó có một API đẹp và đơn giản, nó đau!

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

Nó hỗ trợ một loạt các tính năng cần thiết khác (ví dụ HTTPS, Digest Authentication, vv) Xin vui lòng kiểm tra xem nó ra nếu u phải ...

2

Khoảng trắng có an excellent article khi sử dụng auth cơ bản với urllib2. Tôi đã sao chép đoạn mã thích hợp bên dưới, đã thay đổi để sử dụng POST.

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

Nếu không thấy mã, bạn khó có thể nói lý do bạn nhận được phản hồi 400.

+0

Tôi đồng ý! Rất khó để biết những gì tôi đã cố gắng nếu tôi không nói với bạn. Lời xin lỗi của tôi. Tôi đã có các nhóm chính của phương pháp bây giờ (tôi có thể có khoảng 5 hoán vị cho mỗi "phương pháp"). Với phương pháp này, nó không cho phép. Có vẻ như Trình quản lý mật khẩu không hoạt động. Nhưng tôi đã cố định 'httplib2' ngay bây giờ (như được đăng) vì vậy hy vọng sẽ không phải sử dụng phương pháp khác cho việc này. – Oli

2

Trong khi chỉnh sửa bài viết của tôi bao gồm một số nguồn, tôi nghĩ rằng tôi muốn có vết nứt khác tại (chủ yếu là bởi vì nó tương đối nhỏ và khá so với những người khác) và nhận thấy rằng có a gaping bug ở chỗ phương pháp add_credentials(..) nó không thực sự làm bất cứ gì. Bạn có thể giải quyết vấn đề này bằng cách chỉ định tiêu đề (như tôi đã làm với urllib2) như sau:

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

Và công trình này hoạt động.

Các vấn đề liên quan