azure_bootstrap
azure_bootstrap
¶
Azure Bootstrap Library
A production-ready Azure bootstrap library that handles application initialization for Azure Functions, including App Configuration, Key Vault, and App Insights integration.
This library solves the circular dependency between logging and configuration by: 1. Starting with basic console logging 2. Loading configuration from Azure App Configuration + Key Vault 3. Upgrading to App Insights telemetry when available 4. Loading all configs to os.environ for transparent access
Quick Start
from azure_bootstrap import initialize_application, get_bootstrap_logger
Get logger that works immediately¶
logger = get_bootstrap_logger(name)
Bootstrap the application (App Config + Key Vault + App Insights)¶
config_repo = initialize_application()
Now all configs are in os.environ¶
db_host = os.getenv("DATABASE_HOST")
For detailed usage, see: https://github.com/TheViziusGroup/azure-bootstrap
Modules:
| Name | Description |
|---|---|
aks |
AKS runtime helpers — graceful shutdown, build info, probes, pod context. |
alerts |
Tier 2 tiered-alert dispatcher. |
audit |
Audit log conventions. |
auth |
Webhook + API-key authentication helpers. |
bootstrap |
v1-compatible wrappers and helpers. |
config_refresh |
Dynamic log-level refresh via App Configuration. |
contrib |
Package-data templates for the scaffold CLI. |
counters |
Best-effort process-local counters. |
db |
Relational database access layer — SQLAlchemy 2 engine/session factory. |
documentdb |
MongoDB / Cosmos DB document database access. |
email |
Azure Communication Services email sender. |
exceptions |
Project-neutral exception hierarchy for pipelined applications. |
failclose |
Fail-closed-for-auth / fail-open-for-features env helpers. |
fastapi_middleware |
FastAPI request-timing + alerting middleware. |
governance |
Governance — budget guards and usage tracking. |
health |
Framework-neutral readiness probes for Azure App Configuration + App Insights. |
heartbeat |
Background heartbeat + worker-progress watchdog. |
http |
Hardened outbound HTTP client — sync requests stack. |
identity |
Workload Identity / DefaultAzureCredential wrapper. |
ingress |
Tier 2 attachment / file-upload hardening. |
logging |
Tier 1 logging primitives. |
metrics |
Aggregate library metrics for /api/metrics endpoints. |
models |
Custom exceptions for bootstrap operations. |
notify |
Sender-facing throttling + two-tier notification builders. |
openai |
SDK-agnostic Azure OpenAI / Anthropic usage tracker. |
path_safety |
Filename + path sanitization. |
pdf_safety |
PDF action stripping for untrusted pass-through. |
phases |
Per-phase guarded execution for multi-stage pipelines. |
ratelimit |
In-process token-bucket rate limiter. |
repositories |
Repository implementations for Azure bootstrap library. |
retry |
Tenacity-backed retry wrappers with built-in counter bumps and logging. |
sb_lock |
Service Bus message-lock management. |
scheduler |
NCRONTAB → APScheduler CronTrigger parser. |
security |
Constant-time comparison + FastAPI API-key helper. |
servicebus |
Tier 3 Service Bus helpers: consumer watchdog, DLQ growth alarm, daily digest. |
services |
Service implementations for Azure bootstrap library. |
softfail |
Helpers for the "log + alert + continue with degraded result" pattern. |
subscription |
Generic external-resource renewal loop pattern. |
tokens |
HMAC-SHA256 action-token signer (generalized DLQ-resubmit pattern). |
tracing |
Tier 1 tracing primitives: @traced decorator, latency histograms, slow thresholds. |
transports |
Logging transport registry — choose where logs go, toggle each independently. |
validation |
Lightweight JSON / queue-message schema validation. |
Classes:
| Name | Description |
|---|---|
AcsEmailSender |
Transactional email sender via Azure Communication Services. |
InvalidMessageError |
Queue payload failed schema validation. |
NetworkError |
Connection / timeout failure against an external service. |
PipelineError |
Base for any application-level pipeline failure. |
RateLimitError |
HTTP 429 or equivalent — caller should back off. |
TransientError |
Marker for known-recoverable failures. |
UnrecoverableError |
Marker: this failure will never succeed on retry. |
JsonLogFormatter |
Render a log record as a single line of JSON. |
ConfigurationError |
Exception raised when configuration loading or access fails. |
KeyVaultError |
Exception raised when Key Vault operations fail. |
RepositoryError |
Base exception for repository errors. |
EnhancedConfigRepository |
Enhanced configuration repository with hierarchical lookup. |
EnhancedConfigRepositoryInterface |
Abstract interface for enhanced configuration repository operations. |
SecretsRepositoryInterface |
Abstract interface for secrets repository operations. |
SecretsRepository |
Implementation of secrets repository for Azure Key Vault. |
ApplicationBootstrap |
Orchestrates the complete application startup sequence with proper logging flow. |
BootstrapLogger |
Bootstrap logging manager that provides safe logging before full configuration. |
ExtraFieldsFormatter |
Custom formatter that appends extra fields from log records to the message. |
ApplicationBootstrapInterface |
Interface for application bootstrap orchestrator. |
BootstrapLoggerInterface |
Interface for bootstrap logging manager. |
TelemetryManagerInterface |
Interface for telemetry manager. |
TelemetryManager |
Manages Application Insights telemetry and structured logging |
Functions:
| Name | Description |
|---|---|
build_info |
Return version/build metadata from downward-API or CI env vars. |
verify_chain |
Verify the integrity of an ordered list of :class: |
verify_hmac_signature |
Constant-time HMAC-SHA256 verify (GitHub/Sumo |
bootstrap_initialized |
Process-local state probe — useful for /api/health/ready endpoints. |
ensure_bootstrap |
Lazy idempotent wrapper around v1 |
load_local_settings |
Load env vars from an Azure-Functions-style |
bump_counter |
Thread-safe increment. Never raises. |
counter_snapshot |
Return a copy of the counter map. |
drain_outbox |
Claim and drain pending outbox rows. Returns count sent. |
is_unrecoverable |
The consumer's classifier — single |
build_session |
Return a |
request_with_retry |
Issue an HTTP request with default timeout, traceparent, and SSRF guard. |
build_tenant_credential |
Build a |
build_tenant_credential_cached |
Return an access token for tenant_id / scope, using the cache. |
configure_logging |
Install structured-logging defaults. Idempotent — replaces handlers. |
correlation_scope |
Push correlation context for the duration of the with-block. |
mask_secrets_in_dict |
Shallow copy with secret-keyed values replaced by '***'. |
sanitize_for_log |
Replace control chars (\x00-\x1f, \x7f) with '?' and truncate. |
confine_to_root |
Resolve |
sanitize_path_segment |
Normalize a single filename / path segment. |
run_phase |
Run |
run_phases |
Run a list of (name, callable) pairs in order, swallowing per-phase |
create_enhanced_config_repository |
Factory function to create an enhanced configuration repository. |
compare_secrets |
Constant-time equality. Returns False on any None / empty input. |
initialize_application |
Convenience function to perform complete application bootstrap. |
ensure_bootstrap_logging |
Ensure bootstrap logging is configured. |
get_bootstrap_logger |
Get a logger that works during bootstrap phase. |
soft_fail |
Context-manager form of :func: |
soft_fail_with |
Call |
traced |
Trace sync or async functions. |
configure_transports |
Enable/disable the ten built-in transports. Idempotent and re-runnable. |
disable_transport |
Detach (and close) the transport's handler. Idempotent. |
enable_transport |
Attach the transport's handler to the root logger. Idempotent. |
list_transports |
Return |
register_transport |
Register a transport factory under |
queue_message_schema |
Build a sensible MessageSchema for the common consumer case. |
validate_message |
Validate |
refresh_setting |
Re-read named settings from the cached App Configuration repo and |
AcsEmailSender
¶
Transactional email sender via Azure Communication Services.
Methods:
| Name | Description |
|---|---|
send |
Send an email; returns message id on success. |
Source code in azure_bootstrap/email/__init__.py
send
¶
Send an email; returns message id on success.
Source code in azure_bootstrap/email/__init__.py
InvalidMessageError
¶
Bases: UnrecoverableError
Queue payload failed schema validation.
NetworkError
¶
Bases: TransientError
Connection / timeout failure against an external service.
RateLimitError
¶
Bases: TransientError
HTTP 429 or equivalent — caller should back off.
TransientError
¶
Bases: PipelineError
Marker for known-recoverable failures.
Not in UnrecoverableError's tree, so consumers automatically retry.
UnrecoverableError
¶
Bases: PipelineError
Marker: this failure will never succeed on retry.
Consumers MUST dead-letter messages whose handlers raised any subclass
of UnrecoverableError. Anything else is transient (abandon → broker
redelivers).
JsonLogFormatter
¶
Bases: Formatter
Render a log record as a single line of JSON.
Emitted fields: timestamp (ISO-8601 UTC), level, logger,
message, exception (only when exc_info is present), plus every
non-reserved extra={} field (correlation IDs included, since
:class:CorrelationFilter attaches them as record attributes). Extra fields
are passed through :func:mask_secrets_in_dict so secret-keyed values are
redacted to ***.
Source code in azure_bootstrap/logging/jsonformatter.py
ConfigurationError
¶
Bases: RepositoryError
Exception raised when configuration loading or access fails.
This exception is raised when: - Azure App Configuration connection fails - Configuration values are missing or invalid - Configuration refresh operations fail - Configuration loading encounters critical errors
KeyVaultError
¶
Bases: RepositoryError
Exception raised when Key Vault operations fail.
This exception is raised when: - Key Vault connection or authentication fails - Secret retrieval operations fail - Key Vault access is denied or unavailable
EnhancedConfigRepository
¶
EnhancedConfigRepository(app_config_connection_string: str | None = None, secrets_repository: SecretsRepositoryInterface | None = None, auto_load_to_environ: bool = False)
Bases: EnhancedConfigRepositoryInterface
Enhanced configuration repository with hierarchical lookup.
This repository provides unified configuration access with automatic precedence: 1. Environment variables (highest priority) 2. Azure App Configuration with automatic Key Vault reference resolution 3. Key Vault secrets (via secrets repository, fallback only) 4. Default values (lowest priority)
Features: - Hierarchical configuration lookup - Azure App Configuration integration with built-in Key Vault resolution - Automatic Key Vault reference resolution when secrets are stored as references - Fallback to direct Key Vault access for non-referenced secrets - Automatic loading to os.environ - Configuration caching for performance - Comprehensive logging
Key Vault Integration: - When secrets are stored in App Config as Key Vault references (JSON format), they are automatically resolved by the Azure SDK - Reference format: {"uri": "https://vault.vault.azure.net/secrets/secretname"} - Requires Managed Identity with "App Configuration Data Reader" and "Key Vault Secrets User" RBAC roles
Usage
With App Config (Key Vault references auto-resolved)¶
config_repo = EnhancedConfigRepository( app_config_connection_string="...", auto_load_to_environ=True )
Without App Config (environment only)¶
config_repo = EnhancedConfigRepository() db_host = config_repo.get_value("DATABASE_HOST", "localhost")
Initialize the enhanced configuration repository.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
app_config_connection_string
|
str | None
|
Azure App Configuration connection string |
None
|
secrets_repository
|
SecretsRepositoryInterface | None
|
Optional secrets repository for direct Key Vault fallback |
None
|
auto_load_to_environ
|
bool
|
If True, automatically load configs to os.environ on init |
False
|
Methods:
| Name | Description |
|---|---|
get_value |
Get a configuration value with hierarchical lookup. |
get_secret_value |
Get a secret value from Key Vault. |
get_all_values |
Get all configuration values from all sources. |
load_to_environ |
Load configuration values to os.environ. |
refresh |
Refresh configuration from all sources. |
get_repository_metrics |
Get metrics about the configuration repository. |
clear_cache |
Clear the configuration cache. |
is_available |
Check if the configuration repository is available. |
is_app_config_available |
Check if Azure App Configuration is available and accessible. |
is_key_vault_available |
Check if Azure Key Vault is available and accessible. |
Source code in azure_bootstrap/repositories/enhanced_config_repository.py
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 | |
get_value
¶
Get a configuration value with hierarchical lookup.
Lookup order: 1. Environment variables (highest priority) 2. Cache (if previously retrieved) 3. Azure App Configuration with automatic Key Vault reference resolution 4. Key Vault secrets (via secrets repository, fallback) 5. Default value (lowest priority)
Note: If a value is stored in App Config as a Key Vault reference, it will be automatically resolved by the provider.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
key
|
str
|
Configuration key name |
required |
default
|
str | None
|
Default value if key not found |
None
|
Returns:
| Type | Description |
|---|---|
str | None
|
Optional[str]: Configuration value or default |
Source code in azure_bootstrap/repositories/enhanced_config_repository.py
get_secret_value
¶
Get a secret value from Key Vault.
This method specifically targets secrets and bypasses the standard configuration hierarchy to directly access Key Vault.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
key
|
str
|
Secret key name |
required |
default
|
str | None
|
Default value if secret not found |
None
|
Returns:
| Type | Description |
|---|---|
str | None
|
Optional[str]: Secret value or default |
Source code in azure_bootstrap/repositories/enhanced_config_repository.py
get_all_values
¶
Get all configuration values from all sources.
Returns:
| Type | Description |
|---|---|
dict[str, str]
|
Dict[str, str]: All configuration key-value pairs with Key Vault references resolved |
Source code in azure_bootstrap/repositories/enhanced_config_repository.py
load_to_environ
¶
load_to_environ() -> int
Load configuration values to os.environ.
Precedence Logic: 1. Values already in os.environ are PRESERVED (local.settings.json wins) 2. Missing values are added from App Configuration (fill gaps) 3. This allows local development overrides while providing defaults
Example
local.settings.json sets:¶
os.environ["USE_MOCK_SHAREPOINT"] = "true"
App Config has:¶
config["USE_MOCK_SHAREPOINT"] = "false" config["NEW_CONFIG"] = "value"
After load_to_environ():¶
os.environ["USE_MOCK_SHAREPOINT"] = "true" # ✅ Local preserved os.environ["NEW_CONFIG"] = "value" # ✅ Remote added
Returns:
| Name | Type | Description |
|---|---|---|
int |
int
|
Number of NEW values added to os.environ (excludes skipped) |
Source code in azure_bootstrap/repositories/enhanced_config_repository.py
294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 | |
refresh
¶
Refresh configuration from all sources.
This method clears the cache and reloads configuration from App Configuration (with Key Vault references resolved) to pick up any changes.
Source code in azure_bootstrap/repositories/enhanced_config_repository.py
get_repository_metrics
¶
Get metrics about the configuration repository.
Returns:
| Type | Description |
|---|---|
dict[str, Any]
|
Dict[str, Any]: Metrics including source counts, cache hits, etc. |
Source code in azure_bootstrap/repositories/enhanced_config_repository.py
clear_cache
¶
Clear the configuration cache.
This method clears all cached configuration values, forcing the next get_value call to retrieve fresh data from sources.
Source code in azure_bootstrap/repositories/enhanced_config_repository.py
is_available
¶
is_available() -> bool
Check if the configuration repository is available.
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
True if at least one configuration source is available |
Source code in azure_bootstrap/repositories/enhanced_config_repository.py
is_app_config_available
¶
is_app_config_available() -> bool
Check if Azure App Configuration is available and accessible.
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
True if App Config is accessible, False otherwise |
Source code in azure_bootstrap/repositories/enhanced_config_repository.py
EnhancedConfigRepositoryInterface
¶
Bases: ABC
Abstract interface for enhanced configuration repository operations.
This interface defines all configuration access operations for integration with Azure App Configuration, Key Vault, and environment variables following a hierarchical precedence model.
Configuration Precedence (highest to lowest): 1. Environment variables (os.environ) 2. Azure App Configuration 3. Key Vault secrets (via secrets repository) 4. Default values
Benefits: - Abstracts configuration storage implementation details - Enables dependency injection and testing with mocks - Provides clear contract for configuration access - Supports multiple backends with transparent fallback
Methods:
| Name | Description |
|---|---|
get_value |
Get a configuration value with hierarchical lookup. |
get_secret_value |
Get a secret value from Key Vault. |
get_all_values |
Get all configuration values from all sources. |
load_to_environ |
Load all configuration values into os.environ. |
refresh |
Refresh configuration from all sources. |
get_repository_metrics |
Get metrics about the configuration repository. |
is_app_config_available |
Check if Azure App Configuration is available and accessible. |
is_key_vault_available |
Check if Azure Key Vault is available and accessible. |
get_value
abstractmethod
¶
Get a configuration value with hierarchical lookup.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
key
|
str
|
Configuration key name |
required |
default
|
str | None
|
Default value if key not found |
None
|
Returns:
| Type | Description |
|---|---|
str | None
|
Optional[str]: Configuration value or default |
Raises:
| Type | Description |
|---|---|
ConfigurationError
|
If configuration access fails |
Source code in azure_bootstrap/repositories/interfaces/enhanced_config_repository_interface.py
get_secret_value
abstractmethod
¶
Get a secret value from Key Vault.
This method specifically targets secrets and bypasses the standard configuration hierarchy to directly access Key Vault.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
key
|
str
|
Secret key name |
required |
default
|
str | None
|
Default value if secret not found |
None
|
Returns:
| Type | Description |
|---|---|
str | None
|
Optional[str]: Secret value or default |
Raises:
| Type | Description |
|---|---|
SecretAccessError
|
If secret retrieval fails |
Source code in azure_bootstrap/repositories/interfaces/enhanced_config_repository_interface.py
get_all_values
abstractmethod
¶
Get all configuration values from all sources.
Returns:
| Type | Description |
|---|---|
dict[str, str]
|
Dict[str, str]: All configuration key-value pairs |
Raises:
| Type | Description |
|---|---|
ConfigurationError
|
If configuration access fails |
Source code in azure_bootstrap/repositories/interfaces/enhanced_config_repository_interface.py
load_to_environ
abstractmethod
¶
load_to_environ() -> int
Load all configuration values into os.environ.
This method loads all configuration from App Config and Key Vault into environment variables for transparent application access.
Returns:
| Name | Type | Description |
|---|---|---|
int |
int
|
Number of new values added to os.environ (excludes skipped values) |
Raises:
| Type | Description |
|---|---|
ConfigurationError
|
If loading fails |
Source code in azure_bootstrap/repositories/interfaces/enhanced_config_repository_interface.py
refresh
abstractmethod
¶
Refresh configuration from all sources.
This method reloads configuration from App Configuration and Key Vault to pick up any changes.
Raises:
| Type | Description |
|---|---|
ConfigurationError
|
If refresh fails |
Source code in azure_bootstrap/repositories/interfaces/enhanced_config_repository_interface.py
get_repository_metrics
abstractmethod
¶
is_app_config_available
abstractmethod
¶
is_app_config_available() -> bool
Check if Azure App Configuration is available and accessible.
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
True if App Config is accessible, False otherwise |
Source code in azure_bootstrap/repositories/interfaces/enhanced_config_repository_interface.py
is_key_vault_available
abstractmethod
¶
is_key_vault_available() -> bool
Check if Azure Key Vault is available and accessible.
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
True if Key Vault is accessible, False otherwise |
Source code in azure_bootstrap/repositories/interfaces/enhanced_config_repository_interface.py
SecretsRepositoryInterface
¶
Bases: ABC
Abstract interface for secrets repository operations.
This interface defines all secret access operations for integration with Azure Key Vault or other secret storage backends.
Benefits: - Abstracts secret storage implementation details from business logic - Enables dependency injection and testing with mocks - Provides clear contract for secret access operations - Supports multiple backends (Key Vault, local files, environment, etc.)
Methods:
| Name | Description |
|---|---|
get_secret |
Retrieve a secret value by name. |
set_secret |
Store a secret value (if backend supports writes). |
delete_secret |
Delete a secret (if backend supports deletion). |
list_secrets |
List all available secrets (names only for security). |
is_available |
Check if secrets repository is available and accessible. |
get_secret
abstractmethod
¶
Retrieve a secret value by name.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
secret_name
|
str
|
Name of the secret to retrieve |
required |
Returns:
| Type | Description |
|---|---|
str | None
|
Optional[str]: Secret value if found, None otherwise |
Raises:
| Type | Description |
|---|---|
SecretAccessError
|
If secret retrieval fails |
Source code in azure_bootstrap/repositories/interfaces/secrets_repository_interface.py
set_secret
abstractmethod
¶
Store a secret value (if backend supports writes).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
secret_name
|
str
|
Name of the secret |
required |
secret_value
|
str
|
Value to store |
required |
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
True if successful, False otherwise |
Raises:
| Type | Description |
|---|---|
SecretAccessError
|
If secret storage fails |
NotImplementedError
|
If backend doesn't support writes |
Source code in azure_bootstrap/repositories/interfaces/secrets_repository_interface.py
delete_secret
abstractmethod
¶
Delete a secret (if backend supports deletion).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
secret_name
|
str
|
Name of the secret to delete |
required |
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
True if successful, False otherwise |
Raises:
| Type | Description |
|---|---|
SecretAccessError
|
If secret deletion fails |
NotImplementedError
|
If backend doesn't support deletion |
Source code in azure_bootstrap/repositories/interfaces/secrets_repository_interface.py
list_secrets
abstractmethod
¶
List all available secrets (names only for security).
Returns:
| Type | Description |
|---|---|
dict[str, str]
|
Dict[str, str]: Dictionary mapping secret names to metadata |
Raises:
| Type | Description |
|---|---|
SecretAccessError
|
If listing fails |
Source code in azure_bootstrap/repositories/interfaces/secrets_repository_interface.py
SecretsRepository
¶
SecretsRepository(vault_url: str | None = None)
Bases: SecretsRepositoryInterface
Implementation of secrets repository for Azure Key Vault.
This repository provides access to secrets from Azure Key Vault with graceful fallback to environment variables when Key Vault is not available.
Features: - Azure Key Vault integration (when available) - Environment variable fallback for local development - Caching for performance - Comprehensive logging and error handling
Usage
With Key Vault¶
secrets_repo = SecretsRepository(vault_url="https://myvault.vault.azure.net/") db_password = secrets_repo.get_secret("database-password")
Without Key Vault (environment variables only)¶
secrets_repo = SecretsRepository() db_password = secrets_repo.get_secret("DATABASE_PASSWORD")
Initialize the secrets repository.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
vault_url
|
str | None
|
Optional Azure Key Vault URL (e.g., "https://myvault.vault.azure.net/") If not provided, uses AZURE_KEY_VAULT_URL from environment |
None
|
Methods:
| Name | Description |
|---|---|
get_secret |
Retrieve a secret value by name. |
set_secret |
Store a secret value (Key Vault only, not environment). |
delete_secret |
Delete a secret from Key Vault. |
list_secrets |
List all available secrets (names only for security). |
is_available |
Check if secrets repository is available and accessible. |
clear_cache |
Clear the secrets cache. |
Source code in azure_bootstrap/repositories/secrets_repository.py
get_secret
¶
Retrieve a secret value by name.
Lookup order: 1. Cache (if previously retrieved) 2. Azure Key Vault (if available) 3. Environment variables (fallback)
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
secret_name
|
str
|
Name of the secret to retrieve |
required |
Returns:
| Type | Description |
|---|---|
str | None
|
Optional[str]: Secret value if found, None otherwise |
Source code in azure_bootstrap/repositories/secrets_repository.py
set_secret
¶
Store a secret value (Key Vault only, not environment).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
secret_name
|
str
|
Name of the secret |
required |
secret_value
|
str
|
Value to store |
required |
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
True if successful, False otherwise |
Source code in azure_bootstrap/repositories/secrets_repository.py
delete_secret
¶
Delete a secret from Key Vault.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
secret_name
|
str
|
Name of the secret to delete |
required |
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
True if successful, False otherwise |
Source code in azure_bootstrap/repositories/secrets_repository.py
list_secrets
¶
List all available secrets (names only for security).
Returns:
| Type | Description |
|---|---|
dict[str, str]
|
Dict[str, str]: Dictionary mapping secret names to metadata (not values) |
Source code in azure_bootstrap/repositories/secrets_repository.py
ApplicationBootstrap
¶
ApplicationBootstrap(secrets_repository: SecretsRepositoryInterface | None = None)
Bases: ApplicationBootstrapInterface
Orchestrates the complete application startup sequence with proper logging flow.
This class handles the complex bootstrap process that requires careful ordering to avoid circular dependencies between logging, configuration, and secrets.
Bootstrap Flow
- Initialize console logging (safe fallback that always works)
- Try App Insights from environment variables if available
- Create and load enhanced configuration from App Config/Key Vault
- Attempt to upgrade logging to App Insights if connection string is now available
- Load all configuration to os.environ for transparent application access
- Log completion and provide access to configured components
Key Features
- Eliminates circular dependencies between logging and configuration
- Provides working logging throughout the entire bootstrap process
- Graceful fallbacks at every step ensure robustness
- Comprehensive logging of bootstrap progress and decisions
- Transparent configuration access via os.environ after completion
Usage Example
Simple bootstrap¶
bootstrap = ApplicationBootstrap() config_repo = bootstrap.initialize()
Bootstrap with secrets repository¶
bootstrap = ApplicationBootstrap(secrets_repository=my_secrets_repo) config_repo = bootstrap.initialize()
After bootstrap, all configs are in os.environ¶
app_insights_key = os.environ.get("APPLICATIONINSIGHTS_CONNECTION_STRING") database_host = os.getenv("DATABASE_HOST")
Initialize the application bootstrap orchestrator.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
secrets_repository
|
SecretsRepositoryInterface | None
|
Optional secrets repository for Key Vault integration |
None
|
Methods:
| Name | Description |
|---|---|
initialize |
Execute the complete bootstrap sequence with proper logging flow. |
get_config_repository |
Get the configured repository after bootstrap. |
is_bootstrap_completed |
Check if bootstrap process has completed successfully. |
Source code in azure_bootstrap/services/application_bootstrap.py
initialize
¶
initialize() -> EnhancedConfigRepositoryInterface
Execute the complete bootstrap sequence with proper logging flow.
This method orchestrates the entire application startup process following the correct sequence to avoid circular dependencies while ensuring working logging throughout.
Returns:
| Type | Description |
|---|---|
EnhancedConfigRepositoryInterface
|
Configured enhanced configuration repository with all configs loaded |
Raises:
| Type | Description |
|---|---|
RuntimeError
|
If bootstrap fails in an unrecoverable way |
Source code in azure_bootstrap/services/application_bootstrap.py
get_config_repository
¶
get_config_repository() -> EnhancedConfigRepositoryInterface | None
Get the configured repository after bootstrap.
Returns:
| Type | Description |
|---|---|
EnhancedConfigRepositoryInterface | None
|
The enhanced configuration repository if bootstrap is complete, None otherwise |
Source code in azure_bootstrap/services/application_bootstrap.py
BootstrapLogger
¶
Bases: BootstrapLoggerInterface
Bootstrap logging manager that provides safe logging before full configuration.
This class handles the chicken-and-egg problem where: 1. Configuration loading needs logging 2. Logging (App Insights) needs configuration
Solution: Start with basic logging, then upgrade to full telemetry later.
Methods:
| Name | Description |
|---|---|
configure_bootstrap_logging |
Configure basic logging that works before full configuration is loaded. |
is_bootstrap_configured |
Check if bootstrap logging is configured. |
create_logger |
Create a logger with bootstrap configuration if not already done. |
configure_bootstrap_logging
classmethod
¶
configure_bootstrap_logging(level: str | None = None) -> None
Configure basic logging that works before full configuration is loaded.
This provides immediate, safe logging during application bootstrap. Later, telemetry_manager.configure() will enhance it with App Insights.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
level
|
str | None
|
Logging level (DEBUG, INFO, WARNING, ERROR). If not provided, reads from LOG_LEVEL environment variable, defaulting to INFO. |
None
|
Source code in azure_bootstrap/services/bootstrap_logging.py
create_logger
classmethod
¶
Create a logger with bootstrap configuration if not already done.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
Logger name (typically name) |
required |
Returns:
| Type | Description |
|---|---|
Logger
|
Configured logger ready for use |
Source code in azure_bootstrap/services/bootstrap_logging.py
ExtraFieldsFormatter
¶
Bases: Formatter
Custom formatter that appends extra fields from log records to the message.
This ensures that any extra={...} dict passed to logger calls is included in the output, making structured logging data visible in console output.
ApplicationBootstrapInterface
¶
Bases: ABC
Interface for application bootstrap orchestrator.
Defines the contract for handling the complete application startup sequence with proper logging flow.
Methods:
| Name | Description |
|---|---|
initialize |
Execute the complete bootstrap sequence with proper logging flow. |
get_config_repository |
Get the configured repository after bootstrap. |
is_bootstrap_completed |
Check if bootstrap process has completed successfully. |
initialize
abstractmethod
¶
Execute the complete bootstrap sequence with proper logging flow.
This method orchestrates the entire application startup process following the correct sequence to avoid circular dependencies while ensuring working logging throughout.
Returns:
| Type | Description |
|---|---|
EnhancedConfigRepositoryInterface
|
Configured enhanced configuration repository with all configs loaded |
Raises:
| Type | Description |
|---|---|
RuntimeError
|
If bootstrap fails in an unrecoverable way |
Source code in azure_bootstrap/services/interfaces/application_bootstrap_interface.py
get_config_repository
abstractmethod
¶
get_config_repository() -> Optional[EnhancedConfigRepositoryInterface]
Get the configured repository after bootstrap.
Returns:
| Type | Description |
|---|---|
Optional[EnhancedConfigRepositoryInterface]
|
The enhanced configuration repository if bootstrap is complete, None otherwise |
Source code in azure_bootstrap/services/interfaces/application_bootstrap_interface.py
is_bootstrap_completed
abstractmethod
¶
is_bootstrap_completed() -> bool
Check if bootstrap process has completed successfully.
Returns:
| Type | Description |
|---|---|
bool
|
True if bootstrap completed successfully, False otherwise |
Source code in azure_bootstrap/services/interfaces/application_bootstrap_interface.py
BootstrapLoggerInterface
¶
Bases: ABC
Interface for bootstrap logging manager.
Defines the contract for providing safe logging before full configuration is loaded and App Insights is configured.
Methods:
| Name | Description |
|---|---|
configure_bootstrap_logging |
Configure basic logging that works before full configuration is loaded. |
is_bootstrap_configured |
Check if bootstrap logging is configured. |
create_logger |
Create a logger with bootstrap configuration if not already done. |
configure_bootstrap_logging
abstractmethod
classmethod
¶
configure_bootstrap_logging(level: str = 'INFO') -> None
Configure basic logging that works before full configuration is loaded.
This provides immediate, safe logging during application bootstrap. Later, telemetry_manager.configure() will enhance it with App Insights.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
level
|
str
|
Logging level (DEBUG, INFO, WARNING, ERROR) |
'INFO'
|
Source code in azure_bootstrap/services/interfaces/bootstrap_logger_interface.py
is_bootstrap_configured
abstractmethod
classmethod
¶
is_bootstrap_configured() -> bool
Check if bootstrap logging is configured.
Returns:
| Type | Description |
|---|---|
bool
|
True if bootstrap logging is configured, False otherwise |
Source code in azure_bootstrap/services/interfaces/bootstrap_logger_interface.py
create_logger
abstractmethod
classmethod
¶
Create a logger with bootstrap configuration if not already done.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
Logger name (typically name) |
required |
Returns:
| Type | Description |
|---|---|
Logger
|
Configured logger ready for use |
Source code in azure_bootstrap/services/interfaces/bootstrap_logger_interface.py
TelemetryManagerInterface
¶
Bases: ABC
Interface for telemetry manager.
Defines the contract for managing Application Insights telemetry and structured logging throughout the application.
Methods:
| Name | Description |
|---|---|
configure |
Configure Application Insights telemetry with support for bootstrap flow reconfiguration. |
try_upgrade_from_config |
Attempt to upgrade from basic logging to App Insights after config is loaded. |
get_tracer |
Get the configured tracer. |
create_span |
Create a new trace span. |
log_email_processing_start |
Log email processing start with structured data. |
log_email_processing_success |
Log successful email processing. |
log_email_processing_error |
Log email processing error. |
log_queue_message_received |
Log queue message processing. |
log_storage_operation |
Log storage operations. |
configure
abstractmethod
¶
Configure Application Insights telemetry with support for bootstrap flow reconfiguration.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
connection_string
|
str | None
|
App Insights connection string |
None
|
allow_reconfigure
|
bool
|
If True, allows reconfiguration even if already configured |
False
|
Returns:
| Type | Description |
|---|---|
bool
|
True if configuration succeeded, False otherwise |
Source code in azure_bootstrap/services/interfaces/telemetry_manager_interface.py
try_upgrade_from_config
abstractmethod
¶
try_upgrade_from_config(config_repository: EnhancedConfigRepositoryInterface) -> bool
Attempt to upgrade from basic logging to App Insights after config is loaded.
This method is called after configuration loading to check if an App Insights connection string is now available from App Config/Key Vault that wasn't available during initial bootstrap.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
config_repository
|
EnhancedConfigRepositoryInterface
|
Enhanced config repository to check for connection string |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True if upgrade was attempted (success or failure), False if no upgrade needed |
Source code in azure_bootstrap/services/interfaces/telemetry_manager_interface.py
get_tracer
abstractmethod
¶
get_tracer() -> Any
Get the configured tracer.
Returns:
| Type | Description |
|---|---|
Any
|
The OpenTelemetry tracer instance if configured, None otherwise |
create_span
abstractmethod
¶
Create a new trace span.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
Name of the span |
required |
attributes
|
dict[str, Any] | None
|
Optional attributes to attach to the span |
None
|
Returns:
| Type | Description |
|---|---|
Any
|
Span instance if telemetry is configured, None otherwise |
Source code in azure_bootstrap/services/interfaces/telemetry_manager_interface.py
log_email_processing_start
abstractmethod
¶
log_email_processing_success
abstractmethod
¶
Log successful email processing.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
message_id
|
str
|
Email message ID |
required |
user_email
|
str
|
User email address |
required |
processing_time_ms
|
int
|
Processing time in milliseconds |
required |
Source code in azure_bootstrap/services/interfaces/telemetry_manager_interface.py
log_email_processing_error
abstractmethod
¶
log_email_processing_error(error: str, message_id: str | None = None, user_email: str | None = None) -> None
Log email processing error.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
error
|
str
|
Error message |
required |
message_id
|
str | None
|
Email message ID (if available) |
None
|
user_email
|
str | None
|
User email address (if available) |
None
|
Source code in azure_bootstrap/services/interfaces/telemetry_manager_interface.py
log_queue_message_received
abstractmethod
¶
log_storage_operation
abstractmethod
¶
Log storage operations.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
operation
|
str
|
Type of storage operation |
required |
container
|
str
|
Storage container name |
required |
blob_name
|
str
|
Blob name |
required |
success
|
bool
|
Whether the operation succeeded |
required |
Source code in azure_bootstrap/services/interfaces/telemetry_manager_interface.py
TelemetryManager
¶
Bases: TelemetryManagerInterface
Manages Application Insights telemetry and structured logging
Methods:
| Name | Description |
|---|---|
configure |
Configure Application Insights telemetry with support for bootstrap flow reconfiguration |
try_upgrade_from_config |
Attempt to upgrade from basic logging to App Insights after config is loaded |
get_tracer |
Get the configured tracer |
create_span |
Create a new trace span |
log_email_processing_start |
Log email processing start with structured data |
log_email_processing_success |
Log successful email processing |
log_email_processing_error |
Log email processing error |
log_queue_message_received |
Log queue message processing |
log_storage_operation |
Log storage operations |
Source code in azure_bootstrap/services/telemetry.py
configure
¶
Configure Application Insights telemetry with support for bootstrap flow reconfiguration
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
connection_string
|
str | None
|
App Insights connection string |
None
|
allow_reconfigure
|
bool
|
If True, allows reconfiguration even if already configured |
False
|
Source code in azure_bootstrap/services/telemetry.py
try_upgrade_from_config
¶
try_upgrade_from_config(config_repository: EnhancedConfigRepositoryInterface) -> bool
Attempt to upgrade from basic logging to App Insights after config is loaded
This method is called after configuration loading to check if an App Insights connection string is now available from App Config/Key Vault that wasn't available during initial bootstrap.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
config_repository
|
EnhancedConfigRepositoryInterface
|
Enhanced config repository to check for connection string |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True if upgrade was attempted (success or failure), False if no upgrade needed |
Source code in azure_bootstrap/services/telemetry.py
create_span
¶
Create a new trace span
Source code in azure_bootstrap/services/telemetry.py
log_email_processing_start
¶
Log email processing start with structured data
Source code in azure_bootstrap/services/telemetry.py
log_email_processing_success
¶
Log successful email processing
Source code in azure_bootstrap/services/telemetry.py
log_email_processing_error
¶
log_email_processing_error(error: str, message_id: str | None = None, user_email: str | None = None) -> None
Log email processing error
Source code in azure_bootstrap/services/telemetry.py
log_queue_message_received
¶
Log queue message processing
Source code in azure_bootstrap/services/telemetry.py
log_storage_operation
¶
Log storage operations
Source code in azure_bootstrap/services/telemetry.py
build_info
¶
Return version/build metadata from downward-API or CI env vars.
Source code in azure_bootstrap/aks/__init__.py
verify_chain
¶
verify_chain(records: list[ChainedAuditRecord]) -> bool
Verify the integrity of an ordered list of :class:ChainedAuditRecord objects.
For each record the function recomputes the expected record_hash from
the record's fields and confirms it matches the stored record_hash. It
also verifies that each record's prev_hash equals the preceding record's
record_hash (or None for the first record).
Returns True if the chain is intact, False on the first detected
anomaly (and logs a warning with tamper-evidence details).
Parameters¶
records:
Ordered list of records as originally produced by
:meth:AuditChain.append_chained.
Source code in azure_bootstrap/audit/__init__.py
verify_hmac_signature
¶
verify_hmac_signature(secret: str, raw_body: bytes, header_value: str, *, prefix: str = 'sha256=') -> bool
Constant-time HMAC-SHA256 verify (GitHub/Sumo sha256=… style).
Parameters¶
secret:
Shared signing secret.
raw_body:
Raw request body bytes (must not be re-serialized JSON).
header_value:
Value of the signature header (may include sha256= prefix).
prefix:
Expected algorithm prefix in the header value.
Source code in azure_bootstrap/auth/hmac.py
ensure_bootstrap
¶
Lazy idempotent wrapper around v1 initialize_application.
Short-circuits when USE_MOCK_BOOTSTRAP is truthy (sets the
initialized flag and returns without contacting Azure). On real
bootstrap, calls v1 initialize_application() and sets the flag.
Re-raises on failure after logging at ERROR with traceback.
Source code in azure_bootstrap/bootstrap/__init__.py
load_local_settings
¶
Load env vars from an Azure-Functions-style local.settings.json.
Behavior:
- Missing file: silent, returns 0.
- Keys starting with _ are documentation sentinels; skipped.
- Never overrides an existing os.environ entry.
- JSON / OS errors are logged at WARNING and return 0.
Source code in azure_bootstrap/bootstrap/__init__.py
bump_counter
¶
Thread-safe increment. Never raises.
Source code in azure_bootstrap/counters/__init__.py
counter_snapshot
¶
drain_outbox
¶
drain_outbox(session: Any, sender_fn: Callable[[dict[str, Any]], None], *, batch_size: int = 10, max_attempts: int = 5, table: str = 'outbox') -> int
Claim and drain pending outbox rows. Returns count sent.
Source code in azure_bootstrap/db/outbox.py
is_unrecoverable
¶
is_unrecoverable(exc: BaseException) -> bool
build_session
¶
build_session(*, total_retries: int = 5, backoff_factor: float = 1.0, pool_connections: int = 10, pool_maxsize: int = 10) -> Any
Return a requests.Session with urllib3 Retry mounted.
Source code in azure_bootstrap/http/__init__.py
request_with_retry
¶
request_with_retry(method: str, url: str, *, session: Any | None = None, timeout: float = _DEFAULT_TIMEOUT, headers: dict[str, str] | None = None, allow_private: bool = False, **kwargs: Any) -> Any
Issue an HTTP request with default timeout, traceparent, and SSRF guard.
Source code in azure_bootstrap/http/__init__.py
build_tenant_credential
¶
build_tenant_credential(tenant_id: str, *, app_client_id: str | None = None, token_file_path: str = _DEFAULT_TOKEN_FILE) -> Any
Build a WorkloadIdentityCredential scoped to tenant_id.
Zero-secret — uses the federated token file on disk. Designed for multi-tenant Entra applications that need to acquire per-customer-tenant Graph (or ARM) tokens from a single registered app.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
tenant_id
|
str
|
The target customer / resource tenant. |
required |
app_client_id
|
str | None
|
The multi-tenant app's client ID. Falls back to
|
None
|
token_file_path
|
str
|
Path to the federated token file written by the Azure Workload Identity webhook. Defaults to the standard AKS path. |
_DEFAULT_TOKEN_FILE
|
Returns:
| Type | Description |
|---|---|
Any
|
A |
Raises:
| Type | Description |
|---|---|
ValueError
|
If no client ID can be resolved. |
ImportError
|
If |
Source code in azure_bootstrap/identity/__init__.py
build_tenant_credential_cached
¶
build_tenant_credential_cached(tenant_id: str, scope: str, *, app_client_id: str | None = None) -> str
Return an access token for tenant_id / scope, using the cache.
On a cache hit the cached token string is returned immediately.
On a miss a fresh WorkloadIdentityCredential is built via
:func:build_tenant_credential, get_token(scope) is called, and
the result is stored in the cache before being returned.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
tenant_id
|
str
|
The target customer / resource tenant. |
required |
scope
|
str
|
The OAuth2 scope to request (e.g.
|
required |
app_client_id
|
str | None
|
Passed through to :func: |
None
|
Returns:
| Type | Description |
|---|---|
str
|
The raw token string ( |
Raises:
| Type | Description |
|---|---|
ValueError
|
If no client ID can be resolved. |
ImportError
|
If |
Source code in azure_bootstrap/identity/__init__.py
configure_logging
¶
configure_logging(*, format_string: str = '%(asctime)s %(levelname)s %(name)s %(message)s', silence_defaults: bool = True, extra_noisy_loggers: tuple[str, ...] = ()) -> None
Install structured-logging defaults. Idempotent — replaces handlers.
Source code in azure_bootstrap/logging/config.py
correlation_scope
¶
correlation_scope(correlation_id: str | None = None, **fields: str | None) -> Generator[str, None, None]
Push correlation context for the duration of the with-block.
Yields the resolved correlation_id, always a non-empty string. A fresh
12-char uuid hex is minted when correlation_id is None. Any keyword
argument becomes a context var (e.g. email_id, request_id).
Source code in azure_bootstrap/logging/correlation.py
mask_secrets_in_dict
¶
Shallow copy with secret-keyed values replaced by '***'.
A value is replaced only when truthy — empty strings, None, 0, etc. pass through unmodified so the caller can still see "field was empty".
Source code in azure_bootstrap/logging/masking.py
sanitize_for_log
¶
Replace control chars (\x00-\x1f, \x7f) with '?' and truncate.
Source code in azure_bootstrap/logging/masking.py
confine_to_root
¶
Resolve raw and assert it's under allowed_root.
Both inputs are canonicalized via Path.expanduser().resolve() before
comparison — protects against symlink escape and .. traversal.
Source code in azure_bootstrap/path_safety/__init__.py
sanitize_path_segment
¶
Normalize a single filename / path segment.
Order matters: bidi/zero-width chars are stripped BEFORE any other normalization so a visual-spoofing attack can't hide other transformations.
Source code in azure_bootstrap/path_safety/__init__.py
run_phase
¶
run_phase(name: str, fn: Callable[..., T], *args: Any, namespace: str = 'phase', alert_severity: str | None = 'error', aggregate_counter: str | None = None, **kwargs: Any) -> PhaseResult[T]
Run fn under a try/except. NEVER re-raises.
Counters bumped (best-effort):
- {namespace}.{name}.ok on success
- {namespace}.{name}.failed on exception
- {namespace}.{name}.{aggregate_counter} += len(result) when
aggregate_counter is given AND the result supports len.
Source code in azure_bootstrap/phases/__init__.py
run_phases
¶
run_phases(phases: list[tuple[str, Callable[..., Any]]], *, namespace: str = 'phase', alert_severity: str | None = 'error') -> list[PhaseResult[Any]]
Run a list of (name, callable) pairs in order, swallowing per-phase failures so subsequent phases still execute.
Source code in azure_bootstrap/phases/__init__.py
create_enhanced_config_repository
¶
create_enhanced_config_repository(app_config_connection_string: str | None = None, secrets_repository: SecretsRepositoryInterface | None = None, auto_load_to_environ: bool = False) -> EnhancedConfigRepositoryInterface
Factory function to create an enhanced configuration repository.
This factory function provides a convenient way to create a properly configured EnhancedConfigRepository instance.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
app_config_connection_string
|
str | None
|
Azure App Configuration connection string |
None
|
secrets_repository
|
SecretsRepositoryInterface | None
|
Optional secrets repository for Key Vault integration |
None
|
auto_load_to_environ
|
bool
|
If True, automatically load configs to os.environ on init |
False
|
Returns:
| Name | Type | Description |
|---|---|---|
EnhancedConfigRepositoryInterface |
EnhancedConfigRepositoryInterface
|
Configured repository instance |
Usage
Simple usage with environment variables only¶
config_repo = create_enhanced_config_repository()
With App Config¶
config_repo = create_enhanced_config_repository( app_config_connection_string="Endpoint=...", auto_load_to_environ=True )
With App Config and Key Vault¶
secrets_repo = SecretsRepository(vault_url="...") config_repo = create_enhanced_config_repository( app_config_connection_string="Endpoint=...", secrets_repository=secrets_repo, auto_load_to_environ=True )
Source code in azure_bootstrap/repositories/enhanced_config_repository.py
compare_secrets
¶
Constant-time equality. Returns False on any None / empty input.
Coerces str to bytes via UTF-8. Bytes inputs pass through unchanged.
Source code in azure_bootstrap/security/__init__.py
initialize_application
¶
initialize_application(secrets_repository: SecretsRepositoryInterface | None = None) -> EnhancedConfigRepositoryInterface
Convenience function to perform complete application bootstrap.
This is the main entry point for application initialization. It handles the complete bootstrap sequence and returns the configured repository.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
secrets_repository
|
SecretsRepositoryInterface | None
|
Optional secrets repository for Key Vault integration |
None
|
Returns:
| Type | Description |
|---|---|
EnhancedConfigRepositoryInterface
|
Configured enhanced configuration repository with all configs loaded |
Example
Simple initialization¶
config_repo = initialize_application()
With secrets repository¶
from src.repositories.secrets_repository import create_secrets_repository secrets_repo = create_secrets_repository() config_repo = initialize_application(secrets_repository=secrets_repo)
After initialization, use standard os.environ access¶
app_insights_key = os.environ.get("APPLICATIONINSIGHTS_CONNECTION_STRING")
Source code in azure_bootstrap/services/application_bootstrap.py
ensure_bootstrap_logging
¶
Ensure bootstrap logging is configured.
This is a convenience function that can be called safely multiple times. Call this early in your application startup before doing any logging.
Source code in azure_bootstrap/services/bootstrap_logging.py
get_bootstrap_logger
¶
Get a logger that works during bootstrap phase.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
Logger name (typically name) |
required |
Returns:
| Type | Description |
|---|---|
Logger
|
Logger configured for bootstrap use |
Example
from src.infrastructure.bootstrap_logging import get_bootstrap_logger
logger = get_bootstrap_logger(name) logger.info("This works before full telemetry setup!")
Source code in azure_bootstrap/services/bootstrap_logging.py
soft_fail
¶
soft_fail(*, operation: str, catch: type[BaseException] | tuple[type[BaseException], ...] = Exception, alert_severity: str | None = 'error', counter_name: str | None = None, re_raise_unrecoverable: bool = True) -> Generator[dict[str, Any], None, None]
Context-manager form of :func:soft_fail_with.
Yields a mutable dict the caller can inspect after the block::
with soft_fail(operation='ai.summary', counter_name='ai.summary.failed') as ctx:
summary = ai.summarize(text)
if ctx['degraded']:
summary = None # caller handles the degraded case
Source code in azure_bootstrap/softfail/__init__.py
soft_fail_with
¶
soft_fail_with(fn: Callable[..., T], *args: Any, fallback: T, catch: type[BaseException] | tuple[type[BaseException], ...] = Exception, operation: str, alert_severity: str | None = 'error', counter_name: str | None = None, fallback_fn: Callable[[BaseException], T] | None = None, re_raise_unrecoverable: bool = True, **kwargs: Any) -> SoftFailResult[T]
Call fn(*args, **kwargs); soft-fail with fallback on caught error.
Unrecoverable exceptions (per :func:is_unrecoverable) propagate by
default — set re_raise_unrecoverable=False to explicitly suppress
them too.
Source code in azure_bootstrap/softfail/__init__.py
traced
¶
traced(*, operation: str | None = None, alert_on_error: str | None = None, sensitive_args: tuple[str, ...] = (), log_result: bool = False, slow_threshold_seconds: float | None = None) -> Callable[[F], F]
Trace sync or async functions.
Records latency on every call (success + exception). Logs entry/exit at
DEBUG only. When DEBUG is off, inspect.signature is skipped so the
hot path stays cheap.
Source code in azure_bootstrap/tracing/decorators.py
114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 | |
configure_transports
¶
configure_transports(*, console: bool | None = None, app_insights: bool | None = None, sumo_logic: bool | None = None, panther: bool | None = None, file: bool | None = None, blob: bool | None = None, sql: bool | None = None, nosql: bool | None = None, adx: bool | None = None, event_hubs: bool | None = None) -> None
Enable/disable the ten built-in transports. Idempotent and re-runnable.
For each sink, an explicit boolean wins; otherwise the per-transport env flag is consulted (defaults: console on, all others off).
============== ============================== parameter env flag ============== ============================== console CONSOLE_LOGGING_ENABLED app_insights APP_INSIGHTS_LOGGING_ENABLED sumo_logic SUMO_LOGIC_LOGGING_ENABLED panther PANTHER_LOGGING_ENABLED file FILE_LOGGING_ENABLED blob BLOB_LOGGING_ENABLED sql SQL_LOGGING_ENABLED nosql NOSQL_LOGGING_ENABLED ============== ==============================
Also sets the root logger to effective_log_level() so enabled transports
actually receive records (the stdlib root default of WARNING would otherwise
drop INFO/DEBUG). Honors the LOG_LEVEL / DEBUG_LOGGING_ENABLED env
contract shared with configure_logging().
Source code in azure_bootstrap/transports/__init__.py
disable_transport
¶
Detach (and close) the transport's handler. Idempotent.
Returns True if a handler was removed, False if it was not enabled.
Source code in azure_bootstrap/transports/__init__.py
enable_transport
¶
Attach the transport's handler to the root logger. Idempotent.
Returns True if a handler was added, False if the transport was already
enabled or its factory returned None (transport unavailable).
Source code in azure_bootstrap/transports/__init__.py
list_transports
¶
Return {name: {"registered": True, "enabled": bool}} for all transports.
Source code in azure_bootstrap/transports/__init__.py
register_transport
¶
Register a transport factory under name.
Raises ValueError if name is already registered and replace is
False. Re-registering a currently-enabled transport disables it first; the
caller must re-enable to pick up the new factory.
Source code in azure_bootstrap/transports/__init__.py
queue_message_schema
¶
queue_message_schema(*, required_fields: Iterable[str] = ('correlation_id',), path_field: str | None = None, path_required_prefix: str | None = None, counter_namespace: str = 'queue_message') -> MessageSchema
Build a sensible MessageSchema for the common consumer case.
Adds path-traversal defense (forbidden substrings .. and ://)
when path_field is supplied. required_prefix enforces a blob /
container scoping convention.
Source code in azure_bootstrap/validation/__init__.py
validate_message
¶
validate_message(payload: Any, schema: MessageSchema, *, raise_unrecoverable: bool = True) -> dict[str, Any]
Validate payload against schema. Returns the dict on success.
Failures (non-dict, missing field, type mismatch, pattern, forbidden
substring/prefix, required_prefix) bump the namespaced counter and
raise :class:InvalidMessageError by default.
Source code in azure_bootstrap/validation/__init__.py
refresh_setting
¶
refresh_setting(*names: str) -> None
Re-read named settings from the cached App Configuration repo and
write their values into os.environ.
Net-new in v2. Designed to be called from a recurring job (see
azure_bootstrap.config_refresh.refresh_log_flags) so ops can flip a
setting in App Configuration and see it take effect within seconds
without redeploying.
No-ops with a DEBUG log when initialize_application() has not yet
run. Best-effort — never raises.