adafruit / Adafruit_CircuitPython_Requests

Requests-like interface for web interfacing
MIT License
51 stars 36 forks source link

Setting up requests repeatedly (3 times) results in runtime error #62

Closed askpatrickw closed 1 year ago

askpatrickw commented 3 years ago

Originally I ran into this using AIO time service, but I can reproduce just using requests.

Simplified Test

wifi.radio.connect(config.SSID, config.WIFI_PASSWORD)
POOL = socketpool.SocketPool(wifi.radio)

while True:
    REQUESTS = adafruit_requests.Session(POOL, ssl.create_default_context())
    response = REQUESTS.get("http://wifitest.adafruit.com/testwifi/index.html")
    sleep(SLEEP_TIME)

Always on the 3rd attempt I get this error:

Traceback (most recent call last):
  File "code.py", line 23, in <module>
  File "adafruit_requests.py", line 595, in get
  File "adafruit_requests.py", line 559, in request
  File "adafruit_requests.py", line 428, in _get_socket
RuntimeError: Sending request failed

Workaround Setup requests before the while loop.

Dcai169 commented 3 years ago

I am also having this issue. I can't send more than two requests without an error.

anecdata commented 3 years ago

REQUESTS = adafruit_requests.Session(POOL, ssl.create_default_context()) only needs to be done once, rather than in the loop. ESP32-S2 is currently limited to 4 simultaneous sockets, HTTPS/TLS uses two per transaction.

This code runs indefinitely:

print("Connecting...")
wifi.radio.connect(secrets["ssid"], secrets["password"])

pool = socketpool.SocketPool(wifi.radio)

REQUESTS = adafruit_requests.Session(pool, ssl.create_default_context())

loop = 1
while True:
    print("loop", loop)
    response = REQUESTS.get("https://httpbin.org/get")
    print(response.status_code, response.reason)
    time.sleep(5)
    loop += 1
Dcai169 commented 3 years ago

ESP32-S2 is currently limited to 4 simultaneous sockets, HTTPS/TLS uses two per transaction.

I assume that sockets are automatically freed when the transaction is finished?

anecdata commented 3 years ago

Certainly if you close the response or use a context manager. And I think also if the server closes the socket or if there are certain client socket errors, the client will detect that and close the socket. There's also an optimization to use the same socket (if it still exists) when you re-connect to the same protocol/address/port within a Session. I haven't looked at the library to see what happens when you create more than one Session.

There can be only one pool.

wavesailor commented 2 years ago

I came across this problem too on my MagTag. I was not using socket pool but doing multiple requests. Some of my requests were "automatic" (to Adafruit IO) and some I initiated to OpenWeather API. I would get the error below:

  File "code.py", line 53, in <module>
  File "adafruit_requests.py", line 595, in get
  File "adafruit_requests.py", line 559, in request
  File "adafruit_requests.py", line 428, in _get_socket
RuntimeError: Sending request failed

What seems to be the problem for me is the mixture of auto-connecting to wifi and the automatic requests to AIO for time and my own requests. What I did to get around the problem was make the connection to wifi manually and to put each of my requests and the automatic ones in their own function. But it still would be nice to figure what the error is - could this error not perhaps include more info about what is wrong as it is very difficult to track down?

askpatrickw commented 2 years ago

As I re-read all this slowly and with 11 month older brain, I believe the common issue is where in the code you are creating the Radio and the Requests objects and if you're doing so in such a manner they are called more than once thus using up the sockets as Anecdata mentions here: https://github.com/adafruit/Adafruit_CircuitPython_Requests/issues/62#issuecomment-865173242

I'm going to refactor all my reusable code (initialize the network, setup the system time, etc..) so you have to pass them a Radio and\or a Requests object from the main code.py and not also inside a While loop.

If when I've done that, if I can't reproduce this I'll close it.

askpatrickw commented 2 years ago

If you want to play along ...

import alarm
import socketpool
import ssl
import time
import wifi

import adafruit_requests

print(f"Wake Reason: {alarm.wake_alarm}")

# Get secrets
try:
    from secrets import secrets
except ImportError:
    print("Secrets are kept in secrets.py, please add them there!")
    raise

# Setup Requests
radio = wifi.radio
pool = socketpool.SocketPool(radio)
requests = adafruit_requests.Session(pool, ssl.create_default_context())

radio.connect(secrets['ssid'], secrets['wifi_password'])

print("Request 1")
response = requests.get("https://httpbin.org/get")
print(response.status_code, response.reason)

