2010-11-16 10 views
6

Estoy intentando acceder a una API web utilizando una técnica POST. PUEDO acceder a él usando una técnica GET, pero los propietarios de API me dicen que cierta funcionalidad solo funciona con POST. Lamentablemente, parece que no puedo hacer funcionar el POST.Uso de POST y urllib2 para acceder a la API web

Aquí es lo que funciona 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) 

Aquí es lo que no funciona con la POST (causas de error 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) 

¿Hay algo que saltan a cualquier persona como inherentemente incorrecto en el Código POST? Nunca he hecho una llamada POST antes, pero todo lo que he leído parece sugerir que mi código es razonable. ¿Hay alguna forma diferente en que se supone que debo hacer el comando add_header para la autorización si estoy usando POST?

+1

Su código POST parece ser exactamente el mismo que su código GET. ¿Copiaste y pegaste algo incorrectamente? –

+0

¡Doh! Sí, hubo un error al pegar. Corregido ahora. – neomech

Respuesta

9

Con urllib2 es necesario agregar los datos al cuerpo 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

Tuve un error en mi pregunta donde no pegué mi código POST, pero como puede ver ahora es casi idéntico a lo que tiene aquí. Voy a ir y asumir que el problema se relaciona con la API y lo que está esperando, y no con mi código. – neomech

2

Como @sneeu notas anteriores, es el hecho de añadir los datos a ser publicado a la solicitud que convierte la solicitud de un GET en un POST.

Sin embargo, esto aún asume que lo que la API espera recibir en el cuerpo POST es información codificada en el formulario. Muchas API más recientes con las que he trabajado esperan algo más allí (XML o JSON, más comúnmente).

¿Puedes verificar qué espera recibir esa API como carga útil de datos?

+0

Basado en el código que he visto hasta ahora, creo que tienes razón ... el error es el resultado de que la API no espera lo que intento publicar. – neomech

1

me he enfrentado al mismo problema, quiero enviar datos con el método POST de HTTP, pero después de dir(req) He encontrado get_method, pero sin set_method, y también he encontrado que hay una propiedad llamada data, por lo que probar esto:

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

Gracias @sneeu.

Cuestiones relacionadas