仅使用标准库将curl POST请求转换为Python

Jim*_*imm 20 python json curl

我想将这个curl命令转换为我可以在Python中用于现有脚本的东西.

curl -u 7898678:X -H 'Content-Type: application/json' \
-d '{"message":{"body":"TEXT"}}' http://sample.com/36576/speak.json
Run Code Online (Sandbox Code Playgroud)

TEXT是我想用其余脚本生成的消息替换的.(这已经合理,虽然我不认为它遵循最佳实践或特殊性可靠. - 需要找出如何正确学习编程(即不使用谷歌组装东西))

如果可能的话,我希望这能与标准库一起使用.

Joh*_*lla 23

如果可能的话,我希望这能与标准库一起使用.

标准库提供urllibhttplib处理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
Run Code Online (Sandbox Code Playgroud)

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}
Run Code Online (Sandbox Code Playgroud)

如果您愿意放宽标准库限制,您可以使用PycURL.请注意,它不是非常Pythonic(它几乎只是libcurl上的薄薄的贴面),我不确定它与Python 3的兼容性如何.

  • 这是真的.我发现使用httplib并进行URL munging通常不值得努力,因为urllib2为您提供了所有这些功能. (2认同)

And*_*lke 12

虽然有办法在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)
Run Code Online (Sandbox Code Playgroud)

我用netcat测试了这个,所以我可以看到发送的数据除了排序顺序外,在两种情况下都是相同的.这里第一个用curl完成,第二个用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
Run Code Online (Sandbox Code Playgroud)

(这是从输出稍微调整的.我的测试用例没有使用您使用的相同url路径.)

没有必要使用底层的httplib,它不支持urllib2为你提供代理支持的东西.另一方面,我发现urllib2在这种简单的请求之外是复杂的,如果你想更好地支持发送哪些头文件以及发送它们的顺序,那么使用httplib.