ChronoCourier
A priority-based notification system for routing alerts and reports to Telegram and email.
Description
ChronoCourier is a Flask-based notification service that receives alerts and reports over HTTP, validates and queues them, determines their configured destinations, and delivers them through Telegram and email.
Notifications are processed through priority queues so higher-priority tasks are handled first. Failed deliveries are moved to a separate retry flow, where they are delayed and retried without blocking newly received notifications. Each retry increases the task's priority value until the configured retry limit is reached.
Features
- HTTP API for submitting alerts and reports
- API-key authentication and request validation
- Priority-based task processing
- Separate processing and retry queues
- Configurable retry delay and retry limit
- Telegram topic routing based on log type and message content
- Email routing based on report subject
- Support for email attachments
- JSON-aware formatting for alert messages
- Telegram MarkdownV2 formatting
- Queue monitoring through an HTTP endpoint
- Queue clearing endpoints for operational use
- Runtime configuration reload with validation and rollback
- Health-check endpoint
- Docker and Docker Compose support
- Development SMTP environment using MailHog and stunnel
- Configurable settings through Dynaconf
- Structured application logging through OmniLogger
Architecture
ChronoCourier uses three priority queues:
- Processing Queue — holds newly received alerts and reports.
- Failure Queue — stores tasks that failed delivery and are waiting for their retry time.
- Failure Processing Queue — holds retry tasks while they are being processed by the lazy worker.
Two background workers handle these queues:
- Active Queue Worker continuously processes newly received tasks.
- Lazy Queue Worker periodically moves retryable tasks into the failure-processing queue and processes them in batches.
For each task, ChronoCourier determines the configured Telegram and email destinations and attempts delivery independently. When delivery fails, the task is placed in the failure queue with a future retry timestamp. The retry count is represented by the task's priority value and is increased on each retry until the configured limit is reached.
API
The service listens on port 5030 by default.
Submit an alert
curl -X POST http://localhost:5030/alert \
-F "api-key=key" \
-F "subject=Test alert" \
-F "content=Something went wrong" \
-F "log_type=ERROR"
Alerts require:
api-keysubjectcontentlog_type
Alerts receive the highest initial priority.
Submit a report
curl -X POST http://localhost:5030/report \
-F "api-key=key" \
-F "subject=Test report" \
-F "content=Report content"
Reports require:
api-keysubjectcontent
Reports can also include file attachments.
Health check
curl http://localhost:5030/health
Queue sizes
curl http://localhost:5030/queue_size
Returns the current sizes of the processing, failure, and failure-processing queues.
Reload configuration
GET /reload_settings
GET /reload_settings?confirm=yes
The first request displays a confirmation page. The second reloads and validates the configuration. If validation fails, the previous configuration is restored.
Clear a queue
GET /clear_<queue_type>_queue
GET /clear_<queue_type>_queue?confirm=yes
Supported queue types are:
processingfailurefailure_processing
The endpoint first displays a confirmation page and only clears the queue when confirm=yes is supplied.
Installation
ChronoCourier requires Python 3.11 or newer.
Install the latest released version from PyPI:
pip install chrono-courier
The package provides the chrono_courier command:
chrono_courier
Configuration must be available and valid before starting the service.
Docker
ChronoCourier is available as a Docker image through GitHub Container Registry.
Production image
Run with Docker Compose
The production Docker Compose configuration uses the published ChronoCourier image.
cd docker
docker compose up -d
ChronoCourier is available at:
http://localhost:5030
The container requires a valid ChronoCourier configuration. Configure the required environment variables or mount the appropriate configuration files before starting it.
Development environment
The repository includes a Docker Compose environment for local development and integration testing.
The development environment starts:
- ChronoCourier
- MailHog
- stunnel
The MailHog + stunnel setup provides a local SMTP environment for testing TLS email delivery without using a real mail server.
Start the development environment with:
cd docker
docker compose -f docker-compose.dev.yaml up --build
ChronoCourier is available at:
http://localhost:5030
MailHog's web interface is available at:
http://localhost:8025
The development stunnel configuration exposes SMTP-over-TLS on ports 465 and 587.
The certificates under docker/stunnel/certs/ are intentionally self-signed test certificates and must never be used in production.
Configuration
ChronoCourier uses Dynaconf for application configuration.
The configuration covers:
- Flask host, port, API key, and debug mode
- Queue retry count and retry delay
- Lazy worker sleep interval
- SMTP server and sender credentials
- Email recipients and routing rules
- Telegram bot token and message limits
- Telegram topic IDs and routing rules
Example configuration files are provided under:
src/chrono_courier/config/
Replace the example credentials and destination values before using ChronoCourier outside a local test environment.
Development
A development Docker environment is provided to simplify local development and integration testing.
The repository also includes a request helper at:
src/chrono_courier/helpers_scripts/send_request.py
which demonstrates how to submit alerts and reports to the service.
License
ChronoCourier is licensed under the MIT License.
Metadata
Release files for chrono-courier 1.0.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| chrono_courier-1.0.2.tar.gz | 19.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| chrono_courier-1.0.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 38.3 kB
Release files / chrono_courier-1.0.2.tar.gz
| Download URL | chrono_courier-1.0.2.tar.gz |
|---|---|
| Size | 19.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
374be6dc10d23a1c42d509ee69fe14926a9534a13e289c669c2b8ee473eae30e
|
|
BLAKE2b-256 checksum How to use checksums |
39c39f77ca25c98b70141aaa3b8ae95e961582b239dfe8bb418a8babe0ce1528
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.5
|
Release files / chrono_courier-1.0.2-py3-none-any.whl
| Download URL | chrono_courier-1.0.2-py3-none-any.whl |
|---|---|
| Size | 19.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
d53528e495f065dd9f30a7a22fe00a7ebc3de3b3258ea12f7962190fa22af89d
|
|
BLAKE2b-256 checksum How to use checksums |
a40c3dba22694e384b0fcafb9f18a488dd19028c47456c481828d98e1360c0a3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.5
|