你需要改变什么,以便我的龙卷风代码可以成功发布?

huangapple go评论92阅读模式
英文:

What do I need to change so my tornado code can post successfully?

问题

以下是要翻译的内容,只包括代码部分的翻译:

import requests
from pprint import pprint
import json

PEM = '/full/path/to/my.pem'

client_id='cliendID'
client_secret='clientSecret'

USER='myuser'
PSWD='mypwd'

url = 'https://theurl.com/request/'

data = {
    "grant_type": "password",
    "username": USER,
    "password": PSWD
}

auth = (client_id, client_secret)
response = requests.post(url, auth=auth, data=data, verify=PEM)
answer = response.json()['answer']

print(answer)
curl -iv --user cliendID:clientSecret --key /full/path/to/server.key --cert /full/path/to/my.pem -F grant_type=password -F username=myuser -F password=mypwd https://theurl.com/request/
from tornado.httpclient import AsyncHTTPClient
from tornado.ioloop import IOLoop
import json

async def get_content():
    PEM = '/full/path/to/my.pem'

    client_id='cliendID'
    client_secret='clientSecret'

    url = 'https://theurl.com/request/'

    USER='myuser'
    PSWD='mypwd'

    data = {
        "grant_type": "password",
        "username": USER,
        "password": PSWD
    }

    bodyData = json.dumps(data)

    http_client = AsyncHTTPClient()
    response = await http_client.fetch(url,
                                        method='POST',
                                        body=bodyData,
                                        auth_username=client_id,
                                        auth_password=client_secret,
                                        ca_certs=PEM)

    print(response.body.decode())

async def main():
    await get_content()

if __name__ == "__main__":
    io_loop = IOLoop.current()
    io_loop.run_sync(main)

请注意,这只是提供的代码的翻译部分,不包括其他内容。如果您有其他问题或需要更多帮助,请随时告诉我。

英文:

I have the following (with some strings modified) which works when using the requests library.

import requests
from pprint import pprint
import json

PEM = '/full/path/to/my.pem'

client_id='cliendID'
client_secret='clientSecret'

USER='myuser'
PSWD='mypwd'

url = 'https://theurl.com/request/'
 
data = {
    "grant_type": "password",
    "username": USER,
    "password": PSWD
}

auth = (client_id, client_secret)
response = requests.post( url, auth=auth, data=data, verify=PEM )
answer = response.json()['answer']

print( answer )

The answer printed is what I expect.

The following usage of curl also works:

curl -iv --user cliendID:clientSecret --key /full/path/to/server.key --cert /full/path/to/my.pem -F grant_type=password -F username=myuser -F password=mypwd https://theurl.com/request/

However, when I try to do the same using Tornado and AsyncHTTPClient, I get a "Bad Request" response. Some sample Tornado code is:

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

async def get_content():
    PEM = '/full/path/to/my.pem'

    client_id='cliendID'
    client_secret='clientSecret'

    url = 'https://theurl.com/request/'

    USER='myuser'
    PSWD='mypwd'

    data = {
        "grant_type": "password",
        "username": USER,
        "password": PSWD
    }


    bodyData = json.dumps( data )

    http_client = AsyncHTTPClient()
    response = await http_client.fetch( url,
                                        method        = 'POST',
                                        body          = bodyData,
                                        auth_username = client_id,
                                        auth_password = client_secret,
                                        ca_certs      = PEM )

    print( response.body.decode() )



async def main():
    await get_content()



if __name__ == "__main__":
    io_loop = IOLoop.current()
    io_loop.run_sync(main)

If I had to guess, I believe the issue is with how I am sending the bodyData.

What do I need to change in the Tornado code so this will work...?

答案1

得分: 2

默认情况下,requests库和Tornado的AsyncHTTPClient都将请求体数据发送为表单编码数据(即使用Content-Type: application/x-www-form-urlencoded)。

requests库会自动使用正确的内容类型对数据字典进行编码。

但是,使用Tornado的客户端,您需要手动对数据进行如下编码:

from urllib.parse import urlencode

bodyData = urlencode(data)

...


错误的原因

您收到"Bad Request"错误是因为您将数据发送为JSON,但Content-Type标头(由Tornado自动发送)仍然为www-form-urlencoded。这意味着服务器无法解码您提供的数据,因为它不知道数据是JSON格式的。

英文:

By default, the requests library and Tornado's AsyncHTTPClient, both, send the body data as form encoded data (i.e. with Content-Type: application/x-www-form-urlencoded).

The requests library automatically encodes the data dict with the correct content type.

But with Tornado's client, you're requried to manually encode the data as follows:

from urllib.parse import urlencode

bodyData = urlencode(data)

...


Cause of the error:

You're getting the Bad Request error because you're sending the data as JSON but the Content-Type header (sent automatically by Tornado) still says www-form-urlencoded. That means the server can't decode your supplied data because it doesn't know that it's JSON.

huangapple
  • 本文由 发表于 2023年2月16日 03:54:23
  • 转载请务必保留本文链接:https://go.coder-hub.com/75464834.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定