2010-11-16 18 views
6

J'essaie d'accéder à une API Web à l'aide d'une technique POST. Je suis capable d'y accéder en utilisant une technique GET, mais les propriétaires d'API me disent que certaines fonctionnalités ne fonctionnent qu'avec POST. Malheureusement, je n'arrive pas à faire fonctionner le POST.Utilisation de POST et d'urllib2 pour accéder à l'API Web

est ici ce qui fonctionne avec 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) 

Voici ce qui ne fonctionne pas avec POST (provoque une erreur 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) 

ne fait rien sauter à tout le monde comme étant intrinsèquement incorrect dans le Code POST? Je n'ai jamais fait un appel POST avant, mais tout ce que j'ai lu semble suggérer que mon code est raisonnable. Existe-t-il une façon différente que je suis censé faire la chose add_header pour l'autorisation si j'utilise POST?

+1

Votre code POST semble être exactement le même que votre code GET. Avez-vous copié et collé quelque chose de façon incorrecte? –

+0

Doh! Oui, il y a eu une erreur de collage. Fixé maintenant – neomech

Répondre

9

Avec urllib2 vous devez ajouter les données au corps 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) 
+0

J'ai eu une erreur dans ma question où je n'ai pas collé mon code POST, mais comme vous pouvez le voir maintenant, c'est presque identique à ce que vous avez ici. Je vais juste partir et supposer que le problème se rapporte à l'API et à ce qu'elle attend, et pas avec mon code. – neomech

2

Comme @sneeu notes ci-dessus, il est l'acte d'ajouter les données à envoyer à la demande qui convertit la demande d'un GET dans un POST. Toutefois, cela suppose toujours que l'API s'attend à recevoir dans le corps POST des données codées par formulaire. Beaucoup d'API plus récentes avec lesquelles j'ai travaillé attendent autre chose (XML ou JSON, le plus souvent).

Pouvez-vous vérifier ce que cette API s'attend à recevoir en tant que données utiles?

+0

Basé sur le code que j'ai vu jusqu'ici, je pense que vous avez raison ... l'erreur est le résultat de l'API n'attendant pas ce que j'essaie de publier. – neomech

1

J'ai fait face au même problème, je veux envoyer des données avec la méthode POST du protocole HTTP, mais après dir(req) j'ai trouvé get_method, mais pas set_method, et je trouve aussi qu'il ya une propriété appelée data, alors essayez ceci:

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

Merci @sneeu.