2010-11-16 5 views
6

Sto tentando di accedere a un'API Web utilizzando una tecnica POST. Sono in grado di accedervi utilizzando una tecnica GET, ma i proprietari delle API mi dicono che certe funzionalità funzionano solo con POST. Sfortunatamente non riesco a far funzionare POST.Utilizzo di POST e urllib2 per accedere all'API Web

Ecco cosa funziona con 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) 

Ecco cosa non funziona con POST (causa errore 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) 

fa qualcosa saltare fuori a chiunque come intrinsecamente errato nel Codice POST? Non ho mai fatto una chiamata POST prima, ma tutto ciò che ho letto sembra suggerire che il mio codice è ragionevole. C'è un modo diverso in cui dovrei fare la cosa add_header per l'autorizzazione se sto usando POST?

+1

Il tuo codice POST sembra essere esattamente uguale al tuo codice GET. Hai copiato e incollato qualcosa in modo errato? –

+0

Doh! Sì, c'era un errore di incollatura. Risolto ora. – neomech

risposta

9

Con urllib2 è necessario aggiungere i dati al corpo 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

Ho avuto un errore nella mia domanda in cui non ho incollato il mio codice POST, ma come ora puoi vedere è quasi identico a quello che hai qui. Vado semplicemente ad assumere che il problema si riferisce all'API e a cosa si aspetta, e non al mio codice. – neomech

2

Come @sneeu note sopra, è l'atto di aggiungere i dati per essere pubblicato alla richiesta che converte la richiesta da un GET in un POST.

Tuttavia, ciò presuppone comunque che ciò che l'API si aspetta di ricevere nel corpo del POST sia i dati codificati in forma. Molte API più recenti con cui ho lavorato si aspettano qualcosa di diverso (XML o JSON, più comunemente).

Puoi verificare che cosa si aspetta che l'API riceva come carico utile di dati?

+0

Sulla base del codice che ho visto finora, penso che tu abbia ragione ... l'errore è il risultato dell'API che non si aspetta quello che sto tentando di pubblicare. – neomech

1

Ho affrontato lo stesso problema, voglio inviare i dati con il metodo POST di HTTP, ma dopo dir(req) ho trovato get_method, ma non set_method, e ho anche trovato v'è una proprietà chiamata data, in modo da provare questo fuori:

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

Grazie @sneeu.