Skip to main content

Clue Backend SDK (Python) — OTel-based observation-source event capture for Django, FastAPI, Celery, SQLAlchemy, LangChain, LlamaIndex, CrewAI, MCP, and AI providers.

Project description

clue-backend-sdk

Shared Python backend core for Clue SDK wrappers (Django, FastAPI, Celery). Events flow through an OTel TracerProvider + BatchSpanProcessor + ObservationSourceEventExporter to /api/v1/ingest/backend.

Minimal integration

The SDK exposes a single clue namespace with eight methods (init / identify / group / reset / track / set_consent / flush / close). This mirrors the cross-SDK contract documented in docs/contracts/sdk/public-api.md §1.6.

import asyncio
from clue_backend_sdk import clue

clue.init({
    "endpoint": "https://ingest.example.com/api/v1/ingest/backend",
    "project_key": "...",
    "api_key": "...",
    "service_key": "backend-api",
})

clue.identify("user_42", {"name": "Alice", "email": "alice@example.com"})
clue.group("organization", "org_7", {"name": "Acme Inc"})
clue.track("order_placed", {"product_name": "shirt", "amount": 100})
clue.set_consent("granted")

# Shutdown idiom — both are coroutines for cross-SDK parity.
asyncio.run(clue.flush())
asyncio.run(clue.close())

Do not pass environment or service_name in the MVP setup path. Clue derives dev/prod from the project key prefix, and service_key is the single literal customer-facing backend service label.

clue.track custom event names must match ^[A-Za-z0-9_.:-]{1,128}$. Invalid names are ignored and do not emit a source-signal custom track intent. clue.set_consent only records local SDK state in the MVP backend SDK; it does not emit consent transition events.

Framework wrappers and runtime helpers are imported from their owning modules. The package root is intentionally small: customer-facing lifecycle methods plus stable setup helpers. Direct event builders are not public extension points.

Architecture boundary

The Python SDK is a thin language wrapper around OpenTelemetry and the Clue transport. Framework integrations create spans or annotate the current span, the exporter serializes those spans as sdk_source_signal_observed events, and the Clue backend ingest core performs classification, normalization, privacy projection, and raw-ingest shaping.

Python framework / library hook
  -> OTel span or Clue source-signal attributes
  -> ObservationSourceEventExporter
  -> /api/v1/ingest/backend
  -> apps/api/src/modules/ingest core

Rules:

  • Keep framework code limited to raw facts, correlation context, and standard OTel attributes.
  • Do not add Python-only classification, direct event builders, or custom fallback behavior.
  • Add classifier behavior in the backend ingest core so Node.js, Python, and future SDK wrappers receive the same behavior.
  • Preserve interaction_id, request_span_id, request_id, and trace_id whenever they are available. User-action linkage is an ingest contract, not a display-only field.

Privacy and PII handling

1. Hard-deny: PII / secrets are stripped before transport

The SDK strips a built-in set of property keys before the event leaves the customer process. Caller-supplied denied_keys are added on top of DEFAULT_DENIED_KEYS — they cannot remove a default-denied key.

Hard-deny categories (case- and separator-insensitive — userEmail, user-email, USER_EMAIL, email_address all match):

  • Auth credentials: authorization, cookie, set-cookie, password, passwd, secret, token, access_token, refresh_token, session, session_token, api_key, apikey, private_key
  • PII categories: email, phone, credit_card, ssn

This list is a strict superset of the server-side ingest hard-deny (@clue/shared INGEST_HARD_DENY_KEYS), enforced by the tests/test_privacy_parity.py cross-SDK parity test.

2. HTTP body capture (Django / FastAPI wrappers)

For framework wrappers that capture HTTP request bodies via parameter_snapshot.py, the same hard-deny applies: body.email cannot be unmasked via allowed_value_paths because email is in DEFAULT_DENIED_KEYS. Use a non-PII path (e.g. body.product_name) for explicit plaintext capture.

3. Default-masked: configure server allowlist for analysis projection

Properties that pass the hard-deny gate are still masked by default on the server side. To make a property appear in Clue's analysis UI, the property key must be listed on the resolved project service's observationAnalysisPropertyAllowlist. Without this, the property lands in raw_only_keys (visible in raw observation storage only) and not in analysisProperties.projected.

4. Identity traits stay privacy-safe

clue.identify(user_id, traits={...}) accepts profile traits such as name, email, avatarUrl, role, and plan. Use a stable opaque user_id; the SDK converts email into privacy-safe contact-derived fields before canonical identity events leave the process.

Build / test

python3 -m venv .venv
source .venv/bin/activate
pip install -e '.[test]'
python -m pytest

Live-verify (opt-in, requires apps/api + apps/worker running):

CLUE_LIVE_VERIFY=1 \
CLUE_LIVE_PROJECT_KEY=pk_dev_xxx \
CLUE_LIVE_API_KEY=cluesk_dev_xxx \
python -m pytest tests/test_canonical_endpoint_live.py -v

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

clue_backend_sdk-1.0.0.tar.gz (175.8 kB view details)

Uploaded Source

Built Distribution

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

clue_backend_sdk-1.0.0-py3-none-any.whl (163.4 kB view details)

Uploaded Python 3

File details

Details for the file clue_backend_sdk-1.0.0.tar.gz.

File metadata

  • Download URL: clue_backend_sdk-1.0.0.tar.gz
  • Upload date:
  • Size: 175.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.9.6

File hashes

Hashes for clue_backend_sdk-1.0.0.tar.gz
Algorithm Hash digest
SHA256 80ab1b6ddada1ff279b73be99280ff31cd7b57552cb21d6331f767903e513ccc
MD5 dbada03812b29cee5d4e10b130a2b9f7
BLAKE2b-256 81b71cfcfa185df8556080e9f3489818f32b82e323b55dadfb88f0bf2b6c94d2

See more details on using hashes here.

File details

Details for the file clue_backend_sdk-1.0.0-py3-none-any.whl.

File metadata

File hashes

Hashes for clue_backend_sdk-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 747c847b9970feaf1a1e590ea0995094a100db5166f75aa48f26fe0eace93aca
MD5 40876166ec6ff1823311719d7ff9694d
BLAKE2b-256 43d89ea71e2ac8d86e4bd8d4fef1baca64c729ce106dd559daec5873617d7c04

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