Skip to main content

Error Explorer SDK for Python - Automatic error tracking and monitoring

Project description

Error Explorer SDK for Python

Official Python SDK for Error Explorer - Automatic error tracking and monitoring for Python applications.

Features

  • Automatic Error Capture - Captures uncaught exceptions via sys.excepthook
  • Thread Error Capture - Captures errors in threads via threading.excepthook
  • Breadcrumbs - Track user actions and events leading to errors
  • User Context - Associate errors with user information
  • Tags & Extra Data - Add custom metadata to errors
  • Data Scrubbing - Automatic removal of sensitive data
  • Scope Management - Isolated context for specific operations
  • Async Support - Optional async transport via aiohttp

Installation

pip install error-explorer

For async support:

pip install error-explorer[async]

Quick Start

from error_explorer import ErrorExplorer

# Initialize the SDK
ErrorExplorer.init({
    "token": "your_error_explorer_token",
    "project": "my-python-app",
    "environment": "production",
    "release": "1.0.0",
})

# Errors are now automatically captured!

Configuration Options

from error_explorer import ErrorExplorer, ErrorExplorerOptions

options = ErrorExplorerOptions(
    # Required
    token="your_token",

    # Optional
    project="my-project",
    environment="production",          # Default: "production"
    release="1.0.0",                   # Your app version
    endpoint="https://error-explorer.com/api/v1/webhook",  # Default endpoint
    hmac_secret="optional_hmac_secret", # For request signing

    debug=False,                        # Enable debug logging
    enabled=True,                       # Enable/disable SDK
    sample_rate=1.0,                    # 0.0 to 1.0
    max_breadcrumbs=100,               # Maximum breadcrumbs to keep
    attach_stacktrace=True,            # Include local variables
    send_default_pii=False,            # Scrub PII by default
    server_name="web-1",               # Server identifier
    timeout=10.0,                      # HTTP timeout in seconds

    # Auto capture options
    auto_capture={
        "uncaught_exceptions": True,   # Capture via sys.excepthook
        "unhandled_threads": True,     # Capture thread errors
        "logging": False,              # Add log entries as breadcrumbs
    },

    # Breadcrumb options
    breadcrumbs={
        "enabled": True,
        "max_breadcrumbs": 100,
        "logging": True,
        "http": True,
    },

    # Custom fields to scrub
    scrub_fields=["custom_secret", "my_api_key"],

    # Event processing hook
    before_send=lambda event: event,   # Modify or drop events
)

ErrorExplorer.init(options)

Manual Error Capture

from error_explorer import ErrorExplorer, CaptureContext, User

client = ErrorExplorer.get_client()

# Capture an exception
try:
    risky_operation()
except Exception as e:
    client.capture_exception(e)

# Capture with additional context
try:
    process_order(order_id)
except Exception as e:
    client.capture_exception(e, CaptureContext(
        user=User(id="user_123", email="user@example.com"),
        tags={"order_id": order_id},
        extra={"order_details": order_data},
    ))

# Capture the current exception
try:
    something()
except:
    client.capture_exception()  # Captures current exception

# Capture a message
client.capture_message("Payment processed successfully", level="info")
client.capture_message("Rate limit approaching", level="warning")

User Context

from error_explorer import ErrorExplorer, User

client = ErrorExplorer.get_client()

# Set user context
client.set_user(User(
    id="user_12345",
    email="user@example.com",
    username="johndoe",
    ip_address="192.168.1.1",
    extra={"subscription": "pro"},
))

# Or use a dict
client.set_user({
    "id": "user_12345",
    "email": "user@example.com",
})

# Clear user on logout
client.clear_user()

Breadcrumbs

from error_explorer import ErrorExplorer, Breadcrumb, BreadcrumbType, BreadcrumbLevel

client = ErrorExplorer.get_client()

# Add a breadcrumb
client.add_breadcrumb(Breadcrumb(
    message="User clicked checkout button",
    category="ui.click",
    type=BreadcrumbType.UI,
    level=BreadcrumbLevel.INFO,
    data={"button_id": "checkout-btn"},
))

# Using a dict
client.add_breadcrumb({
    "message": "API request completed",
    "category": "http",
    "type": "http",
    "data": {"url": "/api/orders", "status_code": 200},
})

# Clear all breadcrumbs
client.clear_breadcrumbs()

Tags and Extra Data

client = ErrorExplorer.get_client()

# Set a single tag
client.set_tag("version", "2.0.0")

# Set multiple tags
client.set_tags({
    "environment": "production",
    "region": "us-east-1",
    "feature_flag": "new_checkout",
})

