sporadischer ConnectionError beim Senden von Nachricht an Telegram mit requests.post() - Ursache & Lösung?
Verfasst: Samstag 26. April 2025, 14:37
Hallo zusammen,
ich habe mir letztes Jahr einen Scanner für US-Aktien geschrieben, der das Modul ib_async nutzt (asynchrones Framework für die Interactive Brokers API). Den Scanner lasse ich ab und zu laufen, wenn ich zu Hause bin und Zeit habe. Der Scanner aktualisiert sich alle 2 Minuten selber und läuft fehlerfrei.
Vor einigen Wochen habe ich mir mal gedacht, wäre ja cool, wenn ein Teil der Infos auf mein Handy gesendet werden würde... Also etwas recherchiert, was es da so für Python gibt: WhatsApp Nachrichten oder SMS kosten etwas Geld, aber Telegram scheint kostenlos zu sein. Somit habe ich einfach mal nen Beispiel aus dem Netz getestet: Telegram App installiert, eine eigene Gruppe und einen bot dafür angelegt, das offizielle Telegram Python Modul installiert, ein Code Beispiel getestet und schon konnte ich mir Nachrichten in meine Telegram Gruppe schicken.
Danach habe ich den Code für das Senden an Telegram in ner eigenen Funktion in den Scanner Code eingebaut und da beide Module asynchron laufen, gab es den "This event loop is already running" Fehler, war klar. Ich habe mir die Beispiele angeschaut, wie man beide asynchronen events miteinander laufen lassen kann und da mich das erst Mal überfordert hat, habe ich nach ner einfacheren Lösung gesucht, die es auch gibt, per HTTP requests.post()
Ich habe ein kurzes Beispiel getestet, dann die Funktion im Scanner Code entsprechend auf requests.post() abgeändert und schon lief das: Der Scanner aktualisiert sich und prüft dann die vorhandenen Aktien nach ein paar Kriterien. Wenn Kriterien erfüllt, dann schickt er mir zu diesen Aktien jeweils einen kurzen Text-3-Zeiler. Die Anzahl der Nachrichten variiert von stundenlang nichts bis 1 Nachricht alle 2 Minuten.
Das lief so 2 bis 3 Wochen vollkommen problemlos, bis ich einen abends an meinen Rechner komme und das Scanner Script mit einem riesen Traceback abgebrochen ist, letzte Zeile "requests.exceptions.ConnectionError: ('Connection aborted.', ConnectionResetError(10054, 'Eine vorhandene Verbindung wurde vom Remotehost geschlossen', None, 10054, None))".
OK, ich hatte für request.post() kein try / except drin, weil es das bisher nicht gebraucht hat, also kurz eingebaut und seitdem sieht der relevante Code so aus:
Seitdem wird der ConnectionError aufgefangen und Script läuft weiter, aber ich finde die Ursache für die Verbindungsabbrüche nicht. Es gibt Tage / Stunden, da sendet er brav jede Nachricht, ohne Fehler, auch alle 2 Minuten hintereinander. Und dann gibt es zwischendrin 1 oder 2 Fehlermeldungen (ich weiß, das allgemeine "except Exception as error:" ist nicht sauber, aber einen anderen Fehler als ConnectionError habe ich noch nicht gehabt) und dann läuft es problemlos weiter.
Was ich bisher unternommen habe, um den Fehler zu verstehen:
- ich habe hier im Forum und bei StackExchange diverse Beiträge zu requests.post() gelesen, das sind einige, aber meine Problemstellung war nicht wirklich dabei
- ich habe die Doku von Telegram zu Verbindungsabbrüchen gelesen und die schreiben mMn so ungefähr, kann vorkommen, Fehler einfangen und Nachricht nochmal senden
- ich habe geschaut, ob der Server eine Antwort / Begründung in "response" zurück schickt, aber die Variable ist leer / nicht vorhanden
- ich habe die relevanten Module aktualisiert, was beim Telegram Modul sinnlos ist, da ich das gar nicht nutze zum Senden
- an einem rate oder Größen limit kann es eigentlich auch nicht liegen, es wird 1 Nachricht alle 2 Minuten geschickt und die bsteht aus Text und Unicode Zeichen, erlaubt laut Telegram sind bis zu 10 Nachrichten / Sekunde
Hat jemand Erfahrung mit diesem ConnectionError? Was kann die Ursache sein oder passiert das halt mal, wie Telegram so schreibt?
Was ist die beste Lösung, damit jede Nachricht gesendet wird?
- Bei ConnectionError die Nachricht einfach nochmal senden?
- das senden auf requests.Session() ändern? Oder keine gute Idee mit dem asynchronen ib_async?
- sich in asyncio einarbeiten und eine saubere async Lösung für das Senden in Zusammenspiel mit ib_async umsetzen?
Mein Systemgebung ist Windows 11 und Python 3.12.
Grüße,
Andy
ich habe mir letztes Jahr einen Scanner für US-Aktien geschrieben, der das Modul ib_async nutzt (asynchrones Framework für die Interactive Brokers API). Den Scanner lasse ich ab und zu laufen, wenn ich zu Hause bin und Zeit habe. Der Scanner aktualisiert sich alle 2 Minuten selber und läuft fehlerfrei.
Vor einigen Wochen habe ich mir mal gedacht, wäre ja cool, wenn ein Teil der Infos auf mein Handy gesendet werden würde... Also etwas recherchiert, was es da so für Python gibt: WhatsApp Nachrichten oder SMS kosten etwas Geld, aber Telegram scheint kostenlos zu sein. Somit habe ich einfach mal nen Beispiel aus dem Netz getestet: Telegram App installiert, eine eigene Gruppe und einen bot dafür angelegt, das offizielle Telegram Python Modul installiert, ein Code Beispiel getestet und schon konnte ich mir Nachrichten in meine Telegram Gruppe schicken.
Danach habe ich den Code für das Senden an Telegram in ner eigenen Funktion in den Scanner Code eingebaut und da beide Module asynchron laufen, gab es den "This event loop is already running" Fehler, war klar. Ich habe mir die Beispiele angeschaut, wie man beide asynchronen events miteinander laufen lassen kann und da mich das erst Mal überfordert hat, habe ich nach ner einfacheren Lösung gesucht, die es auch gibt, per HTTP requests.post()
Ich habe ein kurzes Beispiel getestet, dann die Funktion im Scanner Code entsprechend auf requests.post() abgeändert und schon lief das: Der Scanner aktualisiert sich und prüft dann die vorhandenen Aktien nach ein paar Kriterien. Wenn Kriterien erfüllt, dann schickt er mir zu diesen Aktien jeweils einen kurzen Text-3-Zeiler. Die Anzahl der Nachrichten variiert von stundenlang nichts bis 1 Nachricht alle 2 Minuten.
Das lief so 2 bis 3 Wochen vollkommen problemlos, bis ich einen abends an meinen Rechner komme und das Scanner Script mit einem riesen Traceback abgebrochen ist, letzte Zeile "requests.exceptions.ConnectionError: ('Connection aborted.', ConnectionResetError(10054, 'Eine vorhandene Verbindung wurde vom Remotehost geschlossen', None, 10054, None))".
OK, ich hatte für request.post() kein try / except drin, weil es das bisher nicht gebraucht hat, also kurz eingebaut und seitdem sieht der relevante Code so aus:
Code: Alles auswählen
from requests import post
...
def senden_an_telegram(nachricht: str) -> dict:
""" Nachricht an Telegram Gruppe per request POST,
async telegram beisst sich mit async ib
"""
url = f"https://api.telegram.org/bot{BOT_TOKEN}/sendMessage"
payload = {'chat_id': CHAT_ID, 'text': nachricht, 'parse_mode': 'HTML'}
try:
response = post(url, data=payload, timeout=(5,5))
except Exception as error:
return {"ok": False, "error": f"Fehlermeldung: {error}"}
return response.json()
Was ich bisher unternommen habe, um den Fehler zu verstehen:
- ich habe hier im Forum und bei StackExchange diverse Beiträge zu requests.post() gelesen, das sind einige, aber meine Problemstellung war nicht wirklich dabei
- ich habe die Doku von Telegram zu Verbindungsabbrüchen gelesen und die schreiben mMn so ungefähr, kann vorkommen, Fehler einfangen und Nachricht nochmal senden
- ich habe geschaut, ob der Server eine Antwort / Begründung in "response" zurück schickt, aber die Variable ist leer / nicht vorhanden
- ich habe die relevanten Module aktualisiert, was beim Telegram Modul sinnlos ist, da ich das gar nicht nutze zum Senden
- an einem rate oder Größen limit kann es eigentlich auch nicht liegen, es wird 1 Nachricht alle 2 Minuten geschickt und die bsteht aus Text und Unicode Zeichen, erlaubt laut Telegram sind bis zu 10 Nachrichten / Sekunde
Hat jemand Erfahrung mit diesem ConnectionError? Was kann die Ursache sein oder passiert das halt mal, wie Telegram so schreibt?
Was ist die beste Lösung, damit jede Nachricht gesendet wird?
- Bei ConnectionError die Nachricht einfach nochmal senden?
- das senden auf requests.Session() ändern? Oder keine gute Idee mit dem asynchronen ib_async?
- sich in asyncio einarbeiten und eine saubere async Lösung für das Senden in Zusammenspiel mit ib_async umsetzen?
Mein Systemgebung ist Windows 11 und Python 3.12.
Grüße,
Andy