как перевести этот код в curl, используя bash для запроса в python - PullRequest
0 голосов
/ 19 февраля 2019

Я пытаюсь перевести сценарий bash, который работает с curl, для удаленной отправки кода в мега 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)

1 Ответ

0 голосов
/ 20 февраля 2019

Ваши команды curl и requests не эквивалентны.

С помощью curl вы отправляете данные HTTP POST непосредственно в теле запроса.С запросами вы (неявно) создаете данные формы MultiPart Encoded с полем 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/

...