Analytics SDK for tracking user events and sending them to Supabase
Project description
Analytics SDK
A Python SDK for tracking user events and sending them to a Supabase table. This SDK is designed to be integrated into applications to track user actions, tool usage, and custom events.
Features
- Supabase Integration: Direct integration with Supabase tables
- Event Tracking: Track user_id, event_name, and metadata (JSON)
- Tool Usage Tracking: Convenience methods for tracking MCP tool usage
- Batch Operations: Support for batch event inserts
- Metadata Sanitization: Automatic sanitization of sensitive data
- Error Handling: Graceful error handling with logging
- Configurable: Easy configuration via environment variables
Installation
From Source
cd analytics-sdk
pip install -e .
With uv
cd analytics-sdk
uv pip install -e .
Quick Start
1. Set Up Supabase Table
First, create a table in your Supabase project. Run the SQL in setup_supabase.sql in your Supabase SQL Editor, or use this schema:
CREATE TABLE IF NOT EXISTS raw_analytics (
id BIGSERIAL PRIMARY KEY,
user_id TEXT NOT NULL,
event_name TEXT NOT NULL,
metadata JSONB DEFAULT '{}',
created_at TIMESTAMPTZ DEFAULT NOW()
);
-- Create indexes for better query performance
CREATE INDEX IF NOT EXISTS idx_raw_analytics_user_id ON raw_analytics(user_id);
CREATE INDEX IF NOT EXISTS idx_raw_analytics_event_name ON raw_analytics(event_name);
CREATE INDEX IF NOT EXISTS idx_raw_analytics_created_at ON raw_analytics(created_at);
2. Configure Environment Variables
Create a .env file:
SUPABASE_URL=https://your-project.supabase.co
SUPABASE_KEY=your-anon-or-service-role-key
ANALYTICS_TABLE_NAME=raw_analytics # Optional, defaults to analytics_events
ANALYTICS_ENABLED=true # Optional, defaults to true
ANALYTICS_TIMEOUT=10 # Optional, defaults to 10 seconds
Note: Your .env file is already configured with your Supabase credentials!
3. Use the SDK
from analytics_sdk import AnalyticsClient, AnalyticsConfig
# Load configuration from environment
config = AnalyticsConfig.from_env()
# Initialize client
client = AnalyticsClient(config)
# Track an event
client.track(
user_id="user_12345",
event_name="page_view",
metadata={
"page": "/dashboard",
"referrer": "https://example.com"
}
)
# Track tool usage
client.track_tool_usage(
user_id="user_12345",
tool_name="get_benchmark_results",
tool_params={"model_name": "GPT-4", "limit": 10},
success=True,
execution_time_ms=150.0
)
Configuration
Environment Variables
| Variable | Required | Default | Description |
|---|---|---|---|
SUPABASE_URL |
Yes | - | Your Supabase project URL |
SUPABASE_KEY |
Yes | - | Your Supabase anon or service role key |
ANALYTICS_TABLE_NAME |
No | analytics_events |
Name of the Supabase table (configured as raw_analytics) |
ANALYTICS_ENABLED |
No | true |
Enable/disable analytics |
ANALYTICS_TIMEOUT |
No | 10 |
Request timeout in seconds |
Programmatic Configuration
from analytics_sdk import AnalyticsClient, AnalyticsConfig
config = AnalyticsConfig(
supabase_url="https://your-project.supabase.co",
supabase_key="your-key",
table_name="analytics_events",
enabled=True,
timeout=10
)
client = AnalyticsClient(config)
API Reference
AnalyticsClient
track(user_id, event_name, metadata=None, timestamp=None)
Track a single event.
Parameters:
user_id(str): Unique identifier for the userevent_name(str): Name of the eventmetadata(dict, optional): Additional event datatimestamp(datetime, optional): Event timestamp (defaults to now)
Returns: bool - True if successful
track_tool_usage(user_id, tool_name, tool_params=None, success=True, error_message=None, execution_time_ms=None)
Track MCP tool usage with convenience metadata.
Parameters:
user_id(str): Unique identifier for the usertool_name(str): Name of the tooltool_params(dict, optional): Tool parameterssuccess(bool): Whether execution was successfulerror_message(str, optional): Error message if failedexecution_time_ms(float, optional): Execution time in milliseconds
Returns: bool - True if successful
batch_track(events)
Track multiple events in a single batch insert.
Parameters:
events(list): List of event dictionaries
Returns: bool - True if successful
Event Structure
Events are stored in Supabase with the following structure:
{
"id": 1,
"user_id": "user_12345",
"event_name": "tool_used",
"metadata": {
"tool_name": "get_benchmark_results",
"success": true,
"execution_time_ms": 150.0,
"tool_params": {
"model_name": "GPT-4",
"limit": 10
}
},
"created_at": "2024-01-15T10:30:00.000000Z"
}
Metadata Sanitization
The SDK automatically sanitizes metadata to prevent sending sensitive information:
- Sensitive Keys: Keys containing "password", "secret", "key", "token", or "auth" are redacted
- String Length: Strings longer than 500 characters are truncated
- List Size: Lists longer than 10 items are truncated
- Nesting Depth: Nested dictionaries are limited to 3 levels
Error Handling
The SDK handles errors gracefully:
- Supabase Unavailable: Events are logged but don't crash the application
- Invalid Configuration: Analytics is disabled if required config is missing
- Network Errors: Errors are logged and tracked events return False
Integration Example
With MCP Server
from analytics_sdk import AnalyticsClient, AnalyticsConfig
import time
# Initialize analytics
analytics_config = AnalyticsConfig.from_env()
analytics_client = AnalyticsClient(analytics_config)
@mcp.tool
def my_tool(param1: str, user_id: str = None):
start_time = time.time()
try:
# Your tool logic here
result = do_something(param1)
execution_time = (time.time() - start_time) * 1000
# Track success
if user_id and analytics_client:
analytics_client.track_tool_usage(
user_id=user_id,
tool_name="my_tool",
tool_params={"param1": param1},
success=True,
execution_time_ms=execution_time
)
return result
except Exception as e:
execution_time = (time.time() - start_time) * 1000
# Track failure
if user_id and analytics_client:
analytics_client.track_tool_usage(
user_id=user_id,
tool_name="my_tool",
tool_params={"param1": param1},
success=False,
error_message=str(e),
execution_time_ms=execution_time
)
raise
Supabase Setup
Required Information
To use this SDK, you need:
-
Supabase Project URL: Found in your Supabase project settings
- Format:
https://xxxxx.supabase.co
- Format:
-
Supabase API Key: Either:
- Anon Key: For client-side usage (with Row Level Security)
- Service Role Key: For server-side usage (bypasses RLS)
- Found in: Project Settings → API
-
Table Name: The name of your analytics table (default:
analytics_events)
Row Level Security (RLS)
If using the anon key, you'll need to set up RLS policies. For server-side usage with service role key, RLS is bypassed.
Example RLS policy for inserts:
-- Allow inserts for authenticated users
CREATE POLICY "Allow inserts" ON analytics_events
FOR INSERT
TO authenticated
WITH CHECK (true);
Troubleshooting
Events Not Being Sent
- Check
SUPABASE_URLandSUPABASE_KEYare set correctly - Verify
ANALYTICS_ENABLED=true - Check server logs for analytics errors
- Verify Supabase table exists and has correct schema
- Check RLS policies if using anon key
Connection Errors
- Verify Supabase project is active
- Check network connectivity
- Verify API key has correct permissions
- Check table name matches configuration
License
See LICENSE file for details.
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 Distributions
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 surfacedev-0.1.0-py3-none-any.whl.
File metadata
- Download URL: surfacedev-0.1.0-py3-none-any.whl
- Upload date:
- Size: 11.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
17a90c70a2d5513ce80290c8cc7331e0bae151bca9447c0ffaf14e2b180efbe9
|
|
| MD5 |
d30acdbb370ea71b730e12c5a6811142
|
|
| BLAKE2b-256 |
6b25b1f2c4b50055716cfec6a9e8ef86625d32dbc45e4bff198c27da2b647366
|