如何将 POST 中的整数发送到 Tornado 的 AsyncHTTPTestCase.fetch()?

How to send integer in POST to Tornado's AsyncHTTPTestCase.fetch()?

我正在使用 python 的 Tornado 框架来测试我的 HTTP POST 端点。为此,我使用了 fetch 方法。

    data = urllib.urlencode({
        'integer_arg': 1,
        'string_arg': 'hello'
    })

    resp = AsyncHTTPTestCase.fetch('/endpoint', 
                                   method='POST',
                                   headers={'h1': 'H1', 
                                            'h2': 'H2',
                                            'Content-Type': 'application/json'}, 
                                   body=data)

当我这样做时,端点接收 integer_arg 作为字符串 "1",即使我希望它接收它作为整数。这是可以理解的,因为 urllib.urlencode 将其转换为字符串。 那么我怎样才能确保它接收到一个整数呢? 仅仅消除对 urllib.urlencode 的调用是行不通的。

顺便说一句,当我使用如下所示的裸 curl 调用访问同一个端点时,端点正确接收 integer_arg 作为整数 1

curl \
--request POST \
--header "h1: H1" \
--header "h2: H2" \
--header "Content-Type: application/json" \
--data '{
    "integer_arg": 1, 
    "string_arg": "hello"
}' \
"http://localhost:8000/endpoint"

curl中的body与AsyncHTTPClient.fetch中的明显不同。使用 python,您对 curl 中的数据进行 urlencode,只有 json。因此,只需将 urlencode 更改为 json.dumps:

import json
from tornado.ioloop import IOLoop
from tornado.httpclient import AsyncHTTPClient
from tornado.gen import coroutine

@coroutine
def main():
    client = AsyncHTTPClient()
    body = json.dumps({
        'integer_arg': 1,
        'string_arg': 'hello'
    })
    yield client.fetch(
        '/endpoint', method='POST', body=body,
         headers={'h1': 'H1',  'h2': 'H2', 'Content-Type': 'application/json'}
    )

ioloop = IOLoop.instance()
ioloop.run_sync(main)