Alternativa de CURL en Python

114

Tengo una llamada cURL que uso en PHP:

curl -i -H 'Aceptar: aplicación / xml' -u inicio de sesión: clave " https://app.streamsend.com/emails "

Necesito una forma de hacer lo mismo en Python. ¿Existe una alternativa a cURL en Python? Sé de urllib pero soy un novato de Python y no tengo idea de cómo usarlo.

Gaurav Sharma
fuente
2
Puede probar pycurl
ghostdog74
2
urllib2 es un paquete ampliamente utilizado para este tipo de trabajo.
Saurav
3
Lo anterior es un enlace para una gran biblioteca para hacer http simple requestsen python (disponible para instalar a través de easy_install o pip en PyPi). El Nombre / URL es un poco confuso - en un primer momento pensó que esto era casi una solicitud deseos para una mejor urllib2, en vez requestsde una muy intuitiva y fácil de utilizar la biblioteca Pythonic sudo easy_install requestso sudo pip install requests.
dr jimbob
Python Requests vs PyCurl Performance Eres decente en tu requisito
Santhosh

Respuestas:

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']

Su llamada cURL usando urllib2 en su lugar. Completamente no probado.

blwy10
fuente
4
Es bueno comparar esto con la respuesta que se encuentra a continuación y ver cuánto ha progresado Python en los últimos cuatro años
Razi Shaban
133

Puede utilizar las solicitudes HTTP que se describen en la guía del usuario Solicitudes: HTTP para humanos .

Gudbergur
fuente
2
Requests es lo último y lo mejor! Fuma y quema torpe urllib2, deseo que las solicitudes se conviertan en Cliente HTTP estándar para las versiones entrantes 3.x de Python
Phyo Arkar Lwin
1
Cuando cambié a usar solicitudes, nunca más miré hacia atrás para usar urllib2 directamente. La decodificación JSON incorporada también es útil. No es necesario cargar manualmente el cuerpo con json si se establece el tipo de contenido apropiado.
Thomas Farvour
Las solicitudes son tan simples. Incluso pude crear un esquema de autenticación personalizado en unos minutos. urllib2 es súper molesto.
Doug
35

Aquí hay un ejemplo simple usando urllib2 que realiza una autenticación básica contra la API de 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()

Además, si envuelve esto en un script y lo ejecuta desde un terminal, puede canalizar la cadena de respuesta a 'mjson.tool' para habilitar una impresión bonita.

>> basicAuth.py | python -mjson.tool

Una última cosa a tener en cuenta, urllib2 solo admite solicitudes GET & POST.
Si necesita usar otros verbos HTTP como DELETE, PUT, etc., probablemente querrá echar un vistazo a PYCURL

braitsch
fuente
¿Por qué se votó en contra? Quizás porque escribiste PYCURL en lugar de PycURL: D
Bhargav Rao
20

Si está utilizando un comando para llamar a curl de esa manera, puede hacer lo mismo en Python con subprocess. Ejemplo:

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

O puede probar PycURL si desea tener una API más estructurada como la que tiene PHP.

profano
fuente
No. La llamada cURL es parte de un programa. Si pudiera publicar el código que hace exactamente lo mismo que se hace en la llamada de curl anterior, sería genial.
Gaurav Sharma
Agregué un ejemplo de lo que quise decir con el uso de subprocesos según su pregunta, pero supongo que está buscando algo más como PycURL.
unholysampler
Sé que esto es más antiguo, pero PycURL tiene un nivel bastante bajo para la mayoría de los usos de cURL en mi opinión. Incluso la implementación de PHP de cURL es de un nivel bastante bajo.
Thomas Farvour
Recibo "error de nombre, subproceso de nombre no definido" después de llamar a "python" desde cmd y, por lo tanto, estar en el entorno de python.
Timo
@Timo ¿Lo hiciste import subprocess? El entorno de respuesta de Python es como un archivo de Python, tienes que importar los otros módulos.
unholysampler
13
import requests

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

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

Este es el más simple que he podido conseguir.

tadamhicks
fuente
¡Esta es la respuesta más simple! urllib2es demasiado complicado.
not2qubit
7

Algún ejemplo, cómo usar urllib para esas cosas, con algo de sintaxis de azúcar. Conozco las solicitudes y otras bibliotecas, pero urllib es una biblioteca estándar para python y no requiere que se instale nada por separado.

Compatible 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 función no está completa y posiblemente no sea ideal, pero muestra una representación básica y un concepto para usar. Se pueden agregar o cambiar cosas adicionales según el gusto.

Actualización 12/08

Aquí hay un enlace de GitHub a la fuente actualizada en vivo. Actualmente apoyando:

  • autorización

  • Compatible con CRUD

  • detección automática de juego de caracteres

  • detección automática de codificación (compresión)

Reishin
fuente
4

Si está ejecutando todo lo anterior desde la línea de comando que está buscando, le recomendaría HTTPie . Es una fantástica alternativa a cURL y es súper fácil y conveniente de usar (y personalizar).

Aquí está su descripción (sucinta y precisa) de GitHub;

HTTPie (pronunciado aych-tee-tee-pie) es un cliente HTTP de línea de comandos. Su objetivo es hacer que la interacción CLI con los servicios web sea lo más amigable posible para los humanos.

Proporciona un comando http simple que permite enviar solicitudes HTTP arbitrarias utilizando una sintaxis simple y natural, y muestra una salida coloreada. HTTPie se puede utilizar para probar, depurar y, en general, interactuar con servidores HTTP.


La documentación sobre la autenticación debería proporcionarle suficientes sugerencias para resolver su (s) problema (s). Por supuesto, todas las respuestas anteriores también son precisas y brindan diferentes formas de realizar la misma tarea.


Solo para que NO tenga que alejarse de Stack Overflow, esto es lo que ofrece en pocas palabras.

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

stuxnetting
fuente
tal vez no lo entendí en absoluto, pero ¿es un módulo de Python? Supongo que es una herramienta de shell / CLI, y estoy decepcionado: '(parecía ser tan fácil de usar
Alex
@Alex: es un módulo de Python. El README en Github ( github.com/jkbrzt/httpie ) contiene todo lo que necesita.
stuxnetting