OSError: [Errno 103] ECONNABORTED using urequests

All ESP8266 boards running MicroPython.
Official boards are the Adafruit Huzzah and Feather boards.
Target audience: MicroPython users with an ESP8266 board.
Post Reply
User avatar
MorseIot
Posts: 38
Joined: Fri Jun 29, 2018 12:32 am

OSError: [Errno 103] ECONNABORTED using urequests

Post by MorseIot » Thu Aug 02, 2018 5:42 pm

The following code, from time to time, displays the following error message :

Code

Code: Select all

import network
import urequests
import gc
from machine import freq

freq(160000000)

PublicKey= '8BA9FA35FEAF6A356893B577A44408A3'
SecretKey = 'D23D16F1C34F170931894E4C7914121F78C538377BE9CD3F29CC845426B31991'


def setNetworkConfig(ssid, pwd):
    # Access Point
    ap = network.WLAN(network.AP_IF)
    ap.active(False)

    wlan = network.WLAN(network.STA_IF)
    if not wlan.isconnected():
        print('connecting to network...')
        wlan.active(True)
        wlan.connect(ssid, pwd)
        while not wlan.isconnected():
            pass
    print('network config:', wlan.ifconfig())
    return

def deviceInfo(protocol,url,keyPublic,keySecret,silent=False):
    gc.collect()
    # defining the api-endpoint
    API_ENDPOINT = protocol+"://" + url + "/api/device/" + keyPublic + "/info"

    # Headers
    if keySecret is not None:
        headers = {"Content-Type": "application/json", "Authorization": "Bearer " + keySecret,'Connection': 'Close'}
    else:
        headers = {'Connection': 'Close'}

    # sending post request and saving response as response object
    response = urequests.get(url=API_ENDPOINT, headers=headers)

    #statusCode = response.status_code
    parsed = response.json()
    #parsed = response.text;

    if silent is True:
        # extracting response text
        print(parsed)

    response.close()
    API_ENDPOINT = None
    return parsed

def deviceLog(protocol,url, keyPublic, keySecret, code, message,silent=False):
    gc.collect()
    # defining the api-endpoint
    API_ENDPOINT = protocol+"://" + url + "/api/device/" + keyPublic + "/log"

    # Headers
    headers = {"Content-Type": "application/json","Authorization": "Bearer " + keySecret, 'Connection': 'Close'}

    # Body
    body = {"code": code, "message": message}

    # sending post
    response = urequests.post(url=API_ENDPOINT, headers=headers, json=body)
    parsed = response.json()

    if silent is True:
        # extracting response text
        print(parsed)

    response.close()
    API_ENDPOINT = None
    return parsed

def deviceSystemCall(protocol,url,keyPublic,keySecret,silent=False):
    gc.collect()
    # defining the api-endpoint
    API_ENDPOINT = protocol+"://" + url + "/api/device/" + keyPublic +"/system/call"

    # Headers
    headers = {"Content-Type": "application/json", "Authorization": "Bearer " + keySecret, 'Connection': 'Close'}

    # sending post request and saving response as response object
    response = urequests.patch(url=API_ENDPOINT, headers=headers)

    parsed = response.json()

    if silent is True:
        # extracting response text
        print(parsed)

    response.close()
    API_ENDPOINT = None
    return parsed

def resetCause():
    from machine import reset_cause
    code = reset_cause()
    msg = ("Power reboot","Hardware WDT reset","Fatal exception","Software watchdog reset","Software reset","Deep-sleep","Hardware reset")
    response = deviceLog('http','automacao-iot.com.br',PublicKey,SecretKey, code,msg[code],True)
    #print(response)
    return

setNetworkConfig('xxxxx','xxxxxxx')
resetCause()

while True:
    gc.collect()
    response = deviceInfo('http','automacao-iot.com.br',PublicKey,SecretKey,True)
    #print(response)

    response = deviceSystemCall('http','automacao-iot.com.br',PublicKey,SecretKey,True)
    #print(response)

    print("Free Memory ",gc.mem_free())

Error

Code: Select all

