Python (Sentry-compatible SDK)
Use the official sentry-sdk for Python with a Belvador DSN and the data-scrubbing hook Belvador provides.
On this page
For Python Belvador uses the official sentry-sdk with your Belvador DSN, plus the init options and scrubbing hook below.
Before you start#
A project with platform Python and its DSN.
A Python version supported by the current
sentry-sdkrelease (see Sentry's Python guide).
1. Install#
pip install --upgrade "sentry-sdk"2. Initialize at start-up#
Put this where your app starts — before your web framework is imported is best, so its integration is set up too.
import osimport sentry_sdkimport reSENSITIVE_KEY = re.compile(r"password|passwd|pwd|secret|api_key|apikey|api-key|access_token|auth|credentials|credit_card|card_number|cvv|private_key|privatekey|session|cookie|token|bearer|ssn|dob", re.I)DROP_HEADER = re.compile(r"^(authorization|proxy-authorization|cookie|set-cookie|x-forwarded-for|x-real-ip|cf-connecting-ip|true-client-ip)$", re.I)IN_TEXT = [ (re.compile(r"\bBearer\s+[A-Za-z0-9._~+/-]+=*", re.I), "Bearer [Filtered]"), (re.compile(r"\beyJ[A-Za-z0-9_-]{5,}\.[A-Za-z0-9_-]{5,}\.[A-Za-z0-9_-]{5,}"), "[Filtered]"), (re.compile(r"\b[sr]k_(live|test)_[A-Za-z0-9]{8,}\b"), "[Filtered]"), (re.compile(r"([?&#;\s\"']?[^=&#\s\"':]*(?:token|key|secret|password|session|auth)[^=&#\s\"':]*[\"']?\s*[=:]\s*[\"']?)[^&#\s\"',}]+", re.I), r"\1[Filtered]"),]def scrub_text(text): for pattern, repl in IN_TEXT: text = pattern.sub(repl, text) return textdef scrub_value(value, depth=0): if isinstance(value, str): return scrub_text(value) if depth > 8: return value if isinstance(value, (list, tuple)): return [scrub_value(v, depth + 1) for v in value] if isinstance(value, dict): return {k: "[Filtered]" if SENSITIVE_KEY.search(str(k)) else scrub_value(v, depth + 1) for k, v in value.items()} return valuedef scrub_event(event, hint): request = event.get("request") if request: for field in ("data", "cookies", "env"): request.pop(field, None) headers = request.get("headers") or {} for name in list(headers): if DROP_HEADER.match(name): del headers[name] elif SENSITIVE_KEY.search(name): headers[name] = "[Filtered]" if isinstance(request.get("url"), str): request["url"] = scrub_text(request["url"]) if request.get("query_string"): request["query_string"] = scrub_value(request["query_string"]) user = event.get("user") if user is not None: event["user"] = {"id": user["id"]} if "id" in user else None if event.get("message"): event["message"] = scrub_text(event["message"]) if event.get("logentry"): event["logentry"] = scrub_value(event["logentry"]) for ex in (event.get("exception") or {}).get("values") or []: if ex.get("value"): ex["value"] = scrub_text(ex["value"]) for field in ("extra", "contexts", "tags"): if event.get(field): event[field] = scrub_value(event[field]) crumbs = event.get("breadcrumbs") if isinstance(crumbs, dict) and crumbs.get("values"): crumbs["values"] = [scrub_value(b) for b in crumbs["values"]] return eventsentry_sdk.init( dsn=os.environ.get("BELVADOR_DSN", "https://<public-key>@ingest.belvador.dev/<project-id>"), release=os.environ.get("APP_VERSION"), environment=os.environ.get("APP_ENV", "production"), send_default_pii=False, traces_sample_rate=0, max_breadcrumbs=50, max_value_length=8192, before_send=scrub_event,)| Option | Why |
|---|---|
dsn | Reads BELVADOR_DSN from the environment, with the project DSN as fallback |
release, environment | From APP_VERSION and APP_ENV (default production) |
send_default_pii=False | No IP addresses, cookies or user details added by the SDK |
traces_sample_rate=0 | The Sentry SDK sends no spans; for traces use OpenTelemetry |
max_breadcrumbs=50, max_value_length=8192 | Same bounds as Belvador's own SDKs |
before_send=scrub_event | Removes request bodies, cookies, auth headers and client IP headers; keeps only user.id; masks values under sensitive names and credentials in text |
Frameworks#
sentry-sdk turns on integrations for frameworks it finds installed, such as Django, Flask and FastAPI, so unhandled errors in requests are reported. Framework-specific options are in Sentry's Python guide. Belvador has not verified each framework.
Report errors you handle#
import sentry_sdktry: charge_card(order)except PaymentError as error: sentry_sdk.capture_exception(error) raiseCheck that it works#
import sentry_sdksentry_sdk.capture_exception(Exception("Belvador Python test"))sentry_sdk.flush(timeout=2)Run it with the same sentry_sdk.init(...) as your app. The issue appears in the project within a few seconds.
Limits to know#
The scrubbing hook is pattern-based. A secret under an unusual name, or inside a free-text message, can slip through.
Keep
traces_sample_rate=0; tracing data is not stored and is counted as Not supported yet in the project's intake numbers.Scheduled jobs and Celery beat tasks can report runs with
sentry_sdk.crons— see Monitors with the official Sentry SDKs.
Posts on this topic
All posts- How to trace failed agent tool calls without losing or doubling errorsSpan status, exception events and error reporting for agent tool calls that fail or retry, with counts from 60 agent runs and one fix for the handler.
- AI agent observability: the failures that still return 20060 runs of a support agent with seeded tool failures: every failure returned 200 and sent no error. What traces showed, and what customers were told.
Spotted something wrong or missing? Tell us: hello@belvador.dev