Skip to main content

A lightweight MLflow clone that logs ML training metrics, parameters, and artifacts directly to Discord webhooks.

Project description

DiscordFlow 🚀

The MLflow you already have open on your phone. Log ML training metrics, parameters, and artifacts directly to a Discord channel via webhooks — no server required.

PyPI Python Versions License


✨ Features

Feature Description
📈 Metric Logging Post metrics per step/epoch with log_metrics()
⚙️ Param Logging Log hyperparameters with log_param() / log_params()
🏷️ Tags Attach arbitrary key-value tags to runs
📁 Artifact Upload Upload files (models, plots, CSVs) up to 25 MB
📄 Text Artifacts Upload text snippets as .txt file attachments
▶️ Run Management Context-manager start_run() with auto summary embed on exit
🖥️ Dry-Run Mode dry_run=True prints to stdout — no real webhook calls
Error Capture Exceptions inside a start_run() block are caught and posted

📦 Installation

pip install discordflow

Requirements: Python ≥ 3.8, requests


⚡ Quickstart

1. Get a Discord Webhook URL

In your Discord server: Server Settings → Integrations → Webhooks → New Webhook → Copy URL

2. Drop it into your training loop

from discordflow import DiscordFlow

WEBHOOK_URL = "YOUR_DISCORD_WEBHOOK_URL"
dflow = DiscordFlow(WEBHOOK_URL, experiment_name="MoE_Router_Training")

# Log hyperparameters
dflow.log_params({
    "experts": 8,
    "routing_strategy": "top-k",
    "learning_rate": 3e-4,
})

# Training loop
for epoch in range(1, 6):
    loss = 1.0 / epoch
    dflow.log_metrics({
        "Train Loss": round(loss, 4),
        "Load Balance": round(0.8 + 0.02 * epoch, 4),
    }, step=epoch)

# Upload an artifact (max 25 MB)
# dflow.log_artifact("router_weights.pt")
# dflow.log_artifact("loss_curve.png")

3. Context-manager pattern (recommended)

Use start_run() to get an automatic run-summary embed when the block exits — including elapsed time, all params, and final metrics. If your code crashes, the traceback is posted too.

with dflow.start_run("lora_rank_16") as run:
    run.log_params({"lr": 2e-4, "lora_rank": 16, "epochs": 3})
    run.set_tag("framework", "HuggingFace")

    for epoch in range(1, 4):
        run.log_metrics({
            "Train Loss": round(2.5 / epoch, 4),
            "Val Loss":   round(2.7 / epoch, 4),
        }, step=epoch)

# ✅ Run Complete embed is auto-posted here

🧪 Local Testing (Dry Run)

No Discord server? No problem. Use dry_run=True to print all messages to stdout instead of calling the webhook:

dflow = DiscordFlow("ANY_URL", experiment_name="test", dry_run=True)
dflow.log_metrics({"loss": 0.42}, step=1)

Run the bundled demo:

python example.py

📚 API Reference

DiscordFlow(webhook_url, experiment_name, dry_run, username, avatar_url)

Parameter Type Default Description
webhook_url str required Discord webhook URL
experiment_name str "Default Experiment" Shown in every embed
dry_run bool False Print to stdout instead of calling webhook
username str "DiscordFlow 🤖" Bot username shown in Discord
avatar_url str None Custom bot avatar URL

Logging Methods

# Single param
dflow.log_param("learning_rate", 3e-4)

# Multiple params in one embed
dflow.log_params({"lr": 3e-4, "batch_size": 128, "epochs": 10})

# Single metric
dflow.log_metric("loss", 0.42, step=5)

# Multiple metrics in one embed
dflow.log_metrics({"loss": 0.42, "acc": 0.91}, step=5)

# Arbitrary tags (purple embed)
dflow.set_tag("author", "e27")
dflow.set_tag("dataset", "openwebtext")

# Upload a file artifact (max 25 MB)
dflow.log_artifact("checkpoint.pt")
dflow.log_artifact("confusion_matrix.png")

# Upload a text snippet as a file
dflow.log_text("epoch,loss\n1,1.0\n2,0.5", filename="metrics.csv")

Run Management

# Start a named run (context manager — recommended)
with dflow.start_run("sweep_01") as run:
    run.log_params({...})
    run.log_metrics({...}, step=epoch)
    run.set_tag("status", "grid_search")
    run.log_artifact("model.pt")
# ← Auto-posts run summary embed on exit

# Or explicitly end a run
run = dflow.start_run("manual_run")
# ... do stuff ...
dflow.end_run(status="FINISHED")

📤 Publishing to PyPI

cd discordflow-project

# Install build tools
pip install build twine

# Build the package
python -m build

# Upload to PyPI (first time: create account at pypi.org)
twine upload dist/*

🔄 Bump Version & Re-Publish (bash script)

Save this as publish.sh in your project root:

#!/usr/bin/env bash
set -e

NEW_VERSION=$1
if [ -z "$NEW_VERSION" ]; then
    echo "Usage: ./publish.sh <new_version>  e.g. ./publish.sh 0.3.0"
    exit 1
fi

# Update version in pyproject.toml
sed -i '' "s/^version = .*/version = \"$NEW_VERSION\"/" pyproject.toml

# Update version in __init__.py
sed -i '' "s/^__version__ = .*/__version__ = \"$NEW_VERSION\"/" discordflow/__init__.py

echo "✅  Bumped to v$NEW_VERSION"

# Clean old builds
rm -rf dist/ build/ *.egg-info

# Build + upload
python -m build
twine upload dist/*

echo "🚀  Published discordflow v$NEW_VERSION to PyPI"
chmod +x publish.sh
./publish.sh 0.3.0

🤝 Contributing

  1. Fork the repo
  2. Create your feature branch: git checkout -b feat/my-feature
  3. Commit your changes: git commit -m "feat: add my feature"
  4. Push: git push origin feat/my-feature
  5. Open a Pull Request

📄 License

MIT © DiscordFlow Contributors

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

discordflow-0.2.0.tar.gz (12.7 kB view details)

Uploaded Source

Built Distribution

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

discordflow-0.2.0-py3-none-any.whl (11.7 kB view details)

Uploaded Python 3

File details

Details for the file discordflow-0.2.0.tar.gz.

File metadata

  • Download URL: discordflow-0.2.0.tar.gz
  • Upload date:
  • Size: 12.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.2

File hashes

Hashes for discordflow-0.2.0.tar.gz
Algorithm Hash digest
SHA256 ee7eb2db1189416a7b4d6ab0cc5dbdf795cb69fb1bed3fea44b8bb1216b2fc67
MD5 c917738c850d461836194a96aa308ac4
BLAKE2b-256 f7ecce037748a286810a435cbd7ac214732acf29323bfe751243cc9675067b0a

See more details on using hashes here.

File details

Details for the file discordflow-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: discordflow-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 11.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.2

File hashes

Hashes for discordflow-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 8667af547f98b032ac46cb526afc346decc042376a3992d6fad331ea0888590f
MD5 764a55e6f56a344e223b9599ec5e1dbd
BLAKE2b-256 0d728cf5c5fb01de91840ef0df06c2ea6d5d703e7d9712ce2fcceee0b6daa672

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