Skip to main content

Send unhandled Python exceptions straight to a Telegram chat. No backend, no account, no database — just your own bot token.

Project description

devalerts

PyPI Python versions License: MIT

Русская версия

Send unhandled Python exceptions straight to a Telegram chat — the moment they happen, on your phone. No backend, no account, no database — just your own bot token.

import devalerts

devalerts.init(bot_token="123456:ABC-DEF...", chat_id=123456789)

That's the whole setup. Two minutes with @BotFather and every unhandled crash — including ones raised in threads — lands in your chat instead of a log file nobody's watching.

Why devalerts

  • Zero infrastructure. No SaaS signup, no ingestion server, no API key to manage beyond your own Telegram bot token. State lives in a local SQLite file you already own.
  • One line to install, one line to wire up. init() installs the hook and gets out of the way.
  • Not spam. Errors are grouped by fingerprint and rate-limited per group, so a crash loop sends one message, not a thousand.
  • Framework-aware. Ships an ASGI middleware for FastAPI/Starlette apps, where the default excepthook would never even see a request error.
  • Small and typed. No dependencies, ships py.typed, ~450 lines total — short enough to read in one sitting before you trust it with your errors.

Install

uv add devalerts

(or pip install devalerts if you're not using uv)

Usage

  1. Create a bot with @BotFather and get its token.
  2. Message your bot once (or add it to a group) so it's allowed to message you back.
  3. Get your chat id — message @userinfobot, or call https://api.telegram.org/bot<TOKEN>/getUpdates after step 2 and read message.chat.id.
  4. In your app, as early as possible:
import devalerts

devalerts.init(bot_token="123456:ABC-DEF...", chat_id=123456789)

That's it — any unhandled exception (including ones raised in threads) now also lands in your Telegram chat.

Grouping, rate limiting, and the dashboard

Exceptions are grouped by fingerprint (exception type + file + line where it was raised) in a local SQLite file (~/.devalerts/state.db). Each group sends at most one Telegram message per rate_limit_seconds (default 300); repeats inside that window are counted but not sent, and the next message for that group says how many were skipped. Old groups (untouched for 7 days) are pruned automatically. Configure the window via init():

devalerts.init(bot_token="...", chat_id=123456789, rate_limit_seconds=60)

See what's grouped and what's currently rate-limited:

uv run devalerts dashboard
  ID        TYPE          LOCATION                            LAST SEEN TOTAL   STATUS
  ────────────────────────────────────────────────────────────────────────────────────
  a1b2c3d4  ValueError    app/orders.py:42                     2m ago       14   ● limited
  9f8e7d6c  KeyError      app/handlers/webhook.py:88            just now      1   ● sending

  2 error groups, 1 currently rate-limited.

Manually reporting a caught exception

try:
    risky_call()
except Exception:
    devalerts.report()  # sends the currently-handled exception

or:

with devalerts.capture():
    risky_call()  # reports on exception, then re-raises

capture also works as a decorator, so you don't need to touch a function's body at all:

@devalerts.capture()
def risky_call():
    ...

FastAPI / Starlette / any ASGI app

init()'s excepthook won't see request errors — the framework already catches them internally to return a 500 response, so nothing "unhandled" ever reaches the process. Use the ASGI middleware instead:

app.add_middleware(devalerts.ASGIMiddleware)

Only exceptions that actually escape as server errors get reported — routing 404s and raised HTTPExceptions are already turned into responses by the framework before the middleware sees them.

devalerts vs. a full error tracker

If you already run Sentry/Rollbar/etc., keep using it — this isn't a replacement. devalerts is for the side project, internal tool, or small service that doesn't have (and doesn't want) that infrastructure yet:

devalerts Sentry-style tracker
Setup one bot token account + project + SDK config
Backend none — Telegram only hosted or self-hosted service
Where alerts land your Telegram chat a web dashboard
Grouping / rate limiting yes, local SQLite yes, server-side
Search, trends, releases no yes

What this does NOT do (by design)

  • Grouping/rate limiting is local and in-process only (SQLite file, no server) — the dashboard is a CLI table, not a web UI.
  • No backend, no accounts — each user runs their own bot.
  • Basic secret redaction only (a few common token patterns) — do not rely on this for sensitive production data.
  • No automated test suite — verified manually during implementation only.

License

MIT — see LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

devalerts-0.1.4.tar.gz (9.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

devalerts-0.1.4-py3-none-any.whl (12.2 kB view details)

Uploaded Python 3

File details

Details for the file devalerts-0.1.4.tar.gz.

File metadata

  • Download URL: devalerts-0.1.4.tar.gz
  • Upload date:
  • Size: 9.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.29 {"installer":{"name":"uv","version":"0.11.29","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for devalerts-0.1.4.tar.gz
Algorithm Hash digest
SHA256 6cfff35e9a13c9672248da414ee7c72b5488d25bcca49dd332096c389d5ac6f6
MD5 d59d614469041e3d3e0f4dd34c3009c2
BLAKE2b-256 502af10b16804de861342470d88d1204c8ba5161c6cbbd8581f51b88f6d85137

See more details on using hashes here.

File details

Details for the file devalerts-0.1.4-py3-none-any.whl.

File metadata

  • Download URL: devalerts-0.1.4-py3-none-any.whl
  • Upload date:
  • Size: 12.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.29 {"installer":{"name":"uv","version":"0.11.29","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for devalerts-0.1.4-py3-none-any.whl
Algorithm Hash digest
SHA256 08e9751b5ec28f6ca8117ac196b70365d32ca59d933de0bfde4ab75fd74da16e
MD5 1ae9bbfcd9efabbf6f67337c81168bd7
BLAKE2b-256 f7b4b190084142ebac2a6687bdb3e26f2101e2ead1c31fdee445327de2e136f6

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page