Публикация необработанных данных с помощью Python - PullRequest
9 голосов
/ 15 декабря 2011

Я играю с Google Checkout API и хочу использовать его в приложении Django.Мне нужно отправить данные в Google, используя обычную http-аутентификацию.Я проверял это с помощью curl, например:

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

И это отправляет содержимое моего тестового XML-файла в Google.И это прекрасно работает!

Но у меня проблемы с переносом этой простой строки на Python.Мне удалось несколькими различными способами (httplib2, urllib2, pycurl) соединиться с паролем и опубликовать что-либо, но Respose всегда 400 BAD REQUEST.

Есть ли эквивалент Python для отправки блока текста в HTTPОсновной сервер аутентификации?У меня кончаются стены, чтобы биться головой.


Извиняюсь за то, что не добавил никакого кода.Вот некоторые из моих лучших хитов.В каждом DATA является строкой XML.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()

Кажется, что борьба с передачей строки DATA как POSTFIELD.Я пытался urllib.urlencode() использовать данные несколькими различными способами, но


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

Кажется, что учетные данные ничего не делают - я получаю несанкционированное сообщение от Google.

Есть и другие, но все они основаны на них.

Ответы [ 3 ]

12 голосов
/ 14 мая 2012

У меня были похожие проблемы с пакетами stdlib, пока somoneone не указал на удивительные запросы , которые поддерживают базовую аутентификацию Http и другие средства аутентификации прямо из коробки! И у него красивый и простой API, это больно!

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

Он поддерживает множество других необходимых функций (например, HTTPS, дайджест-аутентификация и т. Д.). Пожалуйста, проверьте его, если нужно ...

2 голосов
/ 15 декабря 2011

При редактировании моего поста, чтобы включить некоторый источник, я подумал, что у меня будет еще один треск на httplib2 (главным образом потому, что он сравнительно небольшой и симпатичный по сравнению с другими) и заметил, что зияющая ошибка в этом его add_credentials(..) метод фактически ничего не делает. Вы можете обойти это, указав заголовок (как я сделал с urllib2) следующим образом:

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

И это работает.

2 голосов
/ 15 декабря 2011

В Voidspace есть отличная статья об использовании базовой аутентификации с urllib2. Я скопировал соответствующий фрагмент кода ниже и изменил его на использование 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())

Не видя ваш код, трудно сказать, почему вы получили бы ответ 400.

...