Alternative à CURL en Python

114

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 noob Python et je n'ai aucune idée de comment l'utiliser.

Gaurav Sharma
la source
2
Vous pouvez essayer pycurl
ghostdog74
2
urllib2 est un package largement utilisé pour ce genre de travail.
Saurav
3
Ce qui précède est un lien vers une excellente bibliothèque pour faire du simple http requestsen python (disponible à installer via easy_install ou pip dans PyPi). Le nom / URL est un peu déroutant - au début je presque pensé que c'était une demande pour une meilleure liste urllib2, au lieu d' requestsun simple très intuitif à utiliser la bibliothèque pythonique sudo easy_install requestsou sudo pip install requests.
dr jimbob
Requêtes Python vs performances PyCurl Vous êtes décent sur vos besoins
Santhosh

Réponses:

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

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

blwy10
la source
4
C'est bien de comparer cela avec la réponse ci-dessous et de voir à quel point Python a progressé au cours des quatre dernières années
Razi Shaban
133

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

Gudbergur
la source
2
Les demandes sont les dernières et les meilleures! Il fume et brûle urllib2 maladroit, je souhaite que les requêtes deviennent un client HTTP standard pour les versions 3.x entrantes de python
Phyo Arkar Lwin
1
Lorsque je suis passé à l'utilisation des requêtes, je n'ai plus jamais pensé à utiliser directement urllib2. Le décodage JSON intégré est également pratique. Pas besoin de charger manuellement le corps avec json si le type de contenu approprié est défini.
Thomas Farvour
Les demandes sont si simples. J'ai même pu créer un schéma d'authentification personnalisé en quelques minutes. urllib2 est super ennuyeux.
Doug
35

Voici un exemple simple utilisant 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 encapsulez ceci dans un script et que vous l'exécutez à partir d'un terminal, vous pouvez diriger la chaîne de réponse vers «mjson.tool» pour activer la jolie impression.

>> basicAuth.py | python -mjson.tool

Une dernière chose à noter, urllib2 ne prend en charge que les requêtes GET & POST.
Si vous avez besoin d'utiliser d'autres verbes HTTP comme DELETE, PUT, etc., vous voudrez probablement jeter un coup d'œil à PYCURL

braitsch
la source
Pourquoi cela a-t-il été rejeté? Peut-être parce que vous avez écrit PYCURL au lieu de PycURL: D
Bhargav Rao
20

Si vous utilisez une commande pour appeler curl comme ça, vous pouvez faire la même chose en 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 sous la forme d'une API plus structurée comme celle de PHP.

non-échantillonneur
la source
Non. L'appel cURL fait partie d'un programme. Si vous pouviez publier le code qui fait exactement la même chose que celle faite dans l'appel curl ci-dessus, ce serait génial.
Gaurav Sharma
Ajout d'un exemple de ce que je voulais dire en utilisant un sous-processus basé sur votre question, mais je suppose que vous cherchez quelque chose de plus comme PycURL.
unholysampler
Je sais que c'est plus ancien, mais PycURL est assez bas pour la plupart des utilisations de cURL à mon avis. Même l'implémentation PHP de cURL est de niveau assez bas.
Thomas Farvour
J'obtiens "erreur de nom, sous-processus de nom non défini" après avoir appelé "python" depuis cmd et donc être dans l'environnement python.
Timo
@Timo l'avez-vous fait import subprocess? L'environnement repl python est comme un fichier python, vous devez importer les autres modules.
unholysampler
13
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 obtenir.

tadamhicks
la source
C'est la réponse la plus simple! urllib2est trop compliqué.
not2qubit le
7

Un exemple, comment utiliser urllib pour cela, avec une syntaxe de sucre. Je connais les requêtes et autres bibliothèques, mais urllib est une bibliothèque standard pour python et ne nécessite aucune installation séparée.

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 montre une représentation et un concept de base à utiliser. Des choses supplémentaires pourraient être ajoutées ou modifiées par goût.

Mise à jour du 12/08

Voici un lien GitHub vers la source mise à jour en direct. Soutient actuellement:

  • autorisation

  • Compatible CRUD

  • détection automatique du jeu de caractères

  • détection automatique du codage (compression)

Reishin
la source
4

S'il exécute tout ce qui précède à partir de la ligne de commande que vous recherchez, je recommanderais HTTPie . C'est une alternative fantastique à cURL et est super facile et pratique à utiliser (et à personnaliser).

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

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

Il fournit une commande http simple qui permet d'envoyer des requêtes HTTP arbitraires en utilisant 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 authentification devrait vous donner suffisamment de pointeurs pour résoudre vos problèmes. Bien entendu, toutes les réponses ci-dessus sont également exactes et fournissent différentes manières d'accomplir la même tâche.


Juste 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

stuxnetting
la source
peut-être que je ne l'ai pas du tout compris, mais est-ce un module Python? Je suppose que c'est un outil shell / CLI, et je suis déçu: '(il semblait être si facile à utiliser
Alex
@Alex - C'est un module Python. Le README sur Github ( github.com/jkbrzt/httpie ) contient tout ce dont vous avez besoin.
stuxnetting le