web-dev-qa-db-fra.com

Alternative CURL dans Python

J'ai un appel cURL que j'utilise en PHP:

curl -i -H 'Accepter: application/xml' -u login: clé " https://app.streamsend.com/emails "

J'ai besoin d'un moyen de faire la même chose en Python. Existe-t-il une alternative à cURL en Python? Je connais urllib mais je suis un Python noob et je ne sais pas comment l'utiliser.

113
Gaurav Sharma
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']

Votre appel cURL utilisant urllib2 à la place. Complètement non testé.

68
blwy10

Vous pouvez utiliser les requêtes HTTP décrites dans le guide de l'utilisateur Requests: HTTP for Humans .

132
Gudbergur

Voici un exemple simple d'utilisation de urllib2 qui effectue une authentification de base contre l'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()

De plus, si vous intégrez ceci dans un script et l'exécutez depuis un terminal, vous pouvez diriger la chaîne de réponse vers "mjson.tool" pour permettre une impression agréable.

>> basicAuth.py | python -mjson.tool

Une dernière chose à noter, urllib2 ne supporte que les requêtes GET & POST.
Si vous devez utiliser d'autres verbes HTTP tels que DELETE, PUT, etc., vous voudrez probablement jeter un oeil à PYCURL

35
braitsch

Si vous utilisez une commande pour simplement appeler curl de cette façon, vous pouvez faire la même chose dans Python avec subprocess. Exemple:

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

Ou vous pouvez essayer PycURL si vous voulez l'avoir comme une API plus structurée comme ce que PHP a.

20
unholysampler
import requests

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

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

C'est le plus simple que j'ai pu l'obtenir.

12
tadamhicks

Quelques exemples, comment utiliser urllib pour ces choses, avec une syntaxe en sucre. Je connais les requêtes et les autres bibliothèques, mais urllib est la bibliothèque standard pour python et ne nécessite aucune installation distincte.

Compatible 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 fonction n'est pas complète et n'est peut-être pas idéale, mais affiche une représentation de base et un concept à utiliser. Des choses supplémentaires pourraient être ajoutées ou modifiées par goût.

Mise à jour du 12/08

Here est un lien GitHub pour vivre la source mise à jour. Soutenant actuellement:

  • autorisation

  • Compatible CRUD

  • détection automatique du jeu de caractères

  • détection d'encodage automatique (compression)

7
Reishin

Si vous utilisez tout ce qui précède à partir de la ligne de commande que vous recherchez, nous vous recommandons alors HTTPie . CURL est une alternative fantastique et est super facile et pratique à utiliser (et à personnaliser).

Voici sa (succincte et précise) description de GitHub;

HTTPie (prononcé aych-tee-tee-pie) est un client HTTP en ligne de commande. Son objectif est de rendre l’interaction de la CLI avec les services Web aussi conviviale que possible.

Il fournit une commande http simple qui permet d’envoyer des requêtes HTTP arbitraires à l’aide d’une syntaxe simple et naturelle, et affiche une sortie colorisée. HTTPie peut être utilisé pour tester, déboguer et généralement interagir avec les serveurs HTTP.


La documentation autour de authentification devrait vous donner suffisamment d'indicateurs pour résoudre votre problème. (s) Bien sûr, toutes les réponses ci-dessus sont également exactes et offrent différents moyens d'accomplir la même tâche.


Pour que vous n'ayez PAS à vous éloigner de Stack Overflow, voici ce qu'il offre en un mot.

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
3
stuxnetting