Push notifications from Python
Your Python script finished. Your Django view processed something important. Your FastAPI job ran. You found out by checking logs.
Here’s how to make Python tell you directly.
The simplest version: requests
No SDK needed. trigger.fyi is a plain HTTP endpoint:
import requests
import os
key = os.environ["TRIGGER_FYI_SECRET_KEY"]
requests.post(
f"https://trigger.fyi/{key}",
data="Job complete",
timeout=3
)That’s it. Plain text body, POST, done. Your phone notifies.
With the SDK
If you want levels and metadata:
pip install trigger-fyifrom trigger_fyi import fyi
# Normal notification
fyi("Job complete")
# With detail
fyi("Job complete", body="847 records processed in 4m 12s")
# With metadata
fyi("New signup", body="[email protected]", plan="pro", country="US")
# Log to feed only — no push
fyi.log("Cache warmed", body="12,400 keys")
# High priority
fyi.critical("Payment failed", body=customer_email)The SDK reads TRIGGER_FYI_SECRET_KEY from the environment. It never throws and never blocks — errors are swallowed, not raised.
In a script
import subprocess
import time
from trigger_fyi import fyi
start = time.time()
# Your long-running work
result = subprocess.run(["python", "train.py"], capture_output=True, text=True)
elapsed = time.time() - start
minutes = int(elapsed // 60)
seconds = int(elapsed % 60)
if result.returncode == 0:
fyi("Training complete", body=f"{minutes}m {seconds}s · {result.stdout.strip()[-100:]}")
else:
fyi.critical("Training failed", body=result.stderr.strip()[-200:])In Django
# In any view, after the response is ready
from trigger_fyi import fyi
def signup(request):
user = User.objects.create(...)
# Don't block the request — fire after
fyi("New signup", body=user.email, plan=user.plan)
return JsonResponse({"status": "ok"})For proper async fire-and-forget in Django, use a thread:
import threading
from trigger_fyi import fyi
def notify_async(title, **kwargs):
threading.Thread(target=fyi, args=(title,), kwargs=kwargs, daemon=True).start()
def signup(request):
user = User.objects.create(...)
notify_async("New signup", body=user.email)
return JsonResponse({"status": "ok"})In FastAPI
FastAPI has background tasks built in:
from fastapi import FastAPI, BackgroundTasks
from trigger_fyi import fyi
app = FastAPI()
@app.post("/signup")
async def signup(user: UserCreate, background_tasks: BackgroundTasks):
created = await create_user(user)
background_tasks.add_task(fyi, "New signup", body=created.email, plan=created.plan)
return {"status": "ok"}The background task runs after the response is sent. The user never waits for the notification.
In a cron job
#!/usr/bin/env python3
import os
import sys
from trigger_fyi import fyi
def run_backup():
# your backup logic
return {"items": 847, "duration": "4m 12s"}
try:
result = run_backup()
fyi("Backup complete", body=f"{result['items']} items · {result['duration']}")
except Exception as e:
fyi.critical("Backup failed", body=str(e))
sys.exit(1)Getting your phone set up
npx trigger.fyiThis generates a key and subscribes your device. Then:
export TRIGGER_FYI_SECRET_KEY=your_key_hereOr add it to your .env file. The SDK reads it at call time, not import time — works fine in serverless and containerized environments.