我正在尝试翻译一个可与curl配合使用的bash脚本,以将ESP01用作具有ESP-link固件的程序员,从而将代码远程发送到大型Arduino。几行,是这样的:
#! /bin/bash
# first make a post to reset the arduino
curl -m 10 -s -w '%{http_code}' -XPOST
http://192.168.4.1/pgmmega/sync
sleep 0.5
# make a GET to Sync with it and wait for the sync
curl -s http://192.168.4.1/pgmmega/sync
sleep 0.1
#send the .hex file
curl -m 20 -s -g -d @/tmp/arduino_build_274266/SMI_6_0_1.ino.hex
http://192.168.4.1/pgmmega/upload
我在python3中的代码是:
#! /bin/python3
import requests
import time
urlsync = 'http://192.168.4.1/pgmmega/sync'
urlupload = 'http://192.168.4.1/pgmmega/upload'
file = {'upload_file':
open('/home/wander/app_llamadores/SMI_6_0_1.ino.hex', 'rb')}
rsync = requests.post(urlsync, stream=True, timeout = 5)
time.sleep(0.4)
print(rsync1.status_code) #204
rsync1 = requests.get(urlsync)
print(rsync1.status_code) #200
rupload = requests.post(urlupload, files=file, timeout=20)
print(rupload.status_code)
我尝试了该代码,尽管同步部分似乎可以正常工作,但是当我发送.hex文件时,却得到了..
Traceback (most recent call last):
File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py",
line 387, in _make_request
six.raise_from(e, None)
File "<string>", line 3, in raise_from
File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py",
line 383, in _make_request
httplib_response = conn.getresponse()
File "/usr/lib/python3.6/http/client.py", line 1331, in
getresponse
response.begin()
File "/usr/lib/python3.6/http/client.py", line 297, in begin
version, status, reason = self._read_status()
File "/usr/lib/python3.6/http/client.py", line 258, in
_read_status
line = str(self.fp.readline(_MAXLINE + 1), "iso-8859-1")
File "/usr/lib/python3.6/socket.py", line 586, in readinto
return self._sock.recv_into(b)
socket.timeout: timed out
During handling of the above exception, another exception
occurred:
Traceback (most recent call last):
File "/usr/lib/python3/dist-packages/requests/adapters.py", line
440, in send
timeout=timeout
File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py",
line 639, in urlopen
_stacktrace=sys.exc_info()[2])
File "/usr/lib/python3/dist-packages/urllib3/util/retry.py",
line 357, in increment
raise six.reraise(type(error), error, _stacktrace)
File "/usr/lib/python3/dist-packages/six.py", line 693, in
reraise
raise value
File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py",
line 601, in urlopen
chunked=chunked)
File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py",
line 389, in _make_request
self._raise_timeout(err=e, url=url, timeout_value=read_timeout)
File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py",
line 309, in _raise_timeout
raise ReadTimeoutError(self, url, "Read timed out. (read
timeout=%s)" % timeout_value)
urllib3.exceptions.ReadTimeoutError:
HTTPConnectionPool(host='192.168.4.1', port=80): Read timed
out. (read timeout=20)
During handling of the above exception, another exception
occurred:
Traceback (most recent call last):
File "./CargaFirmware.py", line 17, in <module>
rupload = requests.post(urlupload, files=file, stream=True,
timeout=20)
File "/usr/lib/python3/dist-packages/requests/api.py", line 112,
in post
return request('post', url, data=data, json=json, **kwargs)
File "/usr/lib/python3/dist-packages/requests/api.py", line 58,
in request
return session.request(method=method, url=url, **kwargs)
File "/usr/lib/python3/dist-packages/requests/sessions.py", line
520, in request
resp = self.send(prep, **send_kwargs)
File "/usr/lib/python3/dist-packages/requests/sessions.py", line
630, in send
r = adapter.send(request, **kwargs)
File "/usr/lib/python3/dist-packages/requests/adapters.py", line
521, in send
raise ReadTimeout(e, request=request)
requests.exceptions.ReadTimeout:
HTTPConnectionPool(host='192.168.4.1', port=80): Read timed
out. (read timeout=20)
答案 0 :(得分:0)
您的curl
和requests
命令不相同。
使用curl,您可以直接在请求正文中进行HTTP POST数据。对于请求,您将(隐式)创建“多部分编码”表单数据,其中upload_file
字段设置为SMI_6_0_1.ino.hex
文件的内容。
查看幕后情况的简单方法是准备请求,无需发送就准备和检查请求
from requests import Request
url = "http://192.168.4.1/pgmmega/sync"
filename = "SMI_6_0_1.ino.hex"
req = Request("POST", url, files={"upload_file": open(filename, "rb")}).prepare()
print(vars(req)["body"])
# b'--052baa09bbc2f6ab52a2c9f8f2b99b3a\r\nContent-Disposition: form-data; name="upload_file"; filename="SMI_6_0_1.ino.hex"\r\n\r\n\r\n--052baa09bbc2f6ab52a2c9f8f2b99b3a--\r\n'
print(vars(req)["headers"]["Content-Type"])
# multipart/form-data; boundary=052baa09bbc2f6ab52a2c9f8f2b99b3a
和
req = Request("POST", url, data=open(filename, "rb")).prepare()
print(vars(req)["body"])
# <_io.BufferedReader name='SMI_6_0_1.ino.hex'>
print(vars(req)["headers"]["Content-Type"])
# KeyError: 'content-type'
因此,很可能requests
正在以目标服务器无法读取的格式发送文件。在这种情况下,切换到requests.post(url, data=...)
应该可以解决问题。
这不是一个罕见的问题。有一个网页,您可以在其中自行将curl
转换为requests
-https://curl.trillworks.com/