Alternativa CURL in Python


114

Ho una chiamata cURL che uso in PHP:

curl -i -H 'Accept: application / xml' -u login: key " https://app.streamsend.com/emails "

Ho bisogno di un modo per fare la stessa cosa in Python. Esiste un'alternativa a cURL in Python. Conosco urllib ma sono un noob di Python e non ho idea di come usarlo.


2
Puoi provare pycurl
ghostdog74

2
urllib2 è un pacchetto ampiamente utilizzato per questo tipo di lavoro.
Saurav


3
Quanto sopra è un collegamento per una grande libreria per eseguire semplici http requestsin python (disponibile per l'installazione tramite easy_install o pip in PyPi). Il nome / URL è un po 'confuso: all'inizio ho quasi pensato che fosse una richiesta di lista dei desideri per una libreria migliore urllib2, invece requestsmolto intuitiva e facile da usare sudo easy_install requestso sudo pip install requests.
dr jimbob

Richieste Python e prestazioni PyCurl Sei decente secondo le tue esigenze
Santhosh

Risposte:


68
import urllib2

manager = urllib2.HTTPPasswordMgrWithDefaultRealm()
manager.add_password(None, 'https://app.streamsend.com/emails', 'login', 'key')
handler = urllib2.HTTPBasicAuthHandler(manager)

director = urllib2.OpenerDirector()
director.add_handler(handler)

req = urllib2.Request('https://app.streamsend.com/emails', headers = {'Accept' : 'application/xml'})

result = director.open(req)
# result.read() will contain the data
# result.info() will contain the HTTP headers

# To get say the content-length header
length = result.info()['Content-Length']

La tua chiamata cURL utilizzando invece urllib2. Completamente non testato.


4
È bello confrontare questo con la risposta sotto e vedere quanto è progredito Python negli ultimi quattro anni
Razi Shaban

133

È possibile utilizzare le richieste HTTP descritte nella guida utente Richieste: HTTP per esseri umani .


2
Le richieste sono le ultime e le migliori! Fuma e brucia il goffo urllib2, vorrei che le richieste diventassero client HTTP standard per le versioni 3.x in arrivo di python
Phyo Arkar Lwin

1
Quando sono passato a utilizzare le richieste non ho mai più guardato indietro a utilizzare direttamente urllib2. Anche la decodifica JSON integrata è utile. Non è necessario caricare manualmente il corpo con json se è impostato il tipo di contenuto appropriato.
Thomas Farvour

Le richieste sono così semplici. Sono stato persino in grado di creare uno schema di autenticazione personalizzato in pochi minuti. urllib2 è super fastidioso.
Doug

35

Ecco un semplice esempio che utilizza urllib2 che esegue un'autenticazione di base sull'API di GitHub.

import urllib2

u='username'
p='userpass'
url='https://api.github.com/users/username'

# simple wrapper function to encode the username & pass
def encodeUserData(user, password):
    return "Basic " + (user + ":" + password).encode("base64").rstrip()

# create the request object and set some headers
req = urllib2.Request(url)
req.add_header('Accept', 'application/json')
req.add_header("Content-type", "application/x-www-form-urlencoded")
req.add_header('Authorization', encodeUserData(u, p))
# make the request and print the results
res = urllib2.urlopen(req)
print res.read()

Inoltre, se lo racchiudi in uno script e lo esegui da un terminale, puoi reindirizzare la stringa di risposta a "mjson.tool" per abilitare la stampa carina.

>> basicAuth.py | python -mjson.tool

Un'ultima cosa da notare, urllib2 supporta solo le richieste GET e POST.
Se devi utilizzare altri verbi HTTP come DELETE, PUT, ecc., Probabilmente vorrai dare un'occhiata a PYCURL


Perché è stato bocciato? Forse perché hai scritto PYCURL invece di PycURL: D
Bhargav Rao

20

Se stai usando un comando per chiamare semplicemente curl in questo modo, puoi fare la stessa cosa in Python con subprocess. Esempio:

subprocess.call(['curl', '-i', '-H', '"Accept: application/xml"', '-u', 'login:key', '"https://app.streamsend.com/emails"'])

Oppure potresti provare PycURL se vuoi averlo come api più strutturato come quello che ha PHP.


No. La chiamata cURL fa parte di un programma. Se potessi pubblicare il codice che fa la stessa identica cosa nella chiamata curl sopra, sarebbe fantastico.
Gaurav Sharma

Aggiunto un esempio di cosa intendevo usando sottoprocesso basato sulla tua domanda, ma immagino che tu stia cercando qualcosa di più simile a PycURL.
unholysampler

So che è più vecchio, ma PycURL è un livello piuttosto basso per la maggior parte degli usi di cURL secondo me. Anche l'implementazione PHP di cURL è di livello piuttosto basso.
Thomas Farvour

Ottengo "errore di nome, sottoprocesso di nome non definito" dopo aver chiamato "python" da cmd e quindi essere nell'env python.
Timo

@Timo l'hai fatto import subprocess? L'ambiente Python repl è proprio come un file Python, devi importare gli altri moduli.
unholysampler

13
import requests

url = 'https://example.tld/'
auth = ('username', 'password')

r = requests.get(url, auth=auth)
print r.content

Questo è il modo più semplice in cui sono riuscito a ottenerlo.


Questa è la risposta più semplice! urllib2è eccessivamente complicato.
not2qubit

7

Qualche esempio, come usare urllib per queste cose, con un po 'di sintassi di zucchero. Conosco richieste e altre librerie, ma urllib è una libreria standard per Python e non richiede l'installazione separata di nulla.

Compatibile con Python 2/3.

import sys
if sys.version_info.major == 3:
  from urllib.request import HTTPPasswordMgrWithDefaultRealm, HTTPBasicAuthHandler, Request, build_opener
  from urllib.parse import urlencode
else:
  from urllib2 import HTTPPasswordMgrWithDefaultRealm, HTTPBasicAuthHandler, Request, build_opener
  from urllib import urlencode


def curl(url, params=None, auth=None, req_type="GET", data=None, headers=None):
  post_req = ["POST", "PUT"]
  get_req = ["GET", "DELETE"]

  if params is not None:
    url += "?" + urlencode(params)

  if req_type not in post_req + get_req:
    raise IOError("Wrong request type \"%s\" passed" % req_type)

  _headers = {}
  handler_chain = []

  if auth is not None:
    manager = HTTPPasswordMgrWithDefaultRealm()
    manager.add_password(None, url, auth["user"], auth["pass"])
    handler_chain.append(HTTPBasicAuthHandler(manager))

  if req_type in post_req and data is not None:
    _headers["Content-Length"] = len(data)

  if headers is not None:
    _headers.update(headers)

  director = build_opener(*handler_chain)

  if req_type in post_req:
    if sys.version_info.major == 3:
      _data = bytes(data, encoding='utf8')
    else:
      _data = bytes(data)

    req = Request(url, headers=_headers, data=_data)
  else:
    req = Request(url, headers=_headers)

  req.get_method = lambda: req_type
  result = director.open(req)

  return {
    "httpcode": result.code,
    "headers": result.info(),
    "content": result.read()
  }


"""
Usage example:
"""

Post data:
  curl("http://127.0.0.1/", req_type="POST", data='cascac')

Pass arguments (http://127.0.0.1/?q=show):
  curl("http://127.0.0.1/", params={'q': 'show'}, req_type="POST", data='cascac')

HTTP Authorization:
  curl("http://127.0.0.1/secure_data.txt", auth={"user": "username", "pass": "password"})

La funzione non è completa e forse non è l'ideale, ma mostra una rappresentazione e un concetto di base da utilizzare. Altre cose potrebbero essere aggiunte o modificate in base al gusto.

Aggiornamento 12/08

Ecco un collegamento a GitHub per una fonte aggiornata in tempo reale. Attualmente supporta:

  • autorizzazione

  • Compatibile con CRUD

  • rilevamento automatico del set di caratteri

  • rilevamento automatico della codifica (compressione)


4

Se sta eseguendo tutto quanto sopra dalla riga di comando che stai cercando, allora ti consiglio HTTPie . È una fantastica alternativa a cURL ed è super facile e conveniente da usare (e personalizzare).

Ecco la sua descrizione (succinta e precisa) da GitHub;

HTTPie (pronunciato aych-tee-tee-pie) è un client HTTP da riga di comando. Il suo obiettivo è rendere l'interazione della CLI con i servizi web il più possibile a misura d'uomo.

Fornisce un semplice comando http che consente di inviare richieste HTTP arbitrarie utilizzando una sintassi semplice e naturale e visualizza l'output colorato. HTTPie può essere utilizzato per testare, eseguire il debug e generalmente interagire con i server HTTP.


La documentazione sull'autenticazione dovrebbe darti indicazioni sufficienti per risolvere i tuoi problemi. Naturalmente, anche tutte le risposte precedenti sono accurate e forniscono modi diversi per svolgere lo stesso compito.


Solo così NON devi allontanarti da Stack Overflow, ecco cosa offre in poche parole.

Basic auth:

$ http -a username:password example.org
Digest auth:

$ http --auth-type=digest -a username:password example.org
With password prompt:

$ http -a username example.org


forse non l'ho capito affatto, ma è un modulo Python? Immagino sia uno strumento shell / CLI e sono deluso: '(sembrava essere così facile da usare
Alex

@Alex - È un modulo Python. Il README su Github ( github.com/jkbrzt/httpie ) contiene tutto ciò di cui hai bisogno.
stuxnetting
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.