print("Request 2")
response = requests.get("https://requestbin.net/r/5h8k316q")
print(response.status_code, response.reason)

print("Request 3")
response = requests.get("https://io.adafruit.com/api/v2/time/seconds")
print(response.status_code, response.reason)

# Create a an alarm that will trigger requested number of seconds from now.
time_alarm = alarm.time.TimeAlarm(monotonic_time=time.monotonic() + 300)
# Exit and deep sleep until the alarm wakes us.
alarm.exit_and_deep_sleep_until_alarms(time_alarm)

It is definitely not working reliably.

[tio 12:18:07] Connected

Code stopped by auto-reload.
soft reboot

Auto-reload is on. Simply save files over USB to run them or enter REPL to disable.
code.py output:
Wake Reason: None
Request 1
200 bytearray(b'OK')
Request 2
200 bytearray(b'OK')
Request 3
200 bytearray(b'OK')

Code done running.

Press any key to enter the REPL. Use CTRL-D to reload.
Pretending to deep sleep until alarm, CTRL-C or file write.
Woken up by alarm.
soft reboot

Auto-reload is on. Simply save files over USB to run them or enter REPL to disable.
code.py output:
Wake Reason: <TimeAlarm>
Request 1
Traceback (most recent call last):
  File "code.py", line 26, in <module>
  File "adafruit_requests.py", line 613, in get
  File "adafruit_requests.py", line 578, in request
OutOfRetries: Repeated socket failures

Code done running.

Press any key to enter the REPL. Use CTRL-D to reload.
anecdata commented 2 years ago

I do often get OutOfRetries: Repeated socket failures after wifi is freshly enabled, but retrying almost always works. Sometimes it works first time every time, other times I'll have a string of requests where the 1st try doesn't work but the first retry does. There are some quirks in how Requests interacts with ESP32-S2, or perhaps in how network issues present themselves.

askpatrickw commented 2 years ago

