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

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

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

问题

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

  1. import requests
  2. from pprint import pprint
  3. import json
  4. PEM = '/full/path/to/my.pem'
  5. client_id='cliendID'
  6. client_secret='clientSecret'
  7. USER='myuser'
  8. PSWD='mypwd'
  9. url = 'https://theurl.com/request/'
  10. data = {
  11. "grant_type": "password",
  12. "username": USER,
  13. "password": PSWD
  14. }
  15. auth = (client_id, client_secret)
  16. response = requests.post(url, auth=auth, data=data, verify=PEM)
  17. answer = response.json()['answer']
  18. print(answer)
  1. 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/
  1. from tornado.httpclient import AsyncHTTPClient
  2. from tornado.ioloop import IOLoop
  3. import json
  4. async def get_content():
  5. PEM = '/full/path/to/my.pem'
  6. client_id='cliendID'
  7. client_secret='clientSecret'
  8. url = 'https://theurl.com/request/'
  9. USER='myuser'
  10. PSWD='mypwd'
  11. data = {
  12. "grant_type": "password",
  13. "username": USER,
  14. "password": PSWD
  15. }
  16. bodyData = json.dumps(data)
  17. http_client = AsyncHTTPClient()
  18. response = await http_client.fetch(url,
  19. method='POST',
  20. body=bodyData,
  21. auth_username=client_id,
  22. auth_password=client_secret,
  23. ca_certs=PEM)
  24. print(response.body.decode())
  25. async def main():
  26. await get_content()
  27. if __name__ == "__main__":
  28. io_loop = IOLoop.current()
  29. io_loop.run_sync(main)

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

英文:

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

  1. import requests
  2. from pprint import pprint
  3. import json
  4. PEM = '/full/path/to/my.pem'
  5. client_id='cliendID'
  6. client_secret='clientSecret'
  7. USER='myuser'
  8. PSWD='mypwd'
  9. url = 'https://theurl.com/request/'
  10. data = {
  11. "grant_type": "password",
  12. "username": USER,
  13. "password": PSWD
  14. }
  15. auth = (client_id, client_secret)
  16. response = requests.post( url, auth=auth, data=data, verify=PEM )
  17. answer = response.json()['answer']
  18. print( answer )

The answer printed is what I expect.

The following usage of curl also works:

  1. 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:

  1. from tornado.httpclient import AsyncHTTPClient
  2. from tornado.ioloop import IOLoop
  3. import json
  4. async def get_content():
  5. PEM = '/full/path/to/my.pem'
  6. client_id='cliendID'
  7. client_secret='clientSecret'
  8. url = 'https://theurl.com/request/'
  9. USER='myuser'
  10. PSWD='mypwd'
  11. data = {
  12. "grant_type": "password",
  13. "username": USER,
  14. "password": PSWD
  15. }
  16. bodyData = json.dumps( data )
  17. http_client = AsyncHTTPClient()
  18. response = await http_client.fetch( url,
  19. method = 'POST',
  20. body = bodyData,
  21. auth_username = client_id,
  22. auth_password = client_secret,
  23. ca_certs = PEM )
  24. print( response.body.decode() )
  25. async def main():
  26. await get_content()
  27. if __name__ == "__main__":
  28. io_loop = IOLoop.current()
  29. 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的客户端,您需要手动对数据进行如下编码:

  1. from urllib.parse import urlencode
  2. bodyData = urlencode(data)
  3. ...

错误的原因

您收到"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:

  1. from urllib.parse import urlencode
  2. bodyData = urlencode(data)
  3. ...

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:

确定