# Remove a tag
client.remove_tag("feature_flag")

# Set extra data
client.set_extra("request_id", "req_abc123")

# Set named context
client.set_context("order", {
    "id": "order_123",
    "total": 99.99,
    "items": 3,
})

Scope Management

client = ErrorExplorer.get_client()

# Use scope for temporary context
with client.push_scope() as scope:
    scope.set_tag("transaction", "checkout")
    scope.set_user(User(id="temp_user"))
    scope.add_breadcrumb(Breadcrumb(message="In checkout flow"))

    try:
        process_checkout()
    except Exception as e:
        # Error will include scoped context
        client.capture_exception(e)

# Context is automatically restored after the scope

Before Send Hook

def before_send(event):
    # Modify the event
    event["tags"]["processed"] = "true"

    # Drop events based on conditions
    if event.get("level") == "debug":
        return None  # Don't send debug events

    # Remove sensitive data
    if "extra" in event and "password" in event["extra"]:
        del event["extra"]["password"]

    return event

ErrorExplorer.init({
    "token": "your_token",
    "before_send": before_send,
})

Flushing and Closing

client = ErrorExplorer.get_client()

# Flush pending events (useful before shutdown)
success = client.flush(timeout=5.0)

# Close the SDK (also flushes)
client.close()

Framework Integration

Flask

from flask import Flask
from error_explorer import ErrorExplorer, Breadcrumb

app = Flask(__name__)

# Initialize on app startup
ErrorExplorer.init({
    "token": "your_token",
    "environment": "production",
})

@app.before_request
def before_request():
    client = ErrorExplorer.get_client()
    client.add_breadcrumb(Breadcrumb(
        message=f"{request.method} {request.path}",
        category="http",
        type="http",
    ))

@app.errorhandler(Exception)
def handle_exception(e):
    client = ErrorExplorer.get_client()
    client.capture_exception(e)
    return "Internal Server Error", 500

Django

# settings.py
MIDDLEWARE = [
    'myapp.middleware.ErrorExplorerMiddleware',
    # ... other middleware
]

# middleware.py
from error_explorer import ErrorExplorer, Breadcrumb

class ErrorExplorerMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response
        ErrorExplorer.init({
            "token": "your_token",
            "environment": "production",
        })

    def __call__(self, request):
        client = ErrorExplorer.get_client()

        # Add request breadcrumb
        client.add_breadcrumb(Breadcrumb(
            message=f"{request.method} {request.path}",
            category="http",
        ))

        # Set user if authenticated
        if request.user.is_authenticated:
            client.set_user({
                "id": str(request.user.id),
                "email": request.user.email,
            })

        response = self.get_response(request)
        return response

    def process_exception(self, request, exception):
        client = ErrorExplorer.get_client()
        client.capture_exception(exception)
        return None

Testing

# Install dev dependencies
pip install -e ".[dev]"

# Run tests
pytest

# Run with coverage
pytest --cov=error_explorer --cov-report=html

Requirements

  • Python 3.9+
  • requests (for HTTP transport)
  • aiohttp (optional, for async transport)

License

MIT License - see LICENSE file for details.

Support

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

error_explorer-1.1.0.tar.gz (31.3 kB view details)

Uploaded Source

Built Distribution

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

error_explorer-1.1.0-py3-none-any.whl (18.5 kB view details)

Uploaded Python 3

File details

Details for the file error_explorer-1.1.0.tar.gz.

File metadata

  • Download URL: error_explorer-1.1.0.tar.gz
  • Upload date:
  • Size: 31.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.12

File hashes

Hashes for error_explorer-1.1.0.tar.gz
Algorithm Hash digest
SHA256 816497be89294929aeef4826d22f17813f7d8c704f86c94cae507fde51eedc70
MD5 46fd0a1e0e79d8559285c9a0e9c3b09e
BLAKE2b-256 a46b7bc700d18845732ce68408c78d1e6dd7aa1a8e222e29c5596d5b552411db

See more details on using hashes here.

File details

Details for the file error_explorer-1.1.0-py3-none-any.whl.

File metadata

  • Download URL: error_explorer-1.1.0-py3-none-any.whl
  • Upload date:
  • Size: 18.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.12

File hashes

Hashes for error_explorer-1.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 be76754581b2c7bc8484011ed52fd3f03477131570005b99f954c6de0a6fd2bf
MD5 507557049a6382ac1afb740a808bb305
BLAKE2b-256 0f61f3eeba3d2cbe10e0a88907531092b4a20b6f9047b9b643b5925ce84ea61f

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