online - request python




Alternativa CURL en Python (5)

Tengo una llamada cURL que uso en PHP:

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

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


Aquí hay un ejemplo simple usando urllib2 que hace 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 ajusta esto en un script y lo ejecuta desde un terminal, puede canalizar la cadena de respuesta a 'mjson.tool' para permitir una impresión bonita.

>> basicAuth.py | python -mjson.tool

Una última cosa a tener en cuenta, urllib2 solo es compatible con solicitudes GET & POST.
Si necesita usar otros verbos HTTP como DELETE, PUT, etc., probablemente quiera echarle un vistazo a PYCURL



Si está utilizando un comando para simplemente llamar curl como ese, 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 podrías probar PYCURL si quieres tenerlo como una API más estructurada, como lo que PHP tiene.


Un ejemplo, cómo usar urllib para esas cosas, con alguna sintaxis de azúcar. Conozco las solicitudes y otras bibliotecas, pero urllib es lib estándar para Python y no requiere que se instale nada por separado.

Python 2/3 compatible.

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 es 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 por gusto.

12/08 actualización

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

  • autorización

  • CRUD compatible

  • detección automática de charset

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


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

Tu llamada de cURL usando urllib2 en su lugar. Completamente no probado.





curl