Skip to main content

Comprehensive Python logger for Azure, integrating OpenTelemetry for advanced, structured, and distributed tracing.

Project description

AzPaddyPy

Python 3.11+ Azure

AzPaddyPy is a comprehensive Python package for Azure cloud services integration with standardized configuration management, OpenTelemetry tracing, and builder patterns. It simplifies Azure service orchestration while providing flexible, production-ready patterns for complex cloud applications.

๐ŸŒŸ Key Features

  • ๐Ÿ” Azure Identity Management - Token caching, multiple credential types, seamless authentication
  • ๐Ÿ—๏ธ Azure Key Vault Integration - Secrets, keys, and certificates management
  • ๐Ÿ’พ Azure Storage Operations - Blob, file, and queue storage with unified APIs
  • ๐Ÿ“Š Comprehensive Logging - Application Insights integration with OpenTelemetry tracing
  • ๐Ÿ—๏ธ Builder Patterns - Flexible service composition and configuration
  • ๐ŸŒ Environment Detection - Docker vs local development with smart defaults
  • โš™๏ธ Configuration Management - Environment variables, .env files, and service discovery

๐Ÿ“ฆ Installation

# Install with pip
pip install azpaddypy

# Install with uv (recommended)
uv add azpaddypy

๐Ÿš€ Quick Start

Simple Usage (Direct Imports)

from azpaddypy import logger, identity, keyvault, storage_account

# Use logger for application logging
logger.info("Application started")

# Use identity for Azure authentication  
token = identity.get_token("https://management.azure.com/.default")

# Access secrets from Key Vault
secret_value = keyvault.get_secret("my-secret")

# Use storage services
blob_client = storage_account.blob_service_client

Builder Pattern Usage (Recommended)

from azpaddypy.builder import (
    ConfigurationSetupBuilder, 
    AzureManagementBuilder, 
    AzureResourceBuilder
)

# 1. Setup environment configuration
env_config = (
    ConfigurationSetupBuilder()
    .with_local_env_management()      # Load .env files (FIRST)
    .with_environment_detection()     # Detect Docker vs local
    .with_service_configuration()     # Parse service settings
    .with_logging_configuration()     # Setup logging
    .with_identity_configuration()    # Configure authentication
    .build()
)

# 2. Build management services (logger, identity, key vault)
management = (
    AzureManagementBuilder(env_config)
    .with_logger()
    .with_identity() 
    .with_keyvault(vault_url="https://my-vault.vault.azure.net/")
    .build()
)

# 3. Build resource services (storage, etc.)
resources = (
    AzureResourceBuilder(management, env_config)
    .with_storage(account_url="https://mystorageaccount.blob.core.windows.net/")
    .build()
)

# 4. Use the configured services
management.logger.info("Services configured successfully")
secret = management.keyvault.get_secret("database-password")
blob_client = resources.storage_account.blob_service_client

๐Ÿ”ง Configuration

Environment Variables

Create a .env file or set environment variables:

# Required: Key Vault Configuration
key_vault_uri=https://my-vault.vault.azure.net/
head_key_vault_uri=https://my-admin-vault.vault.azure.net/

# Required: Storage Configuration  
STORAGE_ACCOUNT_URL=https://mystorageaccount.blob.core.windows.net/

# Optional: Service Configuration
REFLECTION_NAME=my-application
REFLECTION_KIND=functionapp
SERVICE_VERSION=1.0.0

# Optional: Logging Configuration
LOGGER_LOG_LEVEL=INFO
APPLICATIONINSIGHTS_CONNECTION_STRING=InstrumentationKey=...

# Optional: Identity Configuration
IDENTITY_ENABLE_TOKEN_CACHE=true
IDENTITY_ALLOW_UNENCRYPTED_STORAGE=true

# Optional: Feature Toggles
KEYVAULT_ENABLE_SECRETS=true
KEYVAULT_ENABLE_KEYS=false
KEYVAULT_ENABLE_CERTIFICATES=false

STORAGE_ENABLE_BLOB=true
STORAGE_ENABLE_FILE=true  
STORAGE_ENABLE_QUEUE=true

Azure Authentication

AzPaddyPy supports multiple authentication methods automatically:

Local Development:

# Option 1: Azure CLI (recommended)
az login

# Option 2: Environment variables
export AZURE_CLIENT_ID=your-client-id
export AZURE_TENANT_ID=your-tenant-id  
export AZURE_CLIENT_SECRET=your-client-secret

Production (Azure):

  • Managed Identity (automatically detected)
  • Service Principal (via environment variables)

๐Ÿ“š Usage Examples

Working with Key Vault

from azpaddypy.builder import AzureManagementBuilder, ConfigurationSetupBuilder

# Setup
env_config = ConfigurationSetupBuilder().with_local_env_management().build()
management = (
    AzureManagementBuilder(env_config)
    .with_identity()
    .with_keyvault(name="primary", vault_url="https://my-vault.vault.azure.net/")
    .with_keyvault(name="admin", vault_url="https://my-admin-vault.vault.azure.net/")
    .build()
)

