SDK
Python
The stillrunning-sdkpip package monitors any Python job, agent, or script. Decorate or wrap your code and StillRunning gets a ping on success or failure with the run's duration, plus optional cost, tokens, and model. Works with LangChain, CrewAI, agent scripts, Celery/RQ workers, and plain cron jobs. No runtime dependencies.
Install
pip install stillrunning-sdk30-second quickstart
1. Create a workflow at stillrunning.ai/app/new and copy its token. 2. export STILLRUNNING_TOKEN=your_token_here. 3. Monitor your work:
from stillrunning_sdk import StillRunning
sr = StillRunning() # reads STILLRUNNING_TOKEN
@sr.monitor
def nightly_job():
...Every call is timed and reported, success on return, fail on exception (re-raised untouched).
Three ways to use it
Decorate a function:
@sr.monitor
def sync_customers():
...Context manager, attach AI metrics inside the block:
with sr.track() as run:
result = call_agent(prompt)
run.meta(
tokens_in=result.usage.input,
tokens_out=result.usage.output,
model="gpt-4o", # model + tokens -> costUsd estimated automatically
)Run a callable inline:
answer = sr.run(
lambda: call_agent(prompt),
meta={"model": "claude-sonnet-4", "tokens_in": 1200},
)Heartbeats and manual pings
sr.heartbeat() # bare success ping
sr.ping(event="start", traceId="...") # low-level: success | fail | start | logCost estimation
Give model plus token counts and cost is estimated from a built-in pricing table. Pass an explicit cost_usd for exact accounting, or extend the table:
from stillrunning_sdk import register_model_pricing
register_model_pricing([(r"my-custom-model", (1.5, 6.0))]) # USD per 1M (input, output) tokensGrouping multi-step runs
from stillrunning_sdk import StillRunning, with_trace
sr = StillRunning()
with with_trace():
sr.run(plan_step)
sr.run(execute_step) # both pings share one trace_idConfiguration
StillRunning(
token=None, # defaults to env STILLRUNNING_TOKEN
base_url="https://stillrunning.ai",
timeout=3.0, # seconds; bounds each ping
await_ping=True, # False = fire-and-forget in a daemon thread
on_error=None, # callable(Exception) to observe ping failures
)Monitoring never raises into your code: a failed ping routes to on_error and is otherwise swallowed.
Requirements
Python 3.9+. No runtime dependencies (standard library only).
You're set
Open your dashboard to watch runs land with duration, cost, and anomaly alerts.
Open dashboard