Python package for monitoring your pipeline & Model training status in real-time on Slack, Telegram and Microsoft Teams.
Project description
Introducing slackker! :fire:
slackker sends real-time notifications, custom updates, and metric plots from any Python script directly to Slack, Telegram, Microsoft Teams, or Discord — so you can step away from the screen and still stay informed. :coffee:
https://github.com/user-attachments/assets/41ab1ee9-4d3c-44d0-82b2-3194acbf7727
Table of contents :notebook:
- Installation
- Quick Start
- Create a Client
- SimpleCallback — any Python function
- Interactive Pipeline
- Keras
- Lightning
- Legacy API (deprecated)
- Support
- Citation
- Maintainer
Installation :arrow_down:
Install slackker from UV (recommended) or pip. Requires Python >= 3.10.
uv add slackker
pip install slackker
Quick Start :rocket:
from slackker.core import TelegramClient
from slackker.callbacks.simple import SimpleCallback
client = TelegramClient(
token="1234567890:AAAAA_A111BBBBBCCC2DD3eEe44f5GGGgGG",
verbose=1,
)
notify = SimpleCallback(client)
@notify.notifier
def train_model():
# ... your training code ...
return {"accuracy": 0.94, "loss": 0.12}
train_model()
Refer to our website for platform setup instructions (Slack, Telegram, Teams, Discord).
Create a Client
All slackker callbacks use a client object. Create one for your platform and pass it to any callback.
from slackker.core import SlackClient, TelegramClient, TeamsClient, DiscordClient
# Slack
client = SlackClient(
token="xoxb-123234234235-123234234235-adedce74748c3844747aed",
channel_id="C04AAB77ABC",
verbose=0,
)
# Telegram
client = TelegramClient(
token="1234567890:AAAAA_A111BBBBBCCC2DD3eEe44f5GGGgGG",
verbose=0,
)
# Discord
client = DiscordClient(
token="your_bot_token_here",
channel_id="123456789012345678",
verbose=0,
)
# Microsoft Teams
client = TeamsClient(
app_id="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
tenant_id="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
chat_id="19:xxxxxxxxxxxxxxxxxxxxxx_xxxxxxxxxxxxxxxxxxxxxx@thread.v2",
verbose=0,
)
First-time Teams setup: On the first run,
TeamsClientprints a short URL and a code. Visit the URL, enter the code, and sign in. The token is then cached and silently refreshed on every subsequent run.
Client parameters
Shared parameters (Slack, Telegram, Discord):
| Parameter | Type | Default | Description |
|---|---|---|---|
token |
str |
required | Slack app / Telegram bot / Discord bot token |
channel_id |
str |
required (Slack & Discord only) | Slack or Discord channel ID |
chat_id |
str |
None (Telegram only) |
Telegram chat ID — auto-discovered if omitted |
verbose |
int |
0 |
0 = WARNING/ERROR, 1 = INFO, 2 = DEBUG |
Teams-specific parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
app_id |
str |
required | Azure AD application (client) ID |
tenant_id |
str |
"common" |
Azure AD tenant ID, or "common" for personal + org accounts |
chat_id |
str |
required | Teams chat ID (e.g. 19:..._...@thread.v2) — right-click a message → Copy link, extract from URL |
token_cache_path |
str |
~/.slackker/teams_<app_id[:8]>.json |
Path to cache the access/refresh token |
verbose |
int |
0 |
0 = WARNING/ERROR, 1 = INFO, 2 = DEBUG |
SimpleCallback — any Python function
from slackker.core import TelegramClient
from slackker.callbacks.simple import SimpleCallback
client = TelegramClient(
token="1234567890:AAAAA_A111BBBBBCCC2DD3eEe44f5GGGgGG",
verbose=1,
)
notify = SimpleCallback(client)
# Decorator — automatically sends function name, execution time, and return value
@notify.notifier
def train():
# ... your training code ...
return {"accuracy": 0.94, "loss": 0.12}
train()
# notify() — send a custom update anywhere, with optional file attachment
notify.notify(
event="training_complete",
attachment="./artifacts/model.ckpt",
best_val_loss=0.0123,
epoch=20,
)
Works with any client:
SlackClient,TelegramClient,TeamsClient, orDiscordClient.
Async: use await notify.async_notify(event="step_done", accuracy=0.95) in async contexts.
SimpleCallback parameters
Constructor:
| Parameter | Type | Description |
|---|---|---|
client |
BaseClient |
A slackker client instance |
notify() / async_notify() parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
event |
str |
None |
Label in the notification header; defaults to script filename |
attachment |
str |
None |
Path to a file to send alongside the notification |
**kwargs |
— | — | Any key-value pairs to include in the notification body |
ask() / async_ask() parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
question |
str |
required | Message sent to the platform asking for a reply |
timeout |
float |
60.0 |
Seconds to wait for a reply; auto-continues on timeout |
halt_on |
str |
"no" |
Reply text (case-insensitive) that halts the flow |
Returns True to continue, False to halt.
Interactive Pipeline
Use ask() to send a message and wait for the user's reply — ideal for checkpoints, confirmations, or human-in-the-loop pipelines:
from slackker.core import TelegramClient
from slackker.callbacks.simple import SimpleCallback
client = TelegramClient(
token="1234567890:AAAAA_A111BBBBBCCC2DD3eEe44f5GGGgGG",
verbose=1,
)
notifier = SimpleCallback(client)
def pipeline():
notifier.notify(event="preprocessing_done", samples=10000)
reply = notifier.ask("Preprocessing done. Start training? (yes/no)")
if reply.lower() != "yes":
return
# ... training ...
notifier.notify(event="training_complete", accuracy=0.94)
pipeline()
Async version: use await notifier.async_ask("...") in async contexts.
Use with Keras
from slackker.core import TelegramClient
from slackker.callbacks.keras import KerasCallback
client = TelegramClient(
token="1234567890:AAAAA_A111BBBBBCCC2DD3eEe44f5GGGgGG",
verbose=1,
)
slackker = KerasCallback(
client=client,
model_name="MyModel",
export="png",
send_plot=True,
)
history = model.fit(
x_train, y_train,
epochs=10,
batch_size=32,
validation_data=(x_val, y_val),
callbacks=[slackker],
)
Works with any client:
SlackClient,TelegramClient,TeamsClient, orDiscordClient.
KerasCallback parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
client |
BaseClient |
required | A slackker client instance |
model_name |
str |
required | Name used in messages and plot titles |
export |
str |
"png" |
Plot format (eps, jpeg, jpg, pdf, pgf, png, ps, raw, rgba, svg, svgz, tif, tiff) |
send_plot |
bool |
False |
Send training/validation plots when training ends |
Use with Lightning
Unlike Keras, Lightning requires you to explicitly log metrics using self.log() inside your LightningModule. Use on_epoch=True in training_step so slackker can read them at the end of each epoch.
import torch
import torch.nn as nn
from torch.utils.data import DataLoader
import torchvision as tv
import torch.nn.functional as F
from lightning.pytorch import LightningModule, Trainer
from slackker.core import TelegramClient
from slackker.callbacks.lightning import LightningCallback
class LightningModel(LightningModule):
def __init__(self):
super().__init__()
self.fc1 = nn.Linear(28 * 28, 256)
self.fc2 = nn.Linear(256, 128)
self.out = nn.Linear(128, 10)
def forward(self, x):
batch_size, _, _, _ = x.size()
x = x.view(batch_size, -1)
x = F.relu(self.fc1(x))
x = F.relu(self.fc2(x))
return self.out(x)
def configure_optimizers(self):
return torch.optim.Adam(self.parameters(), lr=1e-3)
def training_step(self, batch, batch_idx):
x, y = batch
y_hat = self.forward(x)
loss = F.cross_entropy(y_hat, y)
accuracy = (torch.max(y_hat, 1)[1] == y).float().mean()
# log with on_epoch=True so slackker can read them at epoch end
self.log("train_loss", loss, on_epoch=True)
self.log("train_acc", accuracy, on_epoch=True)
return loss
def validation_step(self, batch, batch_idx):
x, y = batch
y_hat = self.forward(x)
loss = F.cross_entropy(y_hat, y)
accuracy = (torch.max(y_hat, 1)[1] == y).float().mean()
# on_epoch=True by default in validation_step
self.log("val_loss", loss)
self.log("val_acc", accuracy)
return loss
train_data = tv.datasets.MNIST(".", train=True, download=True, transform=tv.transforms.ToTensor())
val_data = tv.datasets.MNIST(".", train=False, download=True, transform=tv.transforms.ToTensor())
train_loader = DataLoader(train_data, batch_size=128)
val_loader = DataLoader(val_data, batch_size=128)
model = LightningModel()
client = TelegramClient(
token="1234567890:AAAAA_A111BBBBBCCC2DD3eEe44f5GGGgGG",
verbose=1,
)
slackker = LightningCallback(
client=client,
model_name="MyModel",
track_logs=["train_loss", "train_acc", "val_loss", "val_acc"],
monitor="val_loss",
export="png",
send_plot=True,
)
trainer = Trainer(max_epochs=10, callbacks=[slackker])
trainer.fit(model, train_loader, val_loader)
Works with any client:
SlackClient,TelegramClient,TeamsClient, orDiscordClient.
LightningCallback parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
client |
BaseClient |
required | A slackker client instance |
model_name |
str |
required | Name used in messages and plot titles |
track_logs |
list[str] |
required | Metrics to track and report each epoch |
monitor |
str |
None |
Metric used to determine the best epoch |
export |
str |
"png" |
Plot format (eps, jpeg, jpg, pdf, pgf, png, ps, raw, rgba, svg, svgz, tif, tiff) |
send_plot |
bool |
False |
Send training plots when training ends |
Legacy API (deprecated)
Note: The old
Update,SlackUpdate, andTelegramUpdateclasses still work but emit aDeprecationWarning. They will be removed in a future release. Please migrate toSimpleCallbackand the new client-based API shown above.
Click to expand legacy usage examples
Basic callbacks (legacy)
from slackker.callbacks.basic import SlackUpdate # or TelegramUpdate
# Slack
slackker = SlackUpdate(
token="xoxb-123234234235-123234234235-adedce74748c3844747aed",
channel_id="C04AAB77ABC",
)
# Telegram
slackker = TelegramUpdate(token="1234567890:AAAAA_A111BBBBBCCC2DD3eEe44f5GGGgGG")
@slackker.notifier
def your_function():
return value_1, value_2
slackker.notify(event="done", value_1=value_1)
Keras callbacks (legacy)
from slackker.callbacks.keras import SlackUpdate # or TelegramUpdate
slackker = SlackUpdate(
token="xoxb-123234234235-123234234235-adedce74748c3844747aed",
channel_id="C04AAB77ABC",
ModelName="Keras_NN",
export="png",
SendPlot=True,
)
history = model.fit(..., callbacks=[slackker])
Lightning callbacks (legacy)
from slackker.callbacks.lightning import SlackUpdate # or TelegramUpdate
slackker = SlackUpdate(
token="xoxb-123234234235-123234234235-adedce74748c3844747aed",
channel_id="C04AAB77ABC",
ModelName="Lightning NN",
TrackLogs=["train_loss", "train_acc", "val_loss", "val_acc"],
monitor="val_loss",
export="png",
SendPlot=True,
)
trainer = Trainer(max_epochs=2, callbacks=[slackker])
trainer.fit(model, train_loader, test_loader)
Support :sparkles:
If you get stuck, we’re here to help. The following are the best ways to get assistance working through your issue:
- Use our Github Issue Tracker for reporting bugs or requesting features.
Contribution are the best way to keep
slackkeramazing :muscle: - If you want to contribute please refer Contributor's Guide for how to contribute in a helpful and collaborative way :innocent:
Citation :page_facing_up:
Please cite slackker in your publications if this is useful for your project/research. Here is an example BibTeX entry:
@misc{siddheshgunjal2023slackker,
title={slackker},
author={Siddhesh Gunjal},
year={2023},
howpublished={\url{https://github.com/siddheshgunjal/slackker}},
}
Maintainer :sunglasses:
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file slackker-1.5.1.tar.gz.
File metadata
- Download URL: slackker-1.5.1.tar.gz
- Upload date:
- Size: 487.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.17 {"installer":{"name":"uv","version":"0.11.17","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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
841281d1eb3c75742d9042343356dc66e4b11ed34c33a754de0b97124d761190
|
|
| MD5 |
406639c6b80ed2636751188691d2fa0f
|
|
| BLAKE2b-256 |
89deeeb58cad22b0efd4502d1f588e1b82c0a3105d22698240e659d2a0daf29b
|
File details
Details for the file slackker-1.5.1-py3-none-any.whl.
File metadata
- Download URL: slackker-1.5.1-py3-none-any.whl
- Upload date:
- Size: 42.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.17 {"installer":{"name":"uv","version":"0.11.17","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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
67d2d1816ae015d81736614767f8023292df38bfeda4cdc831aad23988ca51fb
|
|
| MD5 |
9c1def0a7b895c7ef17675a82b8a19ac
|
|
| BLAKE2b-256 |
3b95132b6e93fc8b10de20131281fed72360543435dddafb1337538d7b43f7c3
|