# Access secrets
database_password = management.keyvaults["primary"].get_secret("database-password")
admin_key = management.keyvaults["admin"].get_secret("admin-api-key")

# Set secrets
management.keyvaults["primary"].set_secret("new-secret", "secret-value")

Working with Storage

from azpaddypy.builder import AzureResourceBuilder

# Build storage configuration
resources = (
    AzureResourceBuilder(management, env_config)
    .with_storage(
        name="main",
        account_url="https://mystorageaccount.blob.core.windows.net/",
        enable_blob=True,
        enable_file=True,
        enable_queue=True
    )
    .build()
)

# Use storage services
storage = resources.storage_accounts["main"]

# Blob operations
blob_client = storage.blob_service_client
container_client = blob_client.get_container_client("my-container")

# Upload a file
with open("local-file.txt", "rb") as data:
    container_client.upload_blob(name="remote-file.txt", data=data)

# Queue operations  
queue_client = storage.queue_service_client
queue = queue_client.get_queue_client("my-queue")
queue.send_message("Hello from azpaddypy!")

# File share operations
file_client = storage.file_service_client
share_client = file_client.get_share_client("my-share")

Advanced Logging

from azpaddypy.builder import AzureManagementBuilder

management = (
    AzureManagementBuilder(env_config)
    .with_logger(
        log_level="DEBUG",
        enable_console=True
    )
    .build()
)

logger = management.logger

# Structured logging
logger.info("User action", extra={
    "user_id": "12345",
    "action": "login",
    "ip_address": "192.168.1.1"
})

# Error logging with context
try:
    risky_operation()
except Exception as e:
    logger.error("Operation failed", extra={
        "error_type": type(e).__name__,
        "operation": "risky_operation"
    }, exc_info=True)

Environment-Specific Configuration

from azpaddypy.builder import ConfigurationSetupBuilder

# Local development configuration
local_config = {
    "AzureWebJobsStorage": "UseDevelopmentStorage=true",
    "DATABASE_URL": "sqlite:///local.db"
}

env_config = (
    ConfigurationSetupBuilder()
    .with_local_env_management()
    .with_environment_detection()
    .with_environment_variables(
        local_config,
        in_docker=False,    # Don't apply in Docker
        in_machine=True     # Apply on local machine
    )
    .with_service_configuration()
    .build()
)

Director Patterns (Simplified Setup)

from azpaddypy.builder.directors import (
    ConfigurationSetupDirector,
    AzureManagementDirector,
    AzureResourceDirector
)

# Quick setup with sensible defaults
env_config = ConfigurationSetupDirector.build_default_config()
management = AzureManagementDirector.build_default_config(env_config)
full_config = AzureResourceDirector.build_default_config(env_config, management)

# Access services
logger = full_config.management.logger
keyvault = full_config.management.keyvault
storage = full_config.resources.storage_account

๐Ÿ—๏ธ Architecture

AzPaddyPy follows a layered builder pattern architecture:

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚        Application Layer           โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚     AzureConfiguration (Combined)   โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚  AzureResourceConfiguration         โ”‚
โ”‚  - Storage Accounts                 โ”‚
โ”‚  - Additional Resources             โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚  AzureManagementConfiguration       โ”‚  
โ”‚  - Logger (App Insights)            โ”‚
โ”‚  - Identity (Token Cache)           โ”‚
โ”‚  - Key Vaults                       โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚  EnvironmentConfiguration           โ”‚
โ”‚  - Environment Detection            โ”‚
โ”‚  - Service Configuration            โ”‚
โ”‚  - Local Development Support        โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Builder Flow

  1. ConfigurationSetupBuilder - Environment setup and detection
  2. AzureManagementBuilder - Core management services
  3. AzureResourceBuilder - Azure resource services
  4. Directors - Pre-configured common patterns

๐Ÿ”’ Security Best Practices

Key Vault Security

# โœ… Good: Use specific vault URLs
management.with_keyvault(vault_url="https://prod-vault.vault.azure.net/")

# โŒ Avoid: Hardcoding secrets
database_password = "hardcoded-password"  # DON'T DO THIS

# โœ… Good: Retrieve from Key Vault
database_password = keyvault.get_secret("database-password")

Identity Security

# โœ… Good: Enable token caching for performance
.with_identity_configuration(
    enable_token_cache=True,
    allow_unencrypted_storage=False  # Use encrypted cache in production
)

# โœ… Good: Use Managed Identity in production
# No additional configuration needed - automatically detected

Environment Security

# โœ… Good: Environment-specific configurations
production_config = {
    "IDENTITY_ALLOW_UNENCRYPTED_STORAGE": "false",
    "LOGGER_LOG_LEVEL": "WARNING"
}

