CURL-Alternative in Python

114

Ich habe einen cURL-Aufruf, den ich in PHP verwende:

curl -i -H 'Akzeptieren: application / xml' -u Login: Schlüssel " https://app.streamsend.com/emails "

Ich brauche eine Möglichkeit, dasselbe in Python zu tun. Gibt es eine Alternative zu cURL in Python? Ich kenne urllib, aber ich bin ein Python-Neuling und habe keine Ahnung, wie ich es verwenden soll.

Gaurav Sharma
quelle
2
Sie können versuchen, Pycurl
Ghostdog74
2
urllib2 ist ein weit verbreitetes Paket für diese Art von Arbeit.
Saurav
3
Das Obige ist ein Link für eine großartige Bibliothek, um einfaches http requestsin Python auszuführen (verfügbar zur Installation über easy_install oder pip in PyPi). Der Name / die URL ist etwas verwirrend - zuerst dachte ich fast, dies wäre eine Wunschliste für eine bessere urllib2, stattdessen requestseine sehr intuitive, einfach zu bedienende Python-Bibliothek sudo easy_install requestsoder sudo pip install requests.
Dr. Jimbob
Python Requests vs PyCurl Performance Sie anständig auf Ihre Anforderung
Santhosh

Antworten:

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

Ihr cURL-Aufruf verwendet stattdessen urllib2. Völlig ungetestet.

blwy10
quelle
4
Es ist schön, dies mit der Antwort unten zu vergleichen und zu sehen, wie weit Python in den letzten vier Jahren fortgeschritten ist
Razi Shaban
133

Sie können HTTP-Anforderungen verwenden, die im Benutzerhandbuch " Anforderungen: HTTP für Menschen" beschrieben sind .

Gudbergur
quelle
2
Anfragen sind die neuesten und größten! Es raucht und brennt ungeschickt urllib2, ich wünschte, Anfragen werden Standard-HTTP-Client für Python eingehende 3.x-Versionen
Phyo Arkar Lwin
1
Als ich zur Verwendung von Anfragen wechselte, habe ich nie mehr direkt auf urllib2 zurückgegriffen. Die integrierte JSON-Dekodierung ist ebenfalls praktisch. Sie müssen den Body nicht manuell mit json laden, wenn der entsprechende Inhaltstyp festgelegt ist.
Thomas Farvour
Anfragen sind so einfach. In wenigen Minuten konnte ich sogar ein benutzerdefiniertes Authentifizierungsschema erstellen. urllib2 ist super nervig.
Doug
35

Hier ist ein einfaches Beispiel mit urllib2, das eine grundlegende Authentifizierung für die GitHub-API durchführt.

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()

Wenn Sie dies in ein Skript einbinden und von einem Terminal aus ausführen, können Sie die Antwortzeichenfolge an 'mjson.tool' weiterleiten, um ein hübsches Drucken zu ermöglichen.

>> basicAuth.py | python -mjson.tool

Als letztes ist zu beachten, dass urllib2 nur GET & POST-Anforderungen unterstützt.
Wenn Sie andere HTTP-Verben wie DELETE, PUT usw. verwenden müssen, sollten Sie sich PYCURL ansehen

Braitsch
quelle
Warum wurde dies abgelehnt? Vielleicht, weil Sie PYCURL anstelle von PycURL geschrieben haben: D
Bhargav Rao
20

Wenn Sie einen Befehl verwenden, um Curl einfach so aufzurufen, können Sie dasselbe in Python mit tun subprocess. Beispiel:

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

Oder Sie könnten PycURL ausprobieren, wenn Sie es als strukturiertere API wie PHP haben möchten.

unholysampler
quelle
Nein. Der cURL-Aufruf ist Teil eines Programms. Wenn Sie den Code veröffentlichen könnten, der genau das Gleiche tut wie im obigen Curl-Aufruf, wäre das großartig.
Gaurav Sharma
Es wurde ein Beispiel hinzugefügt, was ich mit der Verwendung von Unterprozessen basierend auf Ihrer Frage gemeint habe, aber ich vermute, Sie suchen nach etwas mehr wie PycURL.
Unholysampler
Ich weiß, dass dies älter ist, aber PycURL ist meiner Meinung nach für die meisten Verwendungen von cURL ziemlich niedrig. Sogar die PHP-Implementierung von cURL ist ziemlich niedrig.
Thomas Farvour
Ich erhalte "Namensfehler, Namensunterprozess nicht definiert", nachdem ich "Python" von cmd aufgerufen habe und mich daher in der Python-Umgebung befinde.
Timo
@ Timo Hast du import subprocess? Die Python-Repl-Umgebung ist wie eine Python-Datei. Sie müssen die anderen Module importieren.
Unholysampler
13
import requests

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

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

Dies ist das einfachste, was ich bekommen habe.

Tadamhicks
quelle
Dies ist die einfachste Antwort! urllib2ist zu kompliziert.
not2qubit
7

Ein Beispiel, wie man urllib für diese Dinge verwendet, mit etwas Zuckersyntax. Ich kenne Anfragen und andere Bibliotheken, aber urllib ist die Standardbibliothek für Python und erfordert keine separate Installation.

Python 2/3 kompatibel.

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"})

Die Funktion ist nicht vollständig und möglicherweise nicht ideal, zeigt jedoch eine grundlegende Darstellung und ein zu verwendendes Konzept. Zusätzliche Dinge können je nach Geschmack hinzugefügt oder geändert werden.

12/08 Update

Hier ist ein GitHub-Link zur aktualisierten Live-Quelle. Derzeit unterstützt:

  • Genehmigung

  • CRUD-kompatibel

  • automatische Zeichensatzerkennung

  • automatische Codierungserkennung (Komprimierung)

Reishin
quelle
4

Wenn alle oben genannten Funktionen über die von Ihnen gesuchte Befehlszeile ausgeführt werden, würde ich HTTPie empfehlen . Es ist eine fantastische cURL-Alternative und super einfach und bequem zu bedienen (und anzupassen).

Hier ist die (prägnante und präzise) Beschreibung von GitHub;

HTTPie (ausgesprochen aych-tee-tee-pie) ist ein Befehlszeilen-HTTP-Client. Ziel ist es, die CLI-Interaktion mit Webdiensten so benutzerfreundlich wie möglich zu gestalten.

Es bietet einen einfachen http-Befehl, mit dem beliebige HTTP-Anforderungen mithilfe einer einfachen und natürlichen Syntax gesendet werden können, und zeigt eine farbige Ausgabe an. HTTPie kann zum Testen, Debuggen und allgemeinen Interagieren mit HTTP-Servern verwendet werden.


Die Dokumentation zur Authentifizierung sollte Ihnen genügend Hinweise geben, um Ihre Probleme zu lösen. Natürlich sind auch alle oben genannten Antworten korrekt und bieten verschiedene Möglichkeiten, um dieselbe Aufgabe zu erfüllen.


Nur damit Sie sich NICHT vom Stapelüberlauf entfernen müssen, ist hier das, was es auf den Punkt bringt.

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

Stuxnetz
quelle
Vielleicht habe ich es gar nicht bekommen, aber ist es ein Python-Modul? Ich denke, es ist ein Shell / CLI-Tool, und ich bin enttäuscht: '(es schien so einfach zu bedienen zu sein
Alex
@Alex - Es ist ein Python-Modul. Die README auf Github ( github.com/jkbrzt/httpie ) enthält alles, was Sie brauchen.
Stuxnetting