I added a bunch of print statements and I see this pattern (which I don't understand).

When it works, before the sock.connect((connect_host, port)), self._socket_free is empty '_socket_free': {} and when it fails it has '_socket_free': {<SSLSocket>: True} when entering _get_socket.

Also, it never gets to more than the 2nd retry.

[tio 14:36:30] Connected
Wake Reason: None
entering Session __init__

# This works

946684814 Request 1
entering requests
entering _get_socket
key: ('io.adafruit.com', 443, 'https:')
_get_socket Session: {
    '_last_response': None, '_socket_free': {}, '_open_sockets': {}, 
    '_socket_pool': <SocketPool>, '_ssl_context': <SSLContext>}
retry_count: 1
set sock to Socket
    sock: <Socket>
set sock to SSL wrapped Socket
    sock: <SSLSocket>
try to connect with sock:<SSLSocket> io.adafruit.com:443
    _get_socket Session: {'_last_response': None, '_socket_free': {},
        '_open_sockets': {}, '_socket_pool': <SocketPool>,
        '_ssl_context': <SSLContext>}
entering _send_request
entering _send
entering _send
entering _send
entering _send
entering _send
entering _send
entering _send
entering _send
entering _send
entering _free_socket
System Time: struct_time(tm_year=2021, tm_mon=11, tm_mday=25, tm_hour=22,
    tm_min=36, tm_sec=42, tm_wday=3, tm_yday=329, tm_isdst=-1)

# This Fails

1637879806 Request 2
entering requests
entering _get_socket
key: ('httpbin.org', 443, 'https:')
_get_socket Session: {'_last_response': None,
    '_socket_free': {<SSLSocket>: True},
    '_open_sockets': {('io.adafruit.com', 443, 'https:'): <SSLSocket>},
    '_socket_pool': <SocketPool>, '_ssl_context': <SSLContext>}

# First attempt: We have an old sock for the last request

retry_count: 1
set sock to Socket
    sock: <Socket>
set sock to SSL wrapped Socket
    sock: <SSLSocket>
try to connect with sock:<SSLSocket> httpbin.org:443
    _get_socket Session: {'_last_response': None,
        '_socket_free': {<SSLSocket>: True},
        '_open_sockets': {('io.adafruit.com', 443, 'https:'): <SSLSocket>},
        '_socket_pool': <SocketPool>, '_ssl_context': <SSLContext>}

# Clean that up by freeing and closing.

call free socket
entering _free_sockets
entering _close_socket

# Try again

retry_count: 2
set sock to Socket
    sock: <Socket>
set sock to SSL wrapped Socket
    sock: <SSLSocket>
try to connect with sock:<SSLSocket> httpbin.org:443
    _get_socket Session: {'_last_response': None, '_socket_free': {},
        '_open_sockets': {}, '_socket_pool': <SocketPool>,
        '_ssl_context': <SSLContext>}

# I think `common_hal_socketpool_socket_connect` has failed in some way
# over in CP Core Land: common_hal_socketpool_socket_connect
# https://github.com/adafruit/circuitpython/blob/main/ports/espressif/common-hal/socketpool/Socket.c#L147

# But there is nothing to clean up so it bails.

no _socket_free.items()
    _get_socket Session: {'_last_response': None, '_socket_free': {},
        '_open_sockets': {}, '_socket_pool': <SocketPool>,
        '_ssl_context': <SSLContext>}
Traceback (most recent call last):
  File "code.py", line 39, in <module>
  File "/lib/adafruit_requests.py", line 612, in get
  File "/lib/adafruit_requests.py", line 553, in request
  File "/lib/adafruit_requests.py", line 417, in _get_socket
RuntimeError: Sending request failed
askpatrickw commented 2 years ago

It was failing almost every time on the 2nd request or sometime on the 2nd loop (after the timer). I tried replacing all the sites I was using and the test works way better, but it will eventually fail off in C-land and one time I had a hard fault. 👀

I'm running it some more with the latest released version, but so far much better with "better" endpoints.

import alarm
import rtc
import socketpool
import ssl
import time
import wifi

import adafruit_requests

print(f"Wake Reason: {alarm.wake_alarm}")

# Get secrets
try:
    from secrets import secrets
except ImportError:
    print("Secrets are kept in secrets.py, please add them there!")
    raise

# Setup Requests
radio = wifi.radio
radio.connect(secrets['ssid'], secrets['wifi_password'])

pool = socketpool.SocketPool(radio)
requests = adafruit_requests.Session(pool, ssl.create_default_context())

print(f"\n{time.time()} Request 1")
# Use Adafruit Time API
# response = requests.get("https://io.adafruit.com/api/v2/time/seconds")
# if response:
#     if response.status_code == 200:
#         r = rtc.RTC()
#         r.datetime = time.localtime(int(response.text))
#         print(f"System Time: {r.datetime}")
#     else:
#         print("Setting time failed")

# Use Word Time API
response = requests.get("http://worldtimeapi.org/api/timezone/GMT")
print(response.status_code, response.reason)
if response:
    if response.status_code == 200:
        r = rtc.RTC()
        r.datetime = time.localtime(int(response.json()['unixtime']))
        print(f"System Time: {r.datetime}")
    else:
        print("Setting time failed")

print(f"\n{time.time()} Request 2")
response = requests.get("https://www.google.com/humans.txt")
print(response.status_code, response.reason)

print(f"\n{time.time()} Request 3")
response = requests.get("https://www.amazon.com/robots.txt")
print(response.status_code, response.reason)

print(f"\n{time.time()} Request 4")
response = requests.get("https://www.bing.com/robots.txt")
print(response.status_code, response.reason)

# Create a an alarm that will trigger requested number of seconds from now.
time_alarm = alarm.time.TimeAlarm(monotonic_time=time.monotonic() + 120)
# Exit and deep sleep until the alarm wakes us.
alarm.exit_and_deep_sleep_until_alarms(time_alarm)
anecdata commented 2 years ago

Are you using a CP version since https://github.com/adafruit/circuitpython/pull/5562 that cured some hardfaults?

anecdata commented 2 years ago

I'm running the above code now with Adafruit CircuitPython 7.1.0-beta.0 on 2021-11-12; Saola 1 w/Wrover with ESP32S2 (actually a DevKit-C but code-wise identical), with the addition of two of the links from the prior example (6 total, but not requestbin that's 404 for me). Should I be doing this in pretend deep sleep, or real deep sleep, or doesn't matter? Just a handful of loops so far, I'll update after it runs for a while or stops on its own.

askpatrickw commented 2 years ago

If I see the hard fault again, I'll try that. I only saw it once.

I was running it with io.adafruit.com and httpbin.org back in the loop as the "better" endpoints were working very reliably and I'm wondering it there's a problem with the services. Because it does seem to fail more often.

I'm running on a FetherS2 Pre-Release with 7.0

Pretending to deep sleep until alarm, CTRL-C or file write.
Woken up by alarm.
soft reboot

