Skip to main content

Error tracking and monitoring SDK for Python applications

Project description

Statly Observe SDK for Python

PyPI version Python versions License: MIT

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

  1. Go to statly.live/dashboard/observe/setup
  2. Create an API key for Observe
  3. 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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

statly_observe-0.1.0.tar.gz (18.9 kB view details)

Uploaded Source

Built Distribution

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

statly_observe-0.1.0-py3-none-any.whl (27.4 kB view details)

Uploaded Python 3

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

Hashes for statly_observe-0.1.0.tar.gz
Algorithm Hash digest
SHA256 aceeb914b85d2f7b869e6da2cfe6e4d6cca2674502330acb1f1417c738357680
MD5 cf3d4786263fdefb95fbbf5926a8a101
BLAKE2b-256 acd923278698209ce0abd5b1dca803149d818928e27d5a90fec88361d5fd9284

See more details on using hashes here.

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

Hashes for statly_observe-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 b6dded564df3368dc545f97e4dfca65a4ef98cf3b55c39adeff813e6cbc6290d
MD5 9731d231ed66ea4d6893dc5224196070
BLAKE2b-256 7ac4c3c50e85dcb012effcf3a5e3d564f1e340a765716c710a87efd005383c01

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