Error tracking and monitoring SDK for Python applications
Project description
Statly Observe SDK for Python
Error tracking and monitoring for Python applications. Capture exceptions, track releases, and debug issues faster.
Features
- Automatic exception capturing with full stack traces
- Breadcrumbs for debugging context
- User context tracking
- Release tracking
- Framework integrations (Flask, Django, FastAPI)
- Async support
- Minimal overhead
Installation
pip install statly-observe
With framework integrations:
pip install statly-observe[flask] # Flask support
pip install statly-observe[django] # Django support
pip install statly-observe[fastapi] # FastAPI/Starlette support
pip install statly-observe[all] # All integrations
Getting Your DSN
- Go to statly.live/dashboard/observe/setup
- Create an API key for Observe
- Copy your DSN (format:
https://<api-key>@statly.live/<org-slug>)
Quick Start
from statly_observe import Statly
# Initialize the SDK
Statly.init(
dsn="https://sk_live_xxx@statly.live/your-org",
environment="production",
release="1.0.0",
)
# Errors are captured automatically via sys.excepthook
# Manual capture
try:
risky_operation()
except Exception as e:
Statly.capture_exception(e)
# Capture a message
Statly.capture_message("User completed checkout", level="info")
# Set user context
Statly.set_user(
id="user-123",
email="user@example.com",
)
# Add breadcrumb for debugging
Statly.add_breadcrumb(
message="User logged in",
category="auth",
level="info",
)
# Always close before exit
Statly.close()
Framework Integrations
Flask
from flask import Flask
from statly_observe import Statly
from statly_observe.integrations.flask import init_flask
app = Flask(__name__)
# Initialize Statly
Statly.init(
dsn="https://sk_live_xxx@statly.live/your-org",
environment="production",
)
# Attach to Flask app
init_flask(app)
@app.route("/")
def index():
return "Hello World"
@app.route("/error")
def error():
raise ValueError("Test error") # Automatically captured
Django
settings.py:
INSTALLED_APPS = [
# ...
'statly_observe.integrations.django',
]
MIDDLEWARE = [
'statly_observe.integrations.django.StatlyMiddleware',
# ... other middleware (Statly should be first)
]
# Statly configuration
STATLY_DSN = "https://sk_live_xxx@statly.live/your-org"
STATLY_ENVIRONMENT = "production"
STATLY_RELEASE = "1.0.0"
wsgi.py or manage.py:
from statly_observe import Statly
from django.conf import settings
Statly.init(
dsn=settings.STATLY_DSN,
environment=settings.STATLY_ENVIRONMENT,
release=settings.STATLY_RELEASE,
)
FastAPI
from fastapi import FastAPI
from statly_observe import Statly
from statly_observe.integrations.fastapi import init_fastapi
app = FastAPI()
# Initialize Statly
Statly.init(
dsn="https://sk_live_xxx@statly.live/your-org",
environment="production",
)
# Attach to FastAPI app
init_fastapi(app)
@app.get("/")
async def root():
return {"message": "Hello World"}
@app.get("/error")
async def error():
raise ValueError("Test error") # Automatically captured
Generic WSGI/ASGI
from statly_observe import Statly
from statly_observe.integrations.wsgi import StatlyWSGIMiddleware
from statly_observe.integrations.asgi import StatlyASGIMiddleware
Statly.init(dsn="https://sk_live_xxx@statly.live/your-org")
# WSGI
app = StatlyWSGIMiddleware(your_wsgi_app)
# ASGI
app = StatlyASGIMiddleware(your_asgi_app)
Configuration Options
| Option | Type | Default | Description |
|---|---|---|---|
dsn |
str |
Required | Your project's Data Source Name |
environment |
str |
None |
Environment name (production, staging, development) |
release |
str |
None |
Release/version identifier for tracking |
debug |
bool |
False |
Enable debug logging to stderr |
sample_rate |
float |
1.0 |
Sample rate for events (0.0 to 1.0) |
max_breadcrumbs |
int |
100 |
Maximum breadcrumbs to store |
before_send |
callable |
None |
Callback to modify/filter events before sending |
before_send Example
def before_send(event):
# Filter out specific errors
if "KeyboardInterrupt" in event.get("message", ""):
return None # Drop the event
# Scrub sensitive data
if "extra" in event and "password" in event["extra"]:
del event["extra"]["password"]
return event
Statly.init(
dsn="...",
before_send=before_send,
)
API Reference
Statly.capture_exception(exception, **context)
Capture an exception with optional additional context:
try:
process_payment(order)
except PaymentError as e:
Statly.capture_exception(
e,
extra={
"order_id": order.id,
"amount": order.total,
},
tags={
"payment_provider": "stripe",
},
)
Statly.capture_message(message, level="info")
Capture a message event:
Statly.capture_message("User signed up", level="info")
Statly.capture_message("Payment failed after 3 retries", level="warning")
Statly.capture_message("Database connection lost", level="error")
Levels: "debug" | "info" | "warning" | "error" | "fatal"
Statly.set_user(**kwargs)
Set user context for all subsequent events:
Statly.set_user(
id="user-123",
email="user@example.com",
username="johndoe",
# Custom fields
subscription="premium",
)
# Clear user on logout
Statly.set_user(None)
Statly.set_tag(key, value) / Statly.set_tags(tags)
Set tags for filtering and searching:
Statly.set_tag("version", "1.0.0")
Statly.set_tags({
"environment": "production",
"server": "web-1",
"region": "us-east-1",
})
Statly.add_breadcrumb(**kwargs)
Add a breadcrumb for debugging context:
Statly.add_breadcrumb(
message="User clicked checkout button",
category="ui.click",
level="info",
data={
"button_id": "checkout-btn",
"cart_items": 3,
},
)
Statly.flush() / Statly.close()
# Flush pending events (keeps SDK running)
Statly.flush()
# Flush and close (use before process exit)
Statly.close()
Context Manager
Use context manager for automatic cleanup:
from statly_observe import Statly
with Statly.init(dsn="...") as client:
# Your code here
pass
# Automatically flushed and closed
Async Support
The SDK automatically detects async contexts:
import asyncio
from statly_observe import Statly
async def main():
Statly.init(dsn="...")
try:
await risky_async_operation()
except Exception as e:
Statly.capture_exception(e)
await Statly.flush_async()
asyncio.run(main())
Logging Integration
Capture Python logging as breadcrumbs or events:
import logging
from statly_observe import Statly
from statly_observe.integrations.logging import StatlyHandler
Statly.init(dsn="...")
# Add handler to capture logs as breadcrumbs
handler = StatlyHandler(level=logging.INFO)
logging.getLogger().addHandler(handler)
# Now logs are captured
logging.info("User logged in") # Becomes a breadcrumb
logging.error("Database error") # Captured as error event
Requirements
- Python 3.8+
- Works with sync and async code
License
MIT
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 statly_observe-0.1.0.tar.gz.
File metadata
- Download URL: statly_observe-0.1.0.tar.gz
- Upload date:
- Size: 18.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
aceeb914b85d2f7b869e6da2cfe6e4d6cca2674502330acb1f1417c738357680
|
|
| MD5 |
cf3d4786263fdefb95fbbf5926a8a101
|
|
| BLAKE2b-256 |
acd923278698209ce0abd5b1dca803149d818928e27d5a90fec88361d5fd9284
|
File details
Details for the file statly_observe-0.1.0-py3-none-any.whl.
File metadata
- Download URL: statly_observe-0.1.0-py3-none-any.whl
- Upload date:
- Size: 27.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b6dded564df3368dc545f97e4dfca65a4ef98cf3b55c39adeff813e6cbc6290d
|
|
| MD5 |
9731d231ed66ea4d6893dc5224196070
|
|
| BLAKE2b-256 |
7ac4c3c50e85dcb012effcf3a5e3d564f1e340a765716c710a87efd005383c01
|