Skip to main content

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 keys
  • pk_[a-zA-Z0-9]{20,} - Paddle API keys
  • ak-[a-zA-Z0-9]{20,} - Anthropic API keys
  • Bearer [a-zA-Z0-9._-]+ - Bearer tokens
  • x-api-key, authorization - API key headers

Authentication

  • password, passwd, pwd - Password fields
  • token, access_token, refresh_token, session_token - Various tokens
  • secret, private_key, api_secret - Secret fields

Personal Data

  • ssn, social_security - Social Security Numbers
  • credit_card, card_number - Credit card numbers
  • cvv, 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 tracking
  • anthropic_example.py - Anthropic API integration
  • openai_example.py - OpenAI API integration
  • langchain_example.py - LangChain integration
  • streaming_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

lupislabs-1.0.0.tar.gz (15.5 kB view details)

Uploaded Source

Built Distribution

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

lupislabs-1.0.0-py3-none-any.whl (14.4 kB view details)

Uploaded Python 3

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

Hashes for lupislabs-1.0.0.tar.gz
Algorithm Hash digest
SHA256 97869f01ac56d0592b8c428047be0ede488d4404b66f3282ec7d68ba7469db1b
MD5 8bf53da71f9cd7e8e61a38ff999286a8
BLAKE2b-256 40734df9d4738ff54450a3d5dd5f3335ee17e7e5610fc2779c47f97eab86af54

See more details on using hashes here.

Provenance

The following attestation bundles were made for lupislabs-1.0.0.tar.gz:

Publisher: publish-python.yml on henchiyb/lupis-labs

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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

Hashes for lupislabs-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 b0fc6b4c3be6fb21ac26e7eba805fc4dcee7692d36a9da1dc33d051ec2ff5a6a
MD5 f3456f4150c31c660ee47ee35368e923
BLAKE2b-256 02c02a501600f878b9dd7451b68898c2bbf8a3af8cdbf19045ae79200725f940

See more details on using hashes here.

Provenance

The following attestation bundles were made for lupislabs-1.0.0-py3-none-any.whl:

Publisher: publish-python.yml on henchiyb/lupis-labs

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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