Использование POST и urllib2 для доступа к веб-API - PullRequest
6 голосов
/ 16 ноября 2010

Я пытаюсь получить доступ к веб-API, используя технику POST. Я могу получить к нему доступ, используя технику GET, но владельцы API говорят мне, что некоторые функции работают только с POST К сожалению, я не могу заставить работать POST.

Вот что работает с GET:

API_URL = "http://example.com/api/"

def call_api(method, **kwargs):
    url = API_URL + method
    if kwargs:
        url += '?' + urllib.urlencode(kwargs)
    req = urllib2.Request(url)
    auth = 'Basic ' + base64.urlsafe_b64encode("%s:%s" % (USER, PASS))
    req.add_header('Authorization', auth)
    return urllib2.urlopen(req)

Вот что НЕ работает с POST (вызывает ошибку HTTP 400):

API_URL = "http://example.com/api/"

def call_api(method, **kwargs):
    url = API_URL + method
    data=''
    if kwargs:
        data=urllib.urlencode(kwargs)
    req = urllib2.Request(url, data)
    auth = 'Basic ' + base64.urlsafe_b64encode("%s:%s" % (USER, PASS))
    req.add_header('Authorization', auth)
    return urllib2.urlopen(req)

Вызывает ли кто-нибудь что-нибудь неверное в коде POST? Я никогда не делал POST-вызовы раньше, но все, что я прочитал, говорит о том, что мой код разумен Есть ли другой способ, которым я должен делать add_header для авторизации, если я использую POST?

Ответы [ 3 ]

10 голосов
/ 16 ноября 2010

С urllib2 необходимо добавить данные в тело POST:

def call_api(method, **kwargs):
    url = API_URL + method
    req = urllib2.Request(url)

    if kwargs:
        req.add_data(urllib.urlencode(kwargs))

    auth = 'Basic ' + base64.urlsafe_b64encode("%s:%s" % (USER, PASS))
    req.add_header('Authorization', auth)

    # req.get_method() -> 'POST'

    return urllib2.urlopen(req)
2 голосов
/ 16 ноября 2010

Как отмечает @sneeu выше, добавление данных, подлежащих публикации в запрос, приводит к преобразованию запроса из GET в POST.

Однако это все еще предполагает, что то, что API ожидает получить в теле POST, представляет собой данные в кодированной форме. Многие более поздние API, с которыми я работал, ожидают чего-то еще (XML или JSON, чаще всего).

Можете ли вы проверить, что этот API ожидает получить в качестве полезных данных?

1 голос
/ 20 ноября 2012

Я столкнулся с той же проблемой, я хочу отправить данные с помощью метода POST HTTP, но после dir(req) я нашел get_method, но не set_method, и я также обнаружил, что есть свойство под названием data, так что попробуйте:

>>> req.data={"todototry":"123456"}
>>> req.get_method()
'POST'
>>>

Спасибо @ sneeu.

...