Python 3使用标准库发送带有文件的请求。

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

Python 3 send a request with a file using only standard libraries

问题

所以我有以下的代码,它使用requests库工作正常:

  1. file_test = {'file': ('test.json', open('C:/Users/abc/test.json','rb'), 'application/json')}
  2. response = requests.post(url, files=file_test, verify=False)

这段代码按预期工作。但最近公司要求我们只使用标准库。所以我尝试使用http.client库来完成完全相同的事情:

  1. httpHost = 'some host'
  2. uri = 'some uri'
  3. conn = http.client.HTTPSConnection(httpHost,context = ssl._create_unverified_context())
  4. with open('C:/Users/abc/test.json','rb') as file:
  5. f = file.read()
  6. headers = {
  7. 'Content-Type': 'multipart/form-data; boundary=TESTabc123',
  8. 'Content-Length': str(len(f)),
  9. 'Accept' : '*/*'
  10. }
  11. conn.request(verb, uri, body=f, headers=headers)
  12. print(conn.getresponse().status)

然而,我在上面的代码中遇到了500状态码。顺便提一下,headers部分我从Postman中复制了完全相同的内容(在Postman中,我使用相同的文件和相同的headers获得了200的状态码)。

我是否正确地做了这件事?看起来我按照正确的步骤进行了操作,但仍然得到了不希望的结果。我还尝试了使用urllib的request库,但似乎verify=False部分在那里不起作用。

我唯一能想到的问题是请求的内容长度,在Postman中,当提供错误的长度时也会得到500错误。

英文:

So I have the following Code which is working using the requests library:

  1. file_test = {'file': ('test.json', open('C:/Users/abc/test.json','rb'), 'application/json')}
  2. response = requests.post(url, files=file_test, verify=False)

which works as expected. But recently company want us to use only standard libraries. So I went ahead to try out http.client library to accomplish the exact same thing:

  1. httpHost = 'some host'
  2. uri = 'some uri'
  3. conn = http.client.HTTPSConnection(httpHost,context = ssl._create_unverified_context())
  4. with open('C:/Users/abc/test.json','rb') as file:
  5. f = file.read()
  6. headers = {
  7. 'Content-Type': 'multipart/form-data; boundary=TESTabc123',
  8. 'Content-Length': str(len(f)),
  9. 'Accept' : '*/*'
  10. }
  11. conn.request(verb, uri, body=f, headers=headers)
  12. print(conn.getresponse().status)

However, I am hitting a 500 status code with the above code. Just to mention, the headers part I pulled the exact same thing from postman (I was able to get a 200 on postman with the same file and same headers).

Am I doing this thing correctly? It seems like I followed everything correctly but still getting undesired results. I also tried with urllib's request library but seems like the verify=False part doesn't work on there.

The only thing I can think of is the request content length, which in postman, also gives a 500 error when wrong length is provided.

答案1

得分: 0

根据requests文档,Content-Length应该是文件中的字节数,而不是文本的长度,你可以尝试将'Content-Length': str(len(f)),改为'Content-Length': len(f),。同时确保verb = post。

如果有帮助,请告诉我 - Jack

英文:

According to the requests documentation, the Content-Length should be the number of bytes in the file, not the length of the text, could you try changing 'Content-Length': str(len(f)), to 'Content-Length': len(f),.
Also make sure verb = post.

Let me know if that Helps - Jack

答案2

得分: 0

  1. import http.client
  2. import ssl
  3. httpHost = '某个主机'
  4. uri = '某个路径'
  5. boundary = 'TESTabc123'
  6. conn = http.client.HTTPSConnection(httpHost,
  7. context=ssl._create_unverified_context())
  8. with open('C:/Users/abc/test.json', 'rb') as file:
  9. f = file.read()
  10. body = (
  11. f'--{boundary}\r\n'
  12. f'Content-Disposition: form-data; name="file"; filename="test.json"\r\n'
  13. 'Content-Type: application/json\r\n\r\n'
  14. f'{f.decode()}\r\n'
  15. f'--{boundary}--\r\n'
  16. )
  17. headers = {
  18. 'Content-Type': f'multipart/form-data; boundary={boundary}',
  19. 'Content-Length': str(len(body)),
  20. 'Accept': '*/*'
  21. }
  22. conn.request('POST', uri, body=body, headers=headers)
  23. print(conn.getresponse().status)
英文:
  1. import http.client
  2. import ssl
  3. httpHost = 'some host'
  4. uri = 'some uri'
  5. boundary = 'TESTabc123'
  6. conn = http.client.HTTPSConnection(httpHost,
  7. context=ssl._create_unverified_context())
  8. with open('C:/Users/abc/test.json', 'rb') as file:
  9. f = file.read()
  10. body = (
  11. f'--{boundary}\r\n'
  12. f'Content-Disposition: form-data; name="file"; filename="test.json"\r\n'
  13. 'Content-Type: application/json\r\n\r\n'
  14. f'{f.decode()}\r\n'
  15. f'--{boundary}--\r\n'
  16. )
  17. headers = {
  18. 'Content-Type': f'multipart/form-data; boundary={boundary}',
  19. 'Content-Length': str(len(body)),
  20. 'Accept': '*/*'
  21. }
  22. conn.request('POST', uri, body=body, headers=headers)
  23. print(conn.getresponse().status)

I think this will be better

huangapple
  • 本文由 发表于 2023年8月9日 13:41:56
  • 转载请务必保留本文链接:https://go.coder-hub.com/76864874.html
匿名

发表评论

匿名网友

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

确定