2010-01-02 9 views
20

Vorrei convertire questo comando di ricciolo in qualcosa che posso usare in Python per uno script esistente.Convertire una richiesta POST di arricciatura su Python usando solo la libreria standard

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

TEXT è quello che vorrei sostituire con un messaggio generato dal resto dello script (che sta già lavorando ragionevole, anche se io non credo che sta seguendo le migliori pratiche o particolarità affidabile -.. Bisogno per scoprire come apprendere correttamente per programmare (cioè non usare google per assemblare roba))

Mi piacerebbe che questo funzionasse con la libreria standard se possibile.

+1

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

risposta

23

Vorrei che questo per lavorare con la libreria standard, se possibile.

La libreria standard fornisce urllib e httplib per lavorare con gli 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 

Se si desidera eseguire curl stesso, però, si può semplicemente richiamare 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} 

Se sei disposto a rilassare la restrizione della sola libreria standard, puoi utilizzare PycURL. Attenzione che non è molto Pythonic (è praticamente solo un sottile strato su libcurl), e non sono sicuro di quanto sia compatibile con Python 3.

+0

Utilizzare httplib significa saltare alcune delle funzionalità da urllib e urllib2, come il supporto per i proxy. –

+1

@dalke »È vero; questo è solo un semplice esempio per fare una richiesta 'GET' o' POST', che è ciò che penso che l'OP era dopo. –

+2

è vero.Ho appena scoperto che l'utilizzo di httplib e l'esecuzione di URL munging non vale in genere lo sforzo dato che urllib2 offre tutto questo e altro. –

12

Mentre ci sono modi per gestire authentication in urllib2, se sei facendo base di autorizzazione (che significa in modo efficace l'invio del nome utente e la password in chiaro), allora si può fare tutto quello che vuoi con un urllib2.Request e 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) 

ho provato questo con netcat così ho potuto vedere che i dati inviati erano, salvo ordine di classificazione, identici in entrambi i casi. Ecco il primo è stato fatto con l'arricciatura e la seconda 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 

(Questo è leggermente ottimizzato dall'output. Il mio banco di prova non ha utilizzato lo stesso percorso URL che hai usato.)

Non c'è è necessario utilizzare il sottostante httplib, che non supporta le cose che urllib2 offre come supporto proxy. D'altra parte, trovo che urllib2 sia complicato al di fuori di questo semplice tipo di richiesta e se si desidera un supporto migliore per le intestazioni e l'ordine di invio, utilizzare httplib.

+0

grazie per il snippet di rete – nkint

2

Grazie ogni

questo funziona

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') 
Problemi correlati