Auto-reload is on. Simply save files over USB to run them or enter REPL to disable.
code.py output:
Wake Reason: <TimeAlarm>

1638140152 Request 1
System Time: struct_time(tm_year=2021, tm_mon=11, tm_mday=28, tm_hour=22, tm_min=55, tm_sec=55, tm_wday=6, tm_yday=332, tm_isdst=-1)

1638140155 Request 2
Traceback (most recent call last):
  File "code.py", line 49, in <module>
  File "/lib/adafruit_requests.py", line 603, in get
  File "/lib/adafruit_requests.py", line 544, in request
  File "/lib/adafruit_requests.py", line 439, in _get_socket
RuntimeError: Repeated socket failures

Code done running.
anecdata commented 2 years ago

I've been running those 6 URLs looping through pretend deep sleep for about 3-1/2 hours with no hiccups, but clearly some conditions are causing issues at times. Networking is bound to be error-prone, so long-running code will need to catch and handle exceptions in some way. But I think our goal is for the core and Requests to be as resilient and friendly as possible. If we can find patterns or predictability, that may be the best bet for fixes. I'll leave it going and see how it goes.

Update: after 4 hours running, failed with

Traceback (most recent call last):
  File "code.py", line 65, in <module>
  File "adafruit_requests.py", line 613, in get
  File "adafruit_requests.py", line 554, in request
  File "adafruit_requests.py", line 423, in _get_socket
RuntimeError: Sending request failed

on the adafruit link. I'd ordinarily catch and retry intermittent exceptions like that.

Update: I modified each request like this and I'll let it run overnight:

try:
    with requests.get("https://httpbin.org/get") as response:
        print(response.status_code, response.reason)
except RuntimeError as ex:
    print("🛑", ex)

I don't know if leaving prior responses unclosed has any consequences when there's an exception (for example, the socket may not get drained, and then...?)

Update: It ran all night with those changes, occasional Sending request failed, usually on the adafruit link. But otherwise chugging along. Not sure the root cause of that exception.

askpatrickw commented 2 years ago

I think we're seeing the same thing now. You get bonus points for using emoji in your print(). Ultimately I think the issue is in the Core not in this library.

I was looking at porting rety or tenacity, but they all require large swaths of Python libraries CP does not have and probably shouldn't have (too big).

If using requests should always involve a try, should we update all the samples to show that and document it? The other issue is the recovery... website\networks are intermittently down or unavailable but having my project stop working because of that is not a great experience. We should offer advice about that.

askpatrickw commented 2 years ago

I also plan to run this in debug on my Kaluga, and see if I can gather more info on the CP part, I just have to make time to do that.

MadMaxMcKinney commented 2 years ago

Following this discussion as I'm facing what I think is a similar issue? Some education on this topic would be really helpful. I've got a MatrixPortal that I use to look at some Adafruit IO feeds (although I think I want to move to MQTT), and then based on their info the portal will change between "Free" and "Busy", pretty simple!

However after random amounts of time, it will stop responding altogether. The best error I was able to get from the serial in MU was: "An error occured, retrying! 1 - Error response to command" and An error occurred, retrying 1 - repeated socket failures I would see this error hundreds of times and then it would disconnect from my PC.

Is the general consensus to wrap the network requests in a try/except and on the except we just do a pass?

Full code below:

import time
import random
import board
import terminalio
import displayio
import neopixel
from digitalio import DigitalInOut, Direction, Pull
from adafruit_matrixportal.matrixportal import MatrixPortal
from adafruit_bitmap_font import bitmap_font
from adafruit_display_text.label import Label
from adafruit_display_shapes.rect import Rect
from adafruit_matrixportal.network import Network

# --- Vars
UPDATE_DELAY = 3
IS_BUSY = True
IS_DIMMED = False
# ---

# --- Display setup ---
matrixportal = MatrixPortal(debug=False)
display = matrixportal.display

# Turn off onboard neopixel
pixels = neopixel.NeoPixel(board.NEOPIXEL, 1)
pixels[0] = (0, 0, 0)

# Create groups to hold content
contentGroup = displayio.Group()

# --- Content ---
# Background object
background = Rect(0,0,64,32, fill=0x000000)

contentGroup.append(background)

# Create status label (with a default y spacing for the 'connecting' text
font = bitmap_font.load_font("/IBMPlexMono-Medium-24_jep.bdf")
status_label = Label(font,y=14)
# Default text show as connecting, once the internet connection has happened it will resume the code flow and update the text
status_label.text = "..."

