Skip to main content

Cross-platform process monitor with Telegram notifications and remote control

Project description

qara

Watch any process. Get notified on Telegram. Control it remotely.

PyPI Python License


qara is a lightweight daemon that monitors processes and sends real-time notifications to Telegram. Start a long-running job, close your laptop, and stay in control from your phone.

Built for ML practitioners who run multi-hour training jobs, but works with any process.

qara run python train.py --name "gpt-finetune"
# => Telegram: "Process 'gpt-finetune' started (PID 41592)"
# => ... hours later ...
# => Telegram: "Process 'gpt-finetune' finished (exit 0, 3h 42m)"

Features

  • Spawn or attach — start a new process with qara run or monitor an existing one with qara attach <pid>
  • Telegram notifications — get notified on start, finish, and crash with configurable stdout tail
  • Remote control — send /status, /kill, /history, /logs from Telegram
  • Plugin system — extend with plugins via entry points (e.g. qara-ml for GPU metrics and loss tracking)
  • Daemon mode — runs as a user-level service (systemd, launchd) — no root required
  • JSON output--format json on status and history for scripting

Quickstart

Install

pip install qara

# Or with uv (recommended)
uv pip install qara

# With ML plugin (GPU metrics + loss tracking)
pip install qara-ml

Configure

qara config init

This creates ~/.config/qara/config.toml. Open it and add your Telegram bot token and user ID:

[telegram]
bot_token = "123456:ABC-DEF..."
allowed_user_ids = [your_telegram_user_id]
How to get a bot token and user ID
  1. Message @BotFather on Telegram and send /newbot
  2. Follow the prompts to name your bot — you'll receive a token like 123456:ABC-DEF...
  3. To find your user ID, message @userinfobot and it will reply with your numeric ID
  4. Important: Send any message to your new bot first so it can message you back

Start the daemon

qara daemon start

Run a process

qara run python train.py --name "experiment-1"

That's it. You'll receive Telegram notifications when the process starts, finishes, or crashes.

Usage

Process management

# Run a process
qara run python train.py --name "my-job"

# Attach to an existing process
qara attach 12345 --name "background-job"

# List watched processes
qara status
qara status --format json

# View completed runs
qara history --last 10
qara history --format json

Telegram commands

Once the daemon is running, send these commands to your bot:

Command Description
/status List all watched processes
/kill <name> Send SIGTERM to a process (escalates to SIGKILL)
/history Show recent completed runs
/logs <name> Get last N lines of stdout

Daemon management

qara daemon start              # Start in background
qara daemon start --foreground  # Start in foreground (for systemd/launchd)
qara daemon stop               # Stop the daemon
qara daemon status             # Check if daemon is running

Install as a system service

# Auto-detects systemd (Linux) or launchd (macOS)
qara install

# Preview what would be installed
qara install --dry-run

# Remove the service
qara uninstall

Configuration

Full config.toml reference:

[daemon]
log_level = "INFO"  # DEBUG, INFO, WARNING, ERROR

[telegram]
bot_token = "YOUR_BOT_TOKEN"
allowed_user_ids = [123456789]

[telegram.notifications]
on_start = true
on_finish = true
on_crash = true
stdout_tail_lines = 20  # lines of stdout included in finish notification

[commands]
enabled = ["status", "kill", "restart"]
kill_timeout_seconds = 10

[commands.allowed_scripts]
# alias = "/absolute/path/to/script.py"

[plugins]
enabled = ["ml"]

[plugins.ml]
gpu_poll_interval_seconds = 5
loss_pattern = ""  # custom regex, leave empty for default

ML Plugin

The qara-ml plugin adds GPU monitoring and training loss tracking:

pip install qara-ml

Enable it in config.toml:

[plugins]
enabled = ["ml"]

After a training run finishes, you'll receive an additional summary:

GPU summary:
  Peak VRAM: 18204 MB / 24576 MB
  Avg GPU util: 94%
  Peak temp: 78°C

Training summary:
  Final loss: 0.0342
  Best loss: 0.0298 (step 4200)

The loss tracker matches common patterns like loss=0.123, train_loss: 0.456, etc. You can provide a custom regex via loss_pattern in the config.

Architecture

qara daemon start
      │
      ▼
┌─────────────┐     ┌──────────────┐     ┌──────────────┐
│   Watcher    │────▶│  EventEngine │────▶│  Telegram    │
│  (per proc)  │     │  (pub/sub)   │     │  Channel     │
└─────────────┘     └──────┬───────┘     └──────────────┘
                           │
                    ┌──────┴───────┐
                    │   Plugins    │
                    │ (GPU, loss)  │
                    └──────────────┘
      ▲
      │ IPC (Unix socket)
      │
  qara run / qara status / ...
  • Watcher spawns or attaches to processes via asyncio.create_subprocess_exec
  • EventEngine is sequential async pub/sub — handlers receive events in subscription order
  • Plugins subscribe directly to the engine and receive all events including stdout/stderr lines
  • NotificationBus filters internal events before routing to channels
  • IPC uses newline-delimited JSON over Unix sockets (Linux/macOS)

Development

git clone https://github.com/warptengood/qara
cd qara
uv sync --group dev

# Run checks
uv run ruff check src/       # lint
uv run ruff format src/      # format
uv run mypy src/             # type check
uv run pytest                # tests

See CONTRIBUTING.md for guidelines.

License

MIT — see LICENSE for details.

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

qara-0.1.0.tar.gz (136.2 kB view details)

Uploaded Source

Built Distribution

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

qara-0.1.0-py3-none-any.whl (28.8 kB view details)

Uploaded Python 3

File details

Details for the file qara-0.1.0.tar.gz.

File metadata

  • Download URL: qara-0.1.0.tar.gz
  • Upload date:
  • Size: 136.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for qara-0.1.0.tar.gz
Algorithm Hash digest
SHA256 c2240d501392d5ced033afaa078b230429c933494c0554be406619fc5147f00a
MD5 854cc346abd3bbebfcceeab29f7261b4
BLAKE2b-256 206dbaca5f748f77515efddebace6d30dd61df638cf437188946cef9f01607fd

See more details on using hashes here.

Provenance

The following attestation bundles were made for qara-0.1.0.tar.gz:

Publisher: publish.yml on warptengood/qara

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file qara-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: qara-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 28.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for qara-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 3eff17ffa694ec6dafe7bfb00b9b8e838024ba17318833e8f7074bc7b486f654
MD5 0dab876dd89adc9dd3a423f3652dddce
BLAKE2b-256 b68c1c30e7a460044fce13dec07621e6ba4019d380aab42f7f0aa34ab57332e4

See more details on using hashes here.

Provenance

The following attestation bundles were made for qara-0.1.0-py3-none-any.whl:

Publisher: publish.yml on warptengood/qara

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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