如何使用bash在curl中翻译此代码在python中请求

时间:2019-02-19 14:04:31

标签: python curl arduino pycurl

我正在尝试翻译一个可与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)

1 个答案:

答案 0 :(得分:0)

您的curlrequests命令不相同。

使用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/