2010-01-02 18 views
20

Me gustaría convertir este comando curl a algo que pueda usar en Python para un script existente.Convertir una solicitud de POST curl a Python solo utilizando la biblioteca estándar

curl -u 7898678:X -H 'Content-Type: application/json' \ 
-d '{"message":{"body":"TEXT"}}' http://sample.com/36576/speak.json 

TEXTO es lo que me gustaría sustituir con un mensaje generado por el resto del guión (que ya está trabajando razonable, aunque no creo que se está siguiendo las mejores prácticas o particularidad fiable -.. Necesidad para saber cómo aprender correctamente a programar (es decir, no usar google para ensamblar cosas))

Me gustaría que esto funcione con la biblioteca estándar si es posible.

+1

Vaya aquí - http://stackoverflow.com/questions/4348061/how-to-use-python-urllib2-to-send-json- data-for-login/7469725 # 7469725 – treecoder

Respuesta

23

me gustaría que esto funcione con la biblioteca estándar, si es posible.

La biblioteca estándar proporciona urllib y httplib para trabajar con direcciones URL:

>>> import httplib, urllib 
>>> params = urllib.urlencode({'apple': 1, 'banana': 2, 'coconut': 'yummy'}) 
>>> headers = {"Content-type": "application/x-www-form-urlencoded", 
...   "Accept": "text/plain"} 
>>> conn = httplib.HTTPConnection("example.com:80") 
>>> conn.request("POST", "/some/path/to/site", params, headers) 
>>> response = conn.getresponse() 
>>> print response.status, response.reason 
200 OK 

Si desea ejecutar curl en sí, sin embargo, sólo puede invocar os.system():

import os 
TEXT = ... 
cmd = """curl -u 7898678:X -H 'Content-Type: application/json'""" \ 
    """-d '{"message":{"body":"%{t}"}}' http://sample.com/36576/speak.json""" % \ 
    {'t': TEXT} 

Si está dispuesto a relajar la restricción de solo biblioteca estándar, puede usar PycURL. Tenga en cuenta que no es muy Pythonic (es más o menos una chapa delgada sobre libcurl), y no estoy seguro de lo compatible que es con Python 3.

+0

Usar httplib significa omitir algunas de las funciones de urllib y urllib2, como soporte para proxies. –

+1

@dalke »Eso es verdad; esto es solo un ejemplo simple para hacer una solicitud 'GET' o' POST', que es lo que yo buscaba. –

+2

'es cierto.Acabo de descubrir que usar httplib y hacer munging de URL generalmente no vale la pena dado que urllib2 te ofrece todo eso y más. –

12

Si bien hay formas de manejar authentication in urllib2, si usted es al hacerlo básico de autorización (que significa el envío de forma efectiva el nombre de usuario y contraseña en texto claro), entonces usted puede hacer todo lo que quiera con un urllib2.Request y urllib2.urlopen:

import urllib2 

def basic_authorization(user, password): 
    s = user + ":" + password 
    return "Basic " + s.encode("base64").rstrip() 

req = urllib2.Request("http://localhost:8000/36576/speak.json", 
         headers = { 
     "Authorization": basic_authorization("7898678", "X"), 
     "Content-Type": "application/json", 

     # Some extra headers for fun 
     "Accept": "*/*", # curl does this 
     "User-Agent": "my-python-app/1", # otherwise it uses "Python-urllib/..." 
     }, 
         data = '{"message":{"body":"TEXT"}}') 

f = urllib2.urlopen(req) 

he probado esto con netcat por lo que pude Observe que los datos enviados fueron, excepto orden de clasificación, idénticos en ambos casos. Aquí, el primero de ellos se llevó a cabo con el enrollamiento y el segundo con urllib2

% nc -l 8000 
POST /36576/speak.json HTTP/1.1 
Authorization: Basic Nzg5ODY3ODpY 
User-Agent: curl/7.19.4 (universal-apple-darwin10.0) libcurl/7.19.4 OpenSSL/0.9.8k zlib/1.2.3 
Host: localhost:8000 
Accept: */* 
Content-Type: application/json 
Content-Length: 27 

{"message":{"body":"TEXT"}} ^C 

% nc -l 8000 
POST /36576/speak.json HTTP/1.1 
Accept-Encoding: identity 
Content-Length: 27 
Connection: close 
Accept: */* 
User-Agent: my-python-app/1 
Host: localhost:8000 
Content-Type: application/json 
Authorization: Nzg5ODY3ODpY 

{"message":{"body":"TEXT"}}^C 

(esto es ligeramente ajustado de la salida. Mi caso de prueba no utilizó la misma dirección URL que utilizó.)

No hay necesita usar el httplib subyacente, que no es compatible con las cosas que urllib2 le da como soporte de proxy. Por otro lado, encuentro que urllib2 es complicado fuera de este tipo de solicitud simple y si desea una mejor asistencia para qué encabezados se envían y el orden en que se envían, utilice httplib.

+0

gracias por el fragmento neto del gato – nkint

2

Gracias cada

esto funciona

import urllib2 

def speak(status): 

    def basic_authorization(user, password): 
     s = user + ":" + password 
     return "Basic " + s.encode("base64").rstrip() 

    req = urllib2.Request("http://example.com/60/speak.json", 
        headers = { 
     "Authorization": basic_authorization("2345670", "X"), 
    "Content-Type": "application/json", 


     "Accept": "*/*", 
     "User-Agent": "my-python-app/1", 
     }, 
         data = '{"message":{"body":'+ status +'}}') 

    f = urllib2.urlopen(req) 


speak('Yay') 
Cuestiones relacionadas