如何使用urllib3在Python上发布帖子请求?

时间:2015-08-03 02:55:15

标签: python json curl urllib3

我一直在尝试向API发出请求,我必须通过以下正文:

{
"description":"Tenaris",
"ticker":"TS.BA",
"industry":"Metalúrgica",
"currency":"ARS"
}

尽管代码似乎是正确的,但它完成了" Process完成了退出代码0"它运行不正常。我不知道我错过了什么,但这是我的代码:

http = urllib3.PoolManager()
http.urlopen('POST', 'http://localhost:8080/assets', headers={'Content-Type':'application/json'},
                 data={
"description":"Tenaris",
"ticker":"TS.BA",
"industry":"Metalúrgica",
"currency":"ARS"
})

顺便说一下,这是使用Python的第一天,请原谅我,如果我不够具体。

3 个答案:

答案 0 :(得分:9)

由于您尝试传入JSON请求,因此您需要将主体编码为JSON并将其传递给body字段。

对于您的示例,您希望执行以下操作:

import json
encoded_body = json.dumps({
        "description": "Tenaris",
        "ticker": "TS.BA",
        "industry": "Metalúrgica",
        "currency": "ARS",
    })

http = urllib3.PoolManager()

r = http.request('POST', 'http://localhost:8080/assets',
                 headers={'Content-Type': 'application/json'},
                 body=encoded_body)

print r.read() # Do something with the response?

编辑:我原来的回答是错误的。更新它以编码JSON。此外,相关问题:How do I pass raw POST data into urllib3?

答案 1 :(得分:0)

打电话给Gitlab CI时遇到了这个问题。由于上述内容对我不起作用(给我一些有关无法将字节连接到字符串的错误),并且由于我尝试传递的参数是嵌套的,因此我认为我应该发布最终对我有用的内容:

API_ENDPOINT = "https://gitlab.com/api/v4/projects/{}/pipeline".format(GITLAB_PROJECT_ID)

API_TOKEN = "SomeToken"

data = {
    "ref": ref,
    "variables": [
        {
            "key": "ENVIRONMENT",
            "value": some_env
        },
        {   "key": "S3BUCKET",
            "value": some_bucket
        },
    ]
}

req_headers = {
    'Content-Type': 'application/json',
    'PRIVATE-TOKEN': API_TOKEN,
}

http = urllib3.PoolManager()

encoded_data = json.dumps(data).encode('utf-8')

r = http.request('POST', API_ENDPOINT,
             headers=req_headers,
             body=encoded_data)

resp_body = r.data.decode('utf-8')
resp_dict = json.loads(r.data.decode('utf-8'))

logger.info('Response Code: {}'.format(r.status))
logger.info('Response Body: {}'.format(resp_body))

if 'message' in resp_body:
    logfile_msg = 'Failed Gitlab Response-- {} {message}'.format(r.status, **resp_dict)

答案 2 :(得分:-1)

我最近对使用 urllib3 产生了兴趣,并遇到了这个问题。如果您阅读urllib3User Guide”页面,您会看到:

<块引用>

对于 POST 和 PUT 请求,您需要在 URL 中手动编码查询参数

您的代码应调整为如下所示:

import urllib3
from urllib.parse import urlencode

data = {"description":"Tenaris",
        "ticker":"TS.BA",
        "industry":"Metalúrgica",
        "currency":"ARS"}

http = urllib3.PoolManager()
encoded_data = urlencode(data)
http.request('POST',
             'http://localhost:8080/assets?'+encoded_data,
             headers={'Content-Type':'application/json'})