contentGroup.append(status_label)
# ---

def update_bg():
    # Pop the background off the bottom of the stack
    background = contentGroup.pop(0)

    # Change the background color of the background
    if IS_BUSY:
        background.fill = 0xFF0000
    else:
        background.fill = 0x00FF00
    # Insert the modified background back at the bottom of the stack
    contentGroup.insert(0, background)

def update_text():
    # Set status text
    status_label.text = "BUSY" if IS_BUSY else "FREE"

    # Set status text position
    # Get the bouding box info from the label component so we can center it. I subtract 1 from the final value to offset it due to the custom font sizing.
    bbx, bby, bbwidth, bbh = status_label.bounding_box
    status_label.x = round((display.width / 2 - bbwidth / 2) - 1)
    status_label.y = display.height // 2

def fetch_updates():
    # print("Fetching status...")

    # Returns a JSON object as a python dict object from the selected AdafruitIO feed
    meetingFeed = matrixportal.get_io_feed("meeting-status.inmeeting")
    meetingValue = meetingFeed['last_value']

    isDimmedFeed = matrixportal.get_io_feed("meeting-status.isdimmed")
    isDimmedValue = isDimmedFeed['last_value']

    # Update the value with the converted string
    global IS_BUSY
    IS_BUSY = str_to_bool(meetingValue)

    global IS_DIMMED
    IS_DIMMED = str_to_bool(isDimmedValue)

def update_screen():
    fetch_updates()
    update_bg()
    update_text()

def str_to_bool(s):
    if s == 'True':
         return True
    elif s == 'False':
         return False
    else:
         raise ValueError # evil ValueError that doesn't tell you what the wrong value was

# --- Initial display ---
display.show(contentGroup)
update_screen()

# --- Loop ---
while True:

    # Check if dimmed, then hide content
    # Once a bug within Circuitpython has been fixed I can use display.brightness
    # https://github.com/adafruit/circuitpython/issues/3664
    if IS_DIMMED:
        display.brightness = 0
    else:
        display.brightness = 1

    try:
        update_screen()
        time.sleep(UPDATE_DELAY)
    except Exception as ex:
        template = "An exception of type {0} occurred. Arguments:\n{1!r}"
        message = template.format(type(ex).__name__, ex.args)
        # print(message)
kabcasa commented 2 years ago

it seems that my case seems similar in the sense that I cannot manage for this url to retrieve the json response. "http://calendar2.priyom.org/events?timeMin=2022-03-04T00:00:00.000Z&amp;timeMax=2022-03-05T00:00:00.000Z" To check I took a common example. The execution succeeds with the error: File "adafruit_requests.py", line 563, in _get_socket RuntimeError: Sending request failed

I had no problem getting the response with a requests on a python3 script.

Currently my internet connection is a little weak and I suspect that this is the cause. To confirm I would have liked someone with a better connection to do the test

<

import board
import busio
from digitalio import DigitalInOut
import adafruit_requests as requests
import adafruit_esp32spi.adafruit_esp32spi_socket as socket
from adafruit_esp32spi import adafruit_esp32spi

try:
    from secrets import secrets
except ImportError:
    print("WiFi secrets are kept in secrets.py, please add them there!")
    raise

print("ESP32 SPI webclient test")

TEXT_URL = "http://wifitest.adafruit.com/testwifi/index.html"
JSON_URL = "http://calendar2.priyom.org/events?timeMin=2022-03-04T00:00:00.000Z&amp;timeMax=2022-03-05T00:00:00.000Z"

esp32_cs = DigitalInOut(board.ESP_CS)
esp32_ready = DigitalInOut(board.ESP_BUSY)
esp32_reset = DigitalInOut(board.ESP_RESET)

spi = busio.SPI(board.SCK, board.MOSI, board.MISO)
esp = adafruit_esp32spi.ESP_SPIcontrol(spi, esp32_cs, esp32_ready, esp32_reset)

requests.set_socket(socket, esp)

if esp.status == adafruit_esp32spi.WL_IDLE_STATUS:
    print("ESP32 found and in idle mode")
print("Firmware vers.", esp.firmware_version)
print("MAC addr:", [hex(i) for i in esp.MAC_address])

for ap in esp.scan_networks():
    print("\t%s\t\tRSSI: %d" % (str(ap["ssid"], "utf-8"), ap["rssi"]))

print("Connecting to AP...")
while not esp.is_connected:
    try:
        esp.connect_AP(secrets["ssid"], secrets["password"])
    except RuntimeError as e:
        print("could not connect to AP, retrying: ", e)
        continue
