LupisLabs Python SDK for AI application tracing and event tracking
Project description
Lupis Labs Python SDK
Python SDK for LupisLabs with OpenTelemetry tracing and custom event tracking.
Installation
pip install lupislabs
For async support (recommended):
pip install lupislabs[async]
Features
- 🔍 Automatic HTTP Tracing: Automatically captures HTTP requests using OpenTelemetry
- 📊 Custom Event Tracking: Track custom events with properties and metadata
- 💬 Chat ID Support: Group traces by conversation/chat ID
- ⚡ Batching: Automatically batches events for efficient transmission
- 🐍 Python Support: Full Python 3.8+ support with async/await
- 🔒 Sensitive Data Filtering: Automatically filters sensitive data in production
Quick Start
import asyncio
from lupislabs import LupisSDK, LupisConfig
async def main():
lupis = LupisSDK(LupisConfig(
project_id="your-project-id",
enabled=True,
otlp_endpoint="http://localhost:3010/api/traces",
))
lupis.track_event("user_login", {
"method": "email",
"success": True,
})
await lupis.shutdown()
if __name__ == "__main__":
asyncio.run(main())
Configuration
from lupislabs import LupisConfig
config = LupisConfig(
project_id="your-project-id", # Required
enabled=True, # Optional, default: True
otlp_endpoint="http://localhost:3010/api/traces", # Optional
service_name="lupis-sdk", # Optional, default: "lupis-sdk"
service_version="1.0.0", # Optional, default: "1.0.0"
filter_sensitive_data=True, # Optional, default: True
sensitive_data_patterns=[ # Optional, default: common patterns
"sk-[a-zA-Z0-9]{20,}",
"Bearer [a-zA-Z0-9._-]+",
],
redaction_mode="mask", # Optional: "mask", "remove", "hash"
)
Event Tracking
Basic Event Tracking
lupis.track_event("button_click", {
"button_name": "submit",
"page": "/dashboard",
})
Event with User Context
from lupislabs import LupisMetadata
lupis.track_event("feature_used", {
"feature": "export_data",
"format": "csv",
}, metadata=LupisMetadata(
user_id="user_123",
session_id="browser_session_456",
organization_id="org_789",
))
Conversation Grouping
Group traces by conversation/thread using chat_id:
# Set global chat ID for all subsequent traces
lupis.set_chat_id("conversation_123")
# Or set per-operation chat ID
await lupis.run(async def my_ai_function():
# Your AI conversation code here
pass
, options=LupisBlockOptions(chat_id="conversation_123"))
lupis.clear_chat_id()
Metadata Types
sessionId vs chatId
-
session_id: Browser/app session identifier that persists across conversations- Used for analytics and user journey tracking
- Example:
"browser_session_abc123"
-
chat_id: Individual conversation/thread identifier- Used for grouping related traces within a conversation
- Changes for each new conversation
- Example:
"chat_thread_xyz789"
Example Usage
from lupislabs import LupisMetadata, LupisBlockOptions
# Set user context (persists across conversations)
lupis.set_metadata(LupisMetadata(
user_id="user_123",
organization_id="org_456",
session_id="browser_session_abc123", # Same across conversations
))
# Start a new conversation
lupis.set_chat_id("conversation_1")
await lupis.run(async def ai_conversation_1():
# AI conversation code
pass
, options=LupisBlockOptions(chat_id="conversation_1"))
# Start another conversation (same session, different chat)
lupis.set_chat_id("conversation_2")
await lupis.run(async def ai_conversation_2():
# Another AI conversation code
pass
, options=LupisBlockOptions(chat_id="conversation_2"))
Event Batching
Events are automatically batched and sent to the server:
- Batch Size: Up to 50 events per batch
- Flush Interval: Every 5 seconds
- Auto-flush: On shutdown
OpenTelemetry Integration
The SDK automatically instruments HTTP requests and creates traces. Access the tracer:
tracer = lupis.get_tracer()
with lupis.create_span("custom-operation", {
"custom.attribute": "value",
}) as span:
# Your code here
pass
Sensitive Data Filtering
The SDK automatically filters sensitive data in production to protect API keys, tokens, and other sensitive information. This feature is enabled by default for security.
Default Filtering
The SDK automatically filters these common sensitive patterns:
API Keys & Tokens
sk-[a-zA-Z0-9]{20,}- OpenAI API keyspk_[a-zA-Z0-9]{20,}- Paddle API keysak-[a-zA-Z0-9]{20,}- Anthropic API keysBearer [a-zA-Z0-9._-]+- Bearer tokensx-api-key,authorization- API key headers
Authentication
password,passwd,pwd- Password fieldstoken,access_token,refresh_token,session_token- Various tokenssecret,private_key,api_secret- Secret fields
Personal Data
ssn,social_security- Social Security Numberscredit_card,card_number- Credit card numberscvv,cvc- Security codes
Redaction Modes
Choose how sensitive data is replaced:
Mask Mode (Default)
lupis = LupisSDK(LupisConfig(
project_id="your-project-id",
redaction_mode="mask", # Default
))
# Examples:
# sk-1234567890abcdef1234567890abcdef12345678 → sk-1***5678
# Bearer sk-1234567890abcdef1234567890abcdef12345678 → Bear***5678
# password: 'secret-password' → password: '***'
Remove Mode
lupis = LupisSDK(LupisConfig(
project_id="your-project-id",
redaction_mode="remove",
))
# Examples:
# sk-1234567890abcdef1234567890abcdef12345678 → [REDACTED]
# password: 'secret-password' → password: [REDACTED]
Hash Mode
lupis = LupisSDK(LupisConfig(
project_id="your-project-id",
redaction_mode="hash",
))
# Examples:
# sk-1234567890abcdef1234567890abcdef12345678 → [HASH:2dd0e9d5]
# password: 'secret-password' → password: [HASHED]
Custom Patterns
Add your own sensitive data patterns:
lupis = LupisSDK(LupisConfig(
project_id="your-project-id",
filter_sensitive_data=True,
sensitive_data_patterns=[
"sk-[a-zA-Z0-9]{20,}", # OpenAI API keys
"Bearer [a-zA-Z0-9._-]+", # Bearer tokens
"custom_secret", # Your custom field
"my_api_key", # Your custom field
"email", # Email addresses
],
redaction_mode="mask",
))
What Gets Filtered
The SDK filters sensitive data in:
- Request Headers: Authorization, API keys, tokens
- Request Bodies: JSON payloads with sensitive fields
- Response Data: API responses containing sensitive information
- Span Attributes: All OpenTelemetry span attributes
Disable Filtering (Development Only)
⚠️ Warning: Only disable filtering in development environments:
lupis = LupisSDK(LupisConfig(
project_id="your-project-id",
filter_sensitive_data=False, # ⚠️ Sensitive data will be exposed!
))
Production Security
- ✅ Enabled by default - No configuration needed
- ✅ Comprehensive coverage - Common sensitive patterns included
- ✅ Configurable - Add custom patterns as needed
- ✅ Performance optimized - Minimal impact when enabled
- ✅ Debugging friendly - Mask mode preserves partial data for debugging
Shutdown
Always call shutdown() to flush pending events and traces:
await lupis.shutdown()
Examples
See the examples/ directory for more usage examples:
event_tracking_example.py- Custom event trackinganthropic_example.py- Anthropic API integrationopenai_example.py- OpenAI API integrationlangchain_example.py- LangChain integrationstreaming_example.py- Streaming responses
Requirements
- Python 3.8+
- requests
- opentelemetry-api
- opentelemetry-sdk
- opentelemetry-exporter-otlp-proto-http
- opentelemetry-instrumentation-requests
License
Made with ❤️ by the Lupis team
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
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 lupislabs-1.0.0.tar.gz.
File metadata
- Download URL: lupislabs-1.0.0.tar.gz
- Upload date:
- Size: 15.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
97869f01ac56d0592b8c428047be0ede488d4404b66f3282ec7d68ba7469db1b
|
|
| MD5 |
8bf53da71f9cd7e8e61a38ff999286a8
|
|
| BLAKE2b-256 |
40734df9d4738ff54450a3d5dd5f3335ee17e7e5610fc2779c47f97eab86af54
|
Provenance
The following attestation bundles were made for lupislabs-1.0.0.tar.gz:
Publisher:
publish-python.yml on henchiyb/lupis-labs
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
lupislabs-1.0.0.tar.gz -
Subject digest:
97869f01ac56d0592b8c428047be0ede488d4404b66f3282ec7d68ba7469db1b - Sigstore transparency entry: 600845689
- Sigstore integration time:
-
Permalink:
henchiyb/lupis-labs@f4fbb996a5bc6b300cf97af69eaee397b4064fd8 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/henchiyb
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-python.yml@f4fbb996a5bc6b300cf97af69eaee397b4064fd8 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file lupislabs-1.0.0-py3-none-any.whl.
File metadata
- Download URL: lupislabs-1.0.0-py3-none-any.whl
- Upload date:
- Size: 14.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b0fc6b4c3be6fb21ac26e7eba805fc4dcee7692d36a9da1dc33d051ec2ff5a6a
|
|
| MD5 |
f3456f4150c31c660ee47ee35368e923
|
|
| BLAKE2b-256 |
02c02a501600f878b9dd7451b68898c2bbf8a3af8cdbf19045ae79200725f940
|
Provenance
The following attestation bundles were made for lupislabs-1.0.0-py3-none-any.whl:
Publisher:
publish-python.yml on henchiyb/lupis-labs
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
lupislabs-1.0.0-py3-none-any.whl -
Subject digest:
b0fc6b4c3be6fb21ac26e7eba805fc4dcee7692d36a9da1dc33d051ec2ff5a6a - Sigstore transparency entry: 600845691
- Sigstore integration time:
-
Permalink:
henchiyb/lupis-labs@f4fbb996a5bc6b300cf97af69eaee397b4064fd8 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/henchiyb
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-python.yml@f4fbb996a5bc6b300cf97af69eaee397b4064fd8 -
Trigger Event:
workflow_dispatch
-
Statement type: