Преобразовать curl POST-запрос на Python только с использованием стандартной библиотеки
Я хотел бы преобразовать эту команду curl в то, что я могу использовать в Python для существующего script.
curl -u 7898678:X -H 'Content-Type: application/json' \
-d '{"message":{"body":"TEXT"}}' http://sample.com/36576/speak.json
TEXT - это то, что я хотел бы заменить сообщением, сгенерированным остальной частью script. (Это уже работает разумно, хотя я не думаю, что он следит за лучшей практикой или надежностью. - нужно найти как правильно учиться программировать (т.е. не использовать Google для сборки материалов))
Я хотел бы, чтобы это работало со стандартной библиотекой, если это возможно.
Ответы
Ответ 1
Я хотел бы, чтобы это работало со стандартной библиотекой, если это возможно.
Стандартная библиотека предоставляет urllib
и httplib
для работы с URL-адресами:
>>> import httplib, urllib
>>> params = urllib.urlencode({'apple': 1, 'banana': 2, 'coconut': 'yummy'})
>>> headers = {"Content-type": "application/x-www-form-urlencoded",
... "Accept": "text/plain"}
>>> conn = httplib.HTTPConnection("example.com:80")
>>> conn.request("POST", "/some/path/to/site", params, headers)
>>> response = conn.getresponse()
>>> print response.status, response.reason
200 OK
Если вы хотите выполнить curl
самостоятельно, вы можете просто вызвать os.system()
:
import os
TEXT = ...
cmd = """curl -u 7898678:X -H 'Content-Type: application/json'""" \
"""-d '{"message":{"body":"%{t}"}}' http://sample.com/36576/speak.json""" % \
{'t': TEXT}
Если вы хотите смягчить ограничение только для стандартных библиотек, вы можете использовать PycURL
, Помните, что это не очень Pythonic (это довольно тонкий шпон над libcurl), и я не уверен, насколько он совместим с Python 3.
Ответ 2
Хотя существуют способы обработки аутентификации в urllib2, если вы выполняете базовую авторизацию (что означает эффективную отправку имени пользователя и пароля в ясный текст), то вы можете сделать все, что хотите, с помощью urllib2.Request и urllib2.urlopen:
import urllib2
def basic_authorization(user, password):
s = user + ":" + password
return "Basic " + s.encode("base64").rstrip()
req = urllib2.Request("http://localhost:8000/36576/speak.json",
headers = {
"Authorization": basic_authorization("7898678", "X"),
"Content-Type": "application/json",
# Some extra headers for fun
"Accept": "*/*", # curl does this
"User-Agent": "my-python-app/1", # otherwise it uses "Python-urllib/..."
},
data = '{"message":{"body":"TEXT"}}')
f = urllib2.urlopen(req)
Я протестировал это с помощью netcat, чтобы я мог видеть, что отправленные данные были, за исключением порядка сортировки, идентичны в обоих случаях. Здесь первый был сделан с завитком, а второй с urllib2
% nc -l 8000
POST /36576/speak.json HTTP/1.1
Authorization: Basic Nzg5ODY3ODpY
User-Agent: curl/7.19.4 (universal-apple-darwin10.0) libcurl/7.19.4 OpenSSL/0.9.8k zlib/1.2.3
Host: localhost:8000
Accept: */*
Content-Type: application/json
Content-Length: 27
{"message":{"body":"TEXT"}} ^C
% nc -l 8000
POST /36576/speak.json HTTP/1.1
Accept-Encoding: identity
Content-Length: 27
Connection: close
Accept: */*
User-Agent: my-python-app/1
Host: localhost:8000
Content-Type: application/json
Authorization: Nzg5ODY3ODpY
{"message":{"body":"TEXT"}}^C
(Это немного изменено с вывода. В моем тестовом примере не использовался тот же путь URL-адреса, который вы использовали.)
Не нужно использовать базовый httplib, который не поддерживает то, что urllib2 предоставляет вам как поддержку прокси. С другой стороны, я нахожу urllib2 сложным за пределами этого простого запроса, и если вы хотите получить лучшую поддержку для отправки заголовков и отправленного им заказа, используйте httplib.
Ответ 3
Спасибо каждому
это работает
import urllib2
def speak(status):
def basic_authorization(user, password):
s = user + ":" + password
return "Basic " + s.encode("base64").rstrip()
req = urllib2.Request("http://example.com/60/speak.json",
headers = {
"Authorization": basic_authorization("2345670", "X"),
"Content-Type": "application/json",
"Accept": "*/*",
"User-Agent": "my-python-app/1",
},
data = '{"message":{"body":'+ status +'}}')
f = urllib2.urlopen(req)
speak('Yay')
Ответ 4
Взгляните на pycurl http://pycurl.sourceforge.net/