【问题标题】:how to translate this code in curl using bash to request in python如何使用 bash 在 curl 中翻译此代码以在 python 中请求
【发布时间】:2019-02-19 14:04:30
【问题描述】:

我正在尝试翻译一个与 curl 一起使用的 bash 脚本,以将代码远程发送到大型 Arduino,使用 ESP01 作为具有 ESP-link 固件的程序员,完成该工作的 bash 脚本总结在几行,是这样的:

   #! /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)

【问题讨论】:

  • 如果你测试没有超时,会发生什么?
  • 它永远不会中断加载,但是几秒钟后微控制器停止等待代码,并重新启动,代码必须在同步后20秒之前加载。

标签: python curl arduino pycurl


【解决方案1】:

您的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/

【讨论】:

  • 非常感谢,正是发生了什么,评论很有帮助,我不是很了解这个主题,然后我看到了微控制器的响应,我能够看到它由于您在评论中的解释,回复“请求格式错误”。
猜你喜欢
  • 2023-03-29
  • 2022-10-08
  • 1970-01-01
  • 2014-01-23
  • 2017-11-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-26
相关资源
最近更新 更多