Traceback (most recent call last):
  File "main.py", line 115, in <module>
  File "main.py", line 43, in deviceInfo
  File "urequests.py", line 112, in get
  File "urequests.py", line 100, in request
  File "urequests.py", line 58, in request
OSError: [Errno 103] ECONNABORTED
What am I doing wrong ????

SpotlightKid
Posts: 463
Joined: Wed Apr 08, 2015 5:19 am

Re: OSError: [Errno 103] ECONNABORTED using urequests

Post by SpotlightKid » Thu Aug 02, 2018 11:33 pm

MorseIot wrote:
Thu Aug 02, 2018 5:42 pm
What am I doing wrong ????
You are posting sensitive information (SecretKey) on a public online forum?

Does the error occur immediately when the while loops executed for the first time or only after some iterations? Anyway, be sure to put a sleep() in the loop, you're probably spamming the server with dozen/hundreds of request per second requests and it then somehow blocks your client.

User avatar
MorseIot
Posts: 38
Joined: Fri Jun 29, 2018 12:32 am

Re: OSError: [Errno 103] ECONNABORTED using urequests

Post by MorseIot » Fri Aug 03, 2018 12:13 am

SpotlightKid wrote:
Thu Aug 02, 2018 11:33 pm
MorseIot wrote:
Thu Aug 02, 2018 5:42 pm
What am I doing wrong ????
You are posting sensitive information (SecretKey) on a public online forum?

Does the error occur immediately when the while loops executed for the first time or only after some iterations? Anyway, be sure to put a sleep() in the loop, you're probably spamming the server with dozen/hundreds of request per second requests and it then somehow blocks your client.
First- the use of the SecretKey is only for this test (can be revoked) (site automacao-iot.com.br which is an IOT platform).

Second - Use of sleep I believe not to be recommendable, may cause wdt reset.

Besides the fact that esp8266 does not execute thread, then I believe we do not have concurrent execution, it goes one request at a time and only after the response happens.

I am trying to use try: exception, where the error is not generated, but after some time running, the code stops executing, freezing the micropython console

SpotlightKid
Posts: 463
Joined: Wed Apr 08, 2015 5:19 am

Re: OSError: [Errno 103] ECONNABORTED using urequests

Post by SpotlightKid » Fri Aug 03, 2018 12:55 am

MorseIot wrote:
Fri Aug 03, 2018 12:13 am
First- the use of the SecretKey is only for this test (can be revoked) (site automacao-iot.com.br which is an IOT platform).
Still, I could use this key to test the requests you're doing e.g. with CPython from my computer. Is this ok with you?
Second - Use of sleep I believe not to be recommendable, may cause wdt reset.
Where did you get this idea from? If a normal `time.sleep()` didn't work on ESP8266 MicroPython there would be something really wrong.
Besides the fact that esp8266 does not execute thread, then I believe we do not have concurrent execution, it goes one request at a time and only after the response happens.
Yes, but a typical REST request and it's response normally only take a few milliseconds to execute, if the network connection is good and the server isn't exceptionally slow. So your loop can potentially send way too many requests per second. You should introduce some kind of rate limiting.

User avatar
MorseIot
Posts: 38
Joined: Fri Jun 29, 2018 12:32 am

Re: OSError: [Errno 103] ECONNABORTED using urequests

Post by MorseIot » Fri Aug 03, 2018 2:02 am

SpotlightKid wrote:
Fri Aug 03, 2018 12:55 am
MorseIot wrote:
Fri Aug 03, 2018 12:13 am
First- the use of the SecretKey is only for this test (can be revoked) (site automacao-iot.com.br which is an IOT platform).
Still, I could use this key to test the requests you're doing e.g. with CPython from my computer. Is this ok with you?
Second - Use of sleep I believe not to be recommendable, may cause wdt reset.
Where did you get this idea from? If a normal `time.sleep()` didn't work on ESP8266 MicroPython there would be something really wrong.
Besides the fact that esp8266 does not execute thread, then I believe we do not have concurrent execution, it goes one request at a time and only after the response happens.
Yes, but a typical REST request and it's response normally only take a few milliseconds to execute, if the network connection is good and the server isn't exceptionally slow. So your loop can potentially send way too many requests per second. You should introduce some kind of rate limiting.
Where did you get this idea from? If a normal `time.sleep()` didn't work on ESP8266 MicroPython there would be something really wrong.
I did not say that sleep does not work in ESP, I said that it is not recommended in some cases, in my case for example
Still, I could use this key to test the requests you're doing e.g. with CPython from my computer. Is this ok with you?
use this keys
public = 1E9AA74A730F5847CB193D552D901C81
secret = BD5E37A21BB3971ACB94E3D1388ABE9014A7D50BE34F4D52415DCFC84EB81642

