Alternativa CURL em Python


114

Tenho uma chamada cURL que uso em PHP:

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

Preciso de uma maneira de fazer a mesma coisa em Python. Existe uma alternativa para cURL em Python. Eu sei do urllib, mas sou um novato em Python e não tenho ideia de como usá-lo.


2
Você pode tentar pycurl
ghostdog74

2
urllib2 é um pacote amplamente utilizado para esse tipo de trabalho.
Saurav


3
O acima é um link para uma ótima biblioteca para fazer http simples requestsem python (disponível para instalação via easy_install ou pip em PyPi). O nome / URL é um pouco confuso - no começo eu quase pensei que este era um pedido lista para melhor urllib2, em vez requestsde um muito intuitiva e fácil de usar a biblioteca Python sudo easy_install requestsou sudo pip install requests.
dr jimbob

Respostas:


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

Sua chamada cURL usando urllib2. Completamente não testado.


4
É bom comparar isso com a resposta logo abaixo e ver o quanto o Python progrediu nos últimos quatro anos
Razi Shaban

133

Você pode usar as solicitações HTTP descritas em Solicitações: guia do usuário HTTP para humanos .


2
Os pedidos são os melhores e mais recentes! Ele fuma e queima o urllib2 desajeitado, gostaria que as solicitações se tornassem cliente HTTP padrão para versões 3.x recebidas de python
Phyo Arkar Lwin

1
Quando mudei para o uso de solicitações, nunca mais voltei a usar o urllib2 diretamente. A decodificação JSON embutida também é útil. Não há necessidade de carregar manualmente o corpo com json se o tipo de conteúdo apropriado estiver definido.
Thomas Farvour

Os pedidos são tão simples. Consegui até criar um esquema de autenticação personalizado em alguns minutos. urllib2 é super irritante.
Doug

35

Aqui está um exemplo simples usando urllib2 que faz uma autenticação básica na API do 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()

Além disso, se você embrulhar isso em um script e executá-lo de um terminal, você pode canalizar a string de resposta para 'mjson.tool' para ativar a impressão bonita.

>> basicAuth.py | python -mjson.tool

Uma última coisa a ser observada: urllib2 só oferece suporte a solicitações GET e POST.
Se você precisa usar outros verbos HTTP como DELETE, PUT, etc, você provavelmente vai querer dar uma olhada em PYCURL


Por que isso foi rejeitado? Talvez porque você escreveu PYCURL em vez de PycURL: D
Bhargav Rao

20

Se você estiver usando um comando apenas para chamar curl assim, poderá fazer a mesma coisa em Python com subprocess. Exemplo:

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

Ou você pode tentar PycURL se quiser tê-lo como uma API mais estruturada como o que o PHP tem.


Não. A chamada cURL faz parte de um programa. Se você pudesse postar o código que faz exatamente a mesma coisa que está sendo feita na chamada curl acima, isso seria ótimo.
Gaurav Sharma

Adicionado um exemplo do que quero dizer com usar subprocesso com base em sua pergunta, mas acho que você está procurando por algo mais como PycURL.
unholysampler

Eu sei que isso é mais antigo, mas PycURL é de nível muito baixo para a maioria dos usos de cURL na minha opinião. Mesmo a implementação de cURL em PHP é de nível bastante baixo.
Thomas Farvour

Recebo "erro de nome, subprocesso de nome não definido" depois de chamar "python" do cmd e, portanto, estar no env python.
Timo

@Timo e você import subprocess? O ambiente python repl é como um arquivo python, você deve importar os outros módulos.
unholysampler

13
import requests

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

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

Este é o mais simples que consegui fazer.


Esta é a resposta mais simples! urllib2é muito complicado.
not2qubit

7

Algum exemplo, como usar urllib para essas coisas, com alguma sintaxe de açúcar. Eu sei sobre solicitações e outras bibliotecas, mas urllib é lib padrão para python e não requer que nada seja instalado separadamente.

Compatível com 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"})

A função não está completa e possivelmente não é ideal, mas mostra uma representação e um conceito básicos para usar. Coisas adicionais podem ser adicionadas ou alteradas de acordo com o gosto.

12/08 atualização

Aqui está um link do GitHub para a fonte atualizada ao vivo. Suportando atualmente:

  • autorização

  • Compatível com CRUD

  • detecção automática de charset

  • detecção automática de codificação (compressão)


4

Se estiver executando todos os itens acima na linha de comando que você está procurando, recomendo o HTTPie . É uma alternativa cURL fantástica e é super fácil e conveniente de usar (e personalizar).

Aqui está sua descrição (sucinta e precisa) do GitHub;

HTTPie (pronuncia-se aych-tee-tee-pie) é um cliente HTTP de linha de comando. Seu objetivo é tornar a interação da CLI com os serviços da web o mais amigável possível.

Ele fornece um comando http simples que permite o envio de solicitações HTTP arbitrárias usando uma sintaxe simples e natural, e exibe saída colorida. HTTPie pode ser usado para teste, depuração e interação geral com servidores HTTP.


A documentação sobre autenticação deve fornecer dicas suficientes para resolver seu (s) problema (s). Obviamente, todas as respostas acima também são precisas e fornecem maneiras diferentes de realizar a mesma tarefa.


Para que você NÃO precise sair do Stack Overflow, aqui está o que ele oferece em poucas palavras.

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


talvez eu não tenha entendido nada, mas é um módulo Python? Acho que é uma ferramenta shell / CLI, e estou desapontado: '(parecia ser tão fácil de usar
Alex

@Alex - é um módulo Python. O README no Github ( github.com/jkbrzt/httpie ) contém tudo que você precisa.
stuxnetting
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.