print("Connected to", str(esp.ssid, "utf-8"), "\tRSSI:", esp.rssi)
print("My IP address is", esp.pretty_ip(esp.ip_address))
print(
    "IP lookup adafruit.com: %s" % esp.pretty_ip(esp.get_host_by_name("adafruit.com"))
)
print("Ping google.com: %d ms" % esp.ping("google.com"))

print("Fetching text from", TEXT_URL)
r = requests.get(TEXT_URL)
print("-" * 40)
print(r.text)
print("-" * 40)
r.close()

print()
print("Fetching json from", JSON_URL)
r = requests.get(JSON_URL)
print("-" * 40)
print(r.json())
print("-" * 40)
r.close()

print("Done!")

test result :

<

ESP32 SPI webclient test
ESP32 found and in idle mode
Firmware vers. bytearray(b'1.2.2\x00')
MAC addr: ['0xcc', '0x5f', '0x43', '0xc2', '0x9d', '0x1c']
Looney2 RSSI: -35
Looney5G RSSI: -48
Looney2 RSSI: -54
Looney2 RSSI: -55
Looney2 RSSI: -56
EasyLighting_23D26FB2 RSSI: -62
Looney2 RSSI: -67
Looney2 RSSI: -73
Looney2 RSSI: -77
Looney2 RSSI: -83
Connecting to AP...
Connected to Looney5G RSSI: -47
My IP address is ..................................
IP lookup adafruit.com: ..................
Ping google.com: 130 ms
Fetching text from http://wifitest.adafruit.com/testwifi/index.html
----------------------------------------
This is a test of Adafruit WiFi!
If you can read this, its working 
----------------------------------------

Fetching json from http://calendar2.priyom.org/events?timeMin=2022-03-04T00:00:00.000Z&amp;timeMax=2022-03-05T00:00:00.000Z
Traceback (most recent call last):
File "code.py", line 68, in <module>
File "adafruit_requests.py", line 864, in get
File "adafruit_requests.py", line 758, in request
File "adafruit_requests.py", line 710, in request
File "adafruit_requests.py", line 563, in _get_socket
RuntimeError: Sending request failed

Code done running.
>
anecdata commented 2 years ago

@kabcasa Can you file a separate issue? This seems to be a different problem. The JSON file is 22k, I suspect that may have something to do with it. I doubt it's a signal strength issue. It fails for me also in the same way. If you only need some of the JSON, check out https://docs.circuitpython.org/projects/portalbase/en/latest/api.html#module-adafruit_portalbase and some examples of getting just some of the JSON, like https://learn.adafruit.com/spacex-next-launch-display-with-adafruit-magtag/code.

EDIT: I think I found the problem. The HTTP URL redirects to HTTPS (and that doesn't seem to be handled in the library). if you change the URL to HTTPS, it works. ...turns out it's a certificate issue.

kabcasa commented 2 years ago

@anecdata Thank you for your comments. Sorry but you said that it works with https but initially I had tested with https and it gives the same error for me that's why I tried with http. I need this url because with the info obtained my project is to display on a 64x32 RGB LED Matrix. For information i have tested successfully others links

ghost commented 2 years ago

@anecdata Can you speak to your last comment a bit about 22k JSON file being an issue? Is there is a size limit for memory on the ESP chip or something to be aware of? Trying to debug a related issue to this case and not sure if I am just expecting the impossible hardware-wise or if it's a software bug.

anecdata commented 2 years ago

@dsohrabian That turned out to be an incorrect supposition. There probably are RAM (and other) limits on the size of a requested payload, but they would also depend on other loaded libraries, code, which MCU, other wifi / network structures in use, etc. Feel free to ask on Discord (#help-with-circuitpython) or file an issue if you can narrow it down.

scarolan commented 2 years ago

I can confirm the same issue that @askpatrickw reported on a Qt Py ESP32-S3.

Moving the adafruit_requests.Session before the while loop fixed the issue for me.

anecdata commented 1 year ago

A variety of other behaviors have been raised in this discussion, but @askpatrickw: is the original issue still open?

askpatrickw commented 1 year ago

The original issue was cause by creating the request client (object) in the While loop. Doing that before the while loop fixed it.

gary-major commented 9 months ago

Just posted an issue, which seems to be similar here -> https://github.com/adafruit/Adafruit_CircuitPython_AzureIoT/issues/44

my call to requests is outside of the white true loop.