if you want you can create an account on the server www.automacao-iot.com.br, which is free to use so far

What I'm debugging, I believe is a request timeout problem, since urequest has no timeout parameter, I'll try to pass the keep-alive header

Thanks anyway for the help

eradicatore
Posts: 52
Joined: Thu Apr 20, 2017 9:19 pm

Re: OSError: [Errno 103] ECONNABORTED using urequests

Post by eradicatore » Sat Mar 09, 2019 2:16 pm

Hi,
Thanks for this question! I'm just hitting the exact same failure. My code is tiny simple button press handling to trigger posts of json to control a music player, and even with some delays I hit this same ECONNABORTED. This fellow has the same issues it seems:

https://stackoverflow.com/questions/524 ... g-requests

Just curious, were you able to solve this issue ever? I'll keep trying different delays, but whats interesting is Postman can spam these requests as fast as I want. So is this an issue with urequests choking on the size of the response? Is there a check to see if urequests is still "busy"?

Here was my latest version of code

Code: Select all

from machine import Pin
import urequests
import time
import json
import network
import re

btn1 = Pin(12, Pin.IN, Pin.PULL_UP)
btn2 = Pin(12, Pin.IN, Pin.PULL_UP)

## URL for SqueezeServer
url = "http://localhost:9000/jsonrpc.js"

def do_connect():
    import network
    sta_if = network.WLAN(network.STA_IF)
    if not sta_if.isconnected():
        print('connecting to network...')
        sta_if.active(True)
        sta_if.connect('myssid', 'mypasswordhere')
        while not sta_if.isconnected():
            pass
    print('network config:', sta_if.ifconfig())


do_connect()
data_play = { "method": "slim.request", "params": [ "12:34:56:78:99", [ "button", "pause.single" ] ], "id": 0 }

while True:
    time.sleep_ms(250)

    if (btn1.value() == 0):
        r = urequests.post(url, data=json.dumps(data_play))
        time.sleep_ms(650)
        while (btn1.value() == 0):
            time.sleep_ms(200)      
            pass

eradicatore
Posts: 52
Joined: Thu Apr 20, 2017 9:19 pm

Re: OSError: [Errno 103] ECONNABORTED using urequests

Post by eradicatore » Sat Mar 09, 2019 3:03 pm

Ok, garbage collection solved it. Now I can press the button and it works every time! I may tweak the delays to get as tight as possible. Would be nice to query the urequests if busy instead of just a crude delay, but hey...

Here's the new loop at the end:

Code: Select all

gc.enable()

while True:
    time.sleep_ms(250)

    if (btn1.value() == 0):
        urequests.post(url, data=json.dumps(data_play))
        time.sleep_ms(650)
        while (btn1.value() == 0):
            time.sleep_ms(200)
            pass
        gc.collect()

eradicatore
Posts: 52
Joined: Thu Apr 20, 2017 9:19 pm

Re: OSError: [Errno 103] ECONNABORTED using urequests

Post by eradicatore » Wed Mar 13, 2019 6:29 pm

Ok, Just learned from the other thread a better solution:
Thanks for this. I ended up going a different route, but I'll give this a try. The solution I found was to realise urequests.post() returns a response, so response = urequests.post(url) followed by response.close() appears to handle the cleanup. It may work for you.
I believe that's the real answer here, and my work around was just a hack way of doing the same things since response got out of scope. But my way is way more inefficient.

Post Reply