Alternatif CURL dengan Python

114

Saya memiliki panggilan cURL yang saya gunakan di PHP:

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

Saya membutuhkan cara untuk melakukan hal yang sama dengan Python. Apakah ada alternatif untuk cURL dengan Python. Saya tahu tentang urllib tapi saya Python noob dan tidak tahu cara menggunakannya.

Gaurav Sharma
sumber
2
Anda dapat mencoba pycurl
ghostdog74
2
urllib2 adalah paket yang banyak digunakan untuk jenis pekerjaan ini.
Saurav
7
Bahkan lebih baik: docs.python-requests.org/en/latest/index.html
Saurav
3
Di atas adalah link untuk library yang bagus untuk melakukan http sederhana requestsdengan python (tersedia untuk diinstal melalui easy_install atau pip di PyPi). Nama / URL sedikit membingungkan - pada saya pertama hampir pikir ini adalah permintaan wishlist untuk yang lebih baik urllib2, bukan requestsyang sangat intuitif mudah digunakan perpustakaan pythonic sudo easy_install requestsatau sudo pip install requests.
dr jimbob
Permintaan Python vs Kinerja PyCurl Anda layak memenuhi kebutuhan Anda
Santhosh

Jawaban:

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

Panggilan cURL Anda menggunakan urllib2 sebagai gantinya. Sepenuhnya belum teruji.

blwy10
sumber
4
Sangat menyenangkan membandingkan ini dengan jawaban tepat di bawah dan melihat seberapa jauh kemajuan Python selama empat tahun terakhir
Razi Shaban
133

Anda dapat menggunakan Permintaan HTTP yang dijelaskan dalam panduan pengguna Permintaan: HTTP untuk Manusia .

Gudbergur
sumber
2
Permintaan adalah yang terbaru dan terbaik! Ini merokok dan membakar urllib2 yang kikuk, saya berharap permintaan menjadi Klien HTTP standar untuk python versi 3.x yang masuk
Phyo Arkar Lwin
1
Ketika saya beralih menggunakan permintaan, saya tidak pernah melihat kembali untuk menggunakan urllib2 secara langsung lagi. Pengodean JSON bawaan juga berguna. Tidak perlu memuat badan secara manual dengan json jika jenis konten yang sesuai telah ditetapkan.
Thomas Farvour
Permintaannya sangat sederhana. Saya bahkan dapat membuat skema otentikasi khusus dalam beberapa menit. urllib2 sangat mengganggu.
Doug
35

Berikut adalah contoh sederhana menggunakan urllib2 yang melakukan otentikasi dasar terhadap API 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()

Selanjutnya jika Anda membungkus ini dalam skrip dan menjalankannya dari terminal, Anda dapat menyalurkan string respons ke 'mjson.tool' untuk mengaktifkan pencetakan cantik.

>> basicAuth.py | python -mjson.tool

Satu hal terakhir yang perlu diperhatikan, urllib2 hanya mendukung permintaan GET & POST.
Jika Anda perlu menggunakan kata kerja HTTP lain seperti DELETE, PUT, dll, Anda mungkin ingin melihat PYCURL

braitsch
sumber
Mengapa ini ditolak? Mungkin karena Anda menulis PYCURL dan bukan PycURL: D
Bhargav Rao
20

Jika Anda menggunakan perintah untuk memanggil curl seperti itu, Anda dapat melakukan hal yang sama dengan Python subprocess. Contoh:

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

Atau Anda dapat mencoba PycURL jika Anda ingin menjadikannya sebagai api yang lebih terstruktur seperti yang dimiliki PHP.

unholysampler
sumber
Tidak. Panggilan cURL adalah bagian dari program. Jika Anda dapat memposting kode yang melakukan hal yang persis sama dengan yang dilakukan di panggilan curl di atas, itu akan bagus.
Gaurav Sharma
Menambahkan contoh dari apa yang saya maksud dengan menggunakan subproses berdasarkan pertanyaan Anda, tapi saya rasa Anda sedang mencari sesuatu yang lebih seperti PycURL.
unholysampler
Saya tahu ini lebih tua, tetapi PycURL adalah level yang cukup rendah untuk sebagian besar penggunaan cURL menurut saya. Bahkan implementasi PHP dari cURL adalah level yang cukup rendah.
Thomas Farvour
Saya mendapatkan "kesalahan nama, subproses nama tidak ditentukan" setelah memanggil "python" dari cmd dan karena itu berada di python env.
Timo
@Timo Apakah Anda import subprocess? Lingkungan repl python sama seperti file python, Anda harus mengimpor modul lainnya.
unholysampler
13
import requests

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

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

Ini yang paling sederhana yang bisa saya dapatkan.

tadamhicks
sumber
Ini jawaban paling sederhana! urllib2terlalu rumit.
not2qubit
7

Beberapa contoh, bagaimana menggunakan urllib untuk hal-hal itu, dengan beberapa sintaks gula. Saya tahu tentang permintaan dan pustaka lain, tetapi urllib adalah lib standar untuk python dan tidak memerlukan apa pun untuk dipasang secara terpisah.

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

Fungsi tidak lengkap dan mungkin tidak ideal, tetapi menunjukkan representasi dan konsep dasar yang akan digunakan. Hal-hal tambahan dapat ditambahkan atau diubah sesuai selera.

Pembaruan 12/08

Ini adalah tautan GitHub ke sumber yang diperbarui secara langsung. Saat ini mendukung:

  • otorisasi

  • CRUD kompatibel

  • deteksi charset otomatis

  • deteksi pengkodean otomatis (kompresi)

Reishin
sumber
4

Jika menjalankan semua hal di atas dari baris perintah yang Anda cari, maka saya akan merekomendasikan HTTPie . Ini adalah alternatif CURL yang fantastis dan sangat mudah dan nyaman untuk digunakan (dan disesuaikan).

Berikut ini adalah deskripsi (ringkas dan tepat) dari GitHub;

HTTPie (diucapkan aych-tee-tee-pie) adalah klien HTTP baris perintah. Sasarannya adalah membuat interaksi CLI dengan layanan web semaksimal mungkin.

Ini menyediakan perintah http sederhana yang memungkinkan pengiriman permintaan HTTP sewenang-wenang menggunakan sintaks sederhana dan alami, dan menampilkan keluaran berwarna. HTTPie dapat digunakan untuk pengujian, debugging, dan umumnya berinteraksi dengan server HTTP.


Dokumentasi seputar otentikasi harus memberi Anda petunjuk yang cukup untuk menyelesaikan masalah Anda. Tentu saja, semua jawaban di atas juga akurat, dan memberikan cara berbeda untuk menyelesaikan tugas yang sama.


Supaya Anda TIDAK perlu beralih dari Stack Overflow, inilah yang ditawarkan secara singkat.

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
sumber
mungkin saya tidak mengerti sama sekali, tapi apakah itu modul Python? Saya kira itu alat shell / CLI, dan saya kecewa: '(sepertinya sangat mudah digunakan
Alex
@Alex - Ini adalah modul Python. README di Github ( github.com/jkbrzt/httpie ) berisi semua yang Anda butuhkan.
stuxnetting