development_config = {
    "IDENTITY_ALLOW_UNENCRYPTED_STORAGE": "true", 
    "LOGGER_LOG_LEVEL": "DEBUG"
}

๐Ÿš€ Production Deployment

Azure Functions

# function_app.py
import azure.functions as func
from azpaddypy.builder.directors import AzureManagementDirector, ConfigurationSetupDirector

# Initialize once at module level
env_config = ConfigurationSetupDirector.build_default_config()
management = AzureManagementDirector.build_default_config(env_config)

app = func.FunctionApp()

@app.function_name("HttpTrigger")
@app.route(route="api/data")
def http_trigger(req: func.HttpRequest) -> func.HttpResponse:
    management.logger.info("Function triggered")
    
    # Access secrets
    api_key = management.keyvault.get_secret("external-api-key")
    
    # Your function logic here
    return func.HttpResponse("Success")

Docker Deployment

# Dockerfile
FROM python:3.11-slim

WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt

COPY . .

# Set environment variables
ENV REFLECTION_KIND=functionapp
ENV LOGGER_LOG_LEVEL=INFO

CMD ["python", "app.py"]

Environment Configuration

# docker-compose.yml
version: '3.8'
services:
  app:
    build: .
    environment:
      - key_vault_uri=https://prod-vault.vault.azure.net/
      - STORAGE_ACCOUNT_URL=https://prodstorage.blob.core.windows.net/
      - APPLICATIONINSIGHTS_CONNECTION_STRING=${APP_INSIGHTS_CONN_STRING}
    depends_on:
      - azurite
  
  azurite:
    image: mcr.microsoft.com/azure-storage/azurite
    ports:
      - "10000:10000"
      - "10001:10001" 
      - "10002:10002"

๐Ÿงช Testing

# test_azpaddypy.py
import pytest
from azpaddypy.builder import ConfigurationSetupBuilder, AzureManagementBuilder

def test_configuration_setup():
    """Test basic configuration setup."""
    env_config = (
        ConfigurationSetupBuilder()
        .with_local_env_management()
        .with_environment_detection()
        .build()
    )
    
    assert env_config.service_name is not None
    assert env_config.logger_log_level in ["DEBUG", "INFO", "WARNING", "ERROR"]

@pytest.mark.asyncio
async def test_key_vault_integration():
    """Test Key Vault integration.""" 
    management = (
        AzureManagementBuilder(env_config)
        .with_identity()
        .with_keyvault(vault_url="https://test-vault.vault.azure.net/")
        .build()
    )
    
    # Test secret retrieval (requires actual vault in integration tests)
    # secret = management.keyvault.get_secret("test-secret")
    # assert secret is not None

๐Ÿค Contributing

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Make your changes
  4. Add tests for new functionality
  5. Run tests (uv run pytest)
  6. Commit your changes (git commit -m 'Add amazing feature')
  7. Push to the branch (git push origin feature/amazing-feature)
  8. Open a Pull Request

๐Ÿ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.

๐Ÿ“ž Support

๐Ÿ”„ Changelog

v0.6.8

  • Comprehensive builder patterns for Azure services
  • OpenTelemetry integration for advanced tracing
  • Environment detection and local development support
  • Multi-Key Vault support with named configurations
  • Enhanced storage operations with unified APIs

Made with โค๏ธ for Azure developers

Project details


Release history Release notifications | RSS feed

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

azpaddypy-0.7.5.tar.gz (68.8 kB view details)

Uploaded Source

Built Distribution

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

azpaddypy-0.7.5-py3-none-any.whl (42.7 kB view details)

Uploaded Python 3

File details

Details for the file azpaddypy-0.7.5.tar.gz.

File metadata

  • Download URL: azpaddypy-0.7.5.tar.gz
  • Upload date:
  • Size: 68.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.6.9

File hashes

Hashes for azpaddypy-0.7.5.tar.gz
Algorithm Hash digest
SHA256 950d7649f80ea556d0fc19d634f045d38c11feffbc6556e9ed3071a48b61b501
MD5 a6e66a5b42bbbaf7b5e6efa14c2e51d8
BLAKE2b-256 fb02ba5ea2f4fd675e8332a1d1268b036d9d590558f082656e0342d04526fbd3

See more details on using hashes here.

File details

Details for the file azpaddypy-0.7.5-py3-none-any.whl.

File metadata

  • Download URL: azpaddypy-0.7.5-py3-none-any.whl
  • Upload date:
  • Size: 42.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.6.9

File hashes

Hashes for azpaddypy-0.7.5-py3-none-any.whl
Algorithm Hash digest
SHA256 38fc0e7cb2aa818df5a614aeed26d0e2d9eaeb70c65af674025165995b398d3f
MD5 68ad06c85e041cc7ae09737494a83059
BLAKE2b-256 b3bf9085bf8e1f935b9478eb21afc6c873e59788429706d71d09950b0219a05c

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