| title | Code variables in Python |
|---|
The Python SDK (v6.9.1+) supports automatic code variables capture, allowing you to see the state of local variables when exceptions occur.
Code variables capture can be enabled globally during PostHog initialization:
from posthog import Posthog
posthog = Posthog(
"<ph_project_token>",
enable_exception_autocapture=True,
capture_exception_code_variables=True,
)You can enable or disable code variables capture for specific code blocks using contexts:
from posthog import new_context
# Enable for a specific block (when disabled globally)
with new_context():
set_capture_exception_code_variables_context(True)
will_capture_variables()
# Disable for a specific block (when enabled globally)
with new_context():
set_capture_exception_code_variables_context(False)
will_not_capture_variables()Variable names matching mask patterns will have their values replaced with *** in the UI.
The SDK includes sensible defaults for common sensitive variable names:
DEFAULT_CODE_VARIABLES_MASK_PATTERNS = [
r"(?i).*password.*",
r"(?i).*secret.*",
r"(?i).*passwd.*",
r"(?i).*pwd.*",
r"(?i).*api_key.*",
r"(?i).*apikey.*",
r"(?i).*auth.*",
r"(?i).*credentials.*",
r"(?i).*privatekey.*",
r"(?i).*private_key.*",
r"(?i).*token.*",
]posthog = Posthog(
"<ph_project_token>",
enable_exception_autocapture=True,
capture_exception_code_variables=True,
code_variables_mask_patterns=[
r".*password.*", # Mask any variable containing "password"
r".*token.*", # Mask any variable containing "token"
r".*secret.*", # Mask any variable containing "secret"
r"client_secret", # Mask specific variable names
r"private_key", # Mask specific variable names
],
)You can set mask patterns for specific code blocks using contexts:
with new_context():
set_code_variables_mask_patterns_context([r".*password.*"])
mask_patterns_will_only_apply_to_this_method()As a last resort, the SDK also scans captured variable values for high-entropy secrets that name-based masking misses — API keys, tokens, and strong passwords in innocuously-named variables — and replaces them with ***. It recognizes common key formats (OpenAI, Anthropic, AWS, Stripe, GitHub, and more) and random high-entropy strings, while leaving identifiers like UUIDs, hashes, file paths, and URLs untouched.
This is enabled by default. To disable it globally:
posthog = Posthog(
"<ph_project_token>",
enable_exception_autocapture=True,
capture_exception_code_variables=True,
code_variables_detect_secrets=False,
)Or for a specific code block using contexts:
with new_context():
set_code_variables_detect_secrets_context(False)
detection_disabled_only_here()Credentials embedded in connection strings and URLs are scrubbed automatically, regardless of the variable name. Only the credentials are replaced — the scheme, host, and path are kept so the value stays useful for debugging:
postgresql://user:password@db.example.com:5432/mydb
→ postgresql://***@db.example.com:5432/mydb
This is enabled by default. To disable it globally:
posthog = Posthog(
"<ph_project_token>",
enable_exception_autocapture=True,
capture_exception_code_variables=True,
code_variables_mask_url_credentials=False,
)Or for a specific code block using contexts:
with new_context():
set_code_variables_mask_url_credentials_context(False)
masking_disabled_only_here()Variable names matching ignore patterns are not captured at all. This is useful for excluding internal variables, temporary data, or framework-specific variables that don't provide debugging value.
By default, Python internal variables (starting with __) are ignored.
posthog = Posthog(
"<ph_project_token>",
enable_exception_autocapture=True,
capture_exception_code_variables=True,
code_variables_ignore_patterns=[
r"^__.*", # Python internals
r"^_.*", # Private variables
r"temp_.*", # Temporary variables
r"cache_.*", # Cache variables
r"debug_.*", # Debug variables
],
)You can set ignore patterns for specific code blocks using contexts:
with new_context():
set_code_variables_ignore_patterns_context([r"cache_.*"])
ignore_patterns_will_only_apply_to_this_method()