CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-django-sendgrid-v5

Django email backend implementation compatible with SendGrid API v5+ for seamless email delivery integration

Pending
Overview
Eval results
Files

configuration.mddocs/

Configuration

Django settings integration for configuring SendGrid API access, tracking options, sandbox mode, debugging features, and other SendGrid-specific behaviors. All configuration is handled through Django's settings system.

Capabilities

Required Settings

Essential configuration settings that must be provided for the backend to function.

# Required in settings.py
SENDGRID_API_KEY = str  # SendGrid API key for authentication
EMAIL_BACKEND = "sendgrid_backend.SendgridBackend"  # Django email backend

Basic Setup Example

# settings.py
import os

EMAIL_BACKEND = "sendgrid_backend.SendgridBackend"
SENDGRID_API_KEY = os.environ.get("SENDGRID_API_KEY")

# Validate API key presence
if not SENDGRID_API_KEY:
    raise ImproperlyConfigured("SENDGRID_API_KEY environment variable is required")

API Configuration

Settings for SendGrid API endpoint and connection parameters.

SENDGRID_API_KEY = str  # SendGrid API key (required)
SENDGRID_HOST_URL = str  # API endpoint URL (optional)

API Configuration Examples

Standard US endpoint (default):

# settings.py
SENDGRID_API_KEY = "SG.your-api-key-here"
# SENDGRID_HOST_URL defaults to https://api.sendgrid.com

EU endpoint configuration:

# settings.py  
SENDGRID_API_KEY = "SG.your-eu-api-key-here"
SENDGRID_HOST_URL = "https://api.eu.sendgrid.com"

Multiple environment configuration:

# settings.py
import os

# Different API keys per environment
if os.environ.get("ENVIRONMENT") == "production":
    SENDGRID_API_KEY = os.environ["SENDGRID_PROD_API_KEY"]
elif os.environ.get("ENVIRONMENT") == "staging":
    SENDGRID_API_KEY = os.environ["SENDGRID_STAGING_API_KEY"]
else:
    SENDGRID_API_KEY = os.environ["SENDGRID_DEV_API_KEY"]

Sandbox and Debug Settings

Control email delivery behavior in development and testing environments.

SENDGRID_SANDBOX_MODE_IN_DEBUG = bool  # Enable sandbox in DEBUG mode (default: True)
SENDGRID_ECHO_TO_STDOUT = bool  # Echo emails to stdout (default: False)

Sandbox Configuration Examples

Development environment setup:

# settings.py
DEBUG = True

# Prevent accidental email sending in development
SENDGRID_SANDBOX_MODE_IN_DEBUG = True  # Emails won't be delivered

# Enable debug output
SENDGRID_ECHO_TO_STDOUT = True  # Print emails to console

Production environment setup:

# settings.py  
DEBUG = False

# Ensure emails are delivered in production
SENDGRID_SANDBOX_MODE_IN_DEBUG = False  # Not used when DEBUG=False anyway

# Disable debug output
SENDGRID_ECHO_TO_STDOUT = False

Testing environment setup:

# test_settings.py
DEBUG = True

# Force sandbox mode for tests
SENDGRID_SANDBOX_MODE_IN_DEBUG = True

# Capture email output for testing
SENDGRID_ECHO_TO_STDOUT = True

Tracking Settings

Configure email open and click tracking behavior for all emails sent through the backend.

SENDGRID_TRACK_EMAIL_OPENS = bool  # Track email opens (default: True)
SENDGRID_TRACK_CLICKS_HTML = bool  # Track clicks in HTML content (default: True)  
SENDGRID_TRACK_CLICKS_PLAIN = bool  # Track clicks in plain text (default: True)

Tracking Configuration Examples

Full tracking enabled (default):

# settings.py
SENDGRID_TRACK_EMAIL_OPENS = True
SENDGRID_TRACK_CLICKS_HTML = True  
SENDGRID_TRACK_CLICKS_PLAIN = True

Privacy-focused configuration:

# settings.py - Minimal tracking for privacy compliance
SENDGRID_TRACK_EMAIL_OPENS = False
SENDGRID_TRACK_CLICKS_HTML = False
SENDGRID_TRACK_CLICKS_PLAIN = False

Selective tracking configuration:

# settings.py - Track opens but not clicks
SENDGRID_TRACK_EMAIL_OPENS = True
SENDGRID_TRACK_CLICKS_HTML = False
SENDGRID_TRACK_CLICKS_PLAIN = False

Webhook Configuration

Settings for webhook signature verification and event processing.

SENDGRID_WEBHOOK_VERIFICATION_KEY = str  # Webhook signature verification key

Webhook Configuration Example

# settings.py
SENDGRID_WEBHOOK_VERIFICATION_KEY = os.environ.get("SENDGRID_WEBHOOK_KEY")

# Webhook endpoint configuration
WEBHOOK_ENDPOINTS = {
    'sendgrid_events': '/webhooks/sendgrid/events/',
    'sendgrid_inbound': '/webhooks/sendgrid/inbound/',
}

Runtime Configuration Override

Backend initialization parameters that can override Django settings at runtime.

# SendgridBackend.__init__() parameters
api_key = str  # Override SENDGRID_API_KEY
host = str  # Override SENDGRID_HOST_URL  
stream = io.TextIOBase  # Custom output stream for echoing
fail_silently = bool  # Error handling behavior

Runtime Override Examples

Custom backend instance:

from sendgrid_backend import SendgridBackend
import sys

# Override settings for specific use case
custom_backend = SendgridBackend(
    api_key="different-api-key",
    host="https://api.eu.sendgrid.com",
    stream=sys.stderr,  # Custom output stream
    fail_silently=True
)

# Use custom backend
messages = [EmailMessage(...)]
sent_count = custom_backend.send_messages(messages)

Configuration Validation

The backend performs automatic validation of configuration settings.

# Validation errors raised
ImproperlyConfigured  # Missing or invalid required settings
ValueError  # Invalid parameter values (e.g., ip_pool_name length)

Configuration Validation Examples

API key validation:

# Will raise ImproperlyConfigured if no API key provided
try:
    backend = SendgridBackend()
except ImproperlyConfigured as e:
    print("SendGrid configuration error:", e)
    # Handle missing API key

Parameter validation:

from django.core.mail import EmailMessage

msg = EmailMessage(from_email="test@example.com", to=["recipient@example.com"])

# Invalid IP pool name (too short)
msg.ip_pool_name = "x"  # Must be 2-64 characters

try:
    msg.send()
except ValueError as e:
    print("Invalid IP pool name:", e)

Environment-Specific Configuration

Best practices for managing configuration across different environments.

# base_settings.py
EMAIL_BACKEND = "sendgrid_backend.SendgridBackend"

# Default tracking settings
SENDGRID_TRACK_EMAIL_OPENS = True
SENDGRID_TRACK_CLICKS_HTML = True
SENDGRID_TRACK_CLICKS_PLAIN = True

# development_settings.py
from .base_settings import *

DEBUG = True
SENDGRID_API_KEY = os.environ.get("SENDGRID_DEV_API_KEY")
SENDGRID_SANDBOX_MODE_IN_DEBUG = True
SENDGRID_ECHO_TO_STDOUT = True

# production_settings.py  
from .base_settings import *

DEBUG = False
SENDGRID_API_KEY = os.environ.get("SENDGRID_PROD_API_KEY")
SENDGRID_HOST_URL = "https://api.eu.sendgrid.com"  # EU compliance

# Disable debug features
SENDGRID_ECHO_TO_STDOUT = False

# testing_settings.py
from .base_settings import *

DEBUG = True
SENDGRID_API_KEY = "test-key"  # Fake key for testing
SENDGRID_SANDBOX_MODE_IN_DEBUG = True

# Capture output for test assertions
SENDGRID_ECHO_TO_STDOUT = True

Configuration Utilities

Helper functions for working with Django settings in the context of SendGrid configuration.

def get_django_setting(setting_str, default=None):
    """
    Safely retrieve Django setting with fallback default.
    
    Parameters:
    - setting_str (str): Name of Django setting
    - default: Default value if setting not found
    
    Returns:
    Setting value or default
    """

Utility Usage Example

from sendgrid_backend.util import get_django_setting

# Safe setting retrieval with defaults
sandbox_mode = get_django_setting("SENDGRID_SANDBOX_MODE_IN_DEBUG", True)
track_opens = get_django_setting("SENDGRID_TRACK_EMAIL_OPENS", True)
api_timeout = get_django_setting("SENDGRID_API_TIMEOUT", 30)

# Use in custom configuration logic
if get_django_setting("CUSTOM_EMAIL_THROTTLING", False):
    # Apply custom rate limiting
    pass

Version Detection Constants

Constants for detecting SendGrid API version compatibility.

# Available from sendgrid_backend.util
SENDGRID_VERSION: str  # SendGrid package version string
SENDGRID_5: bool  # True if using SendGrid v5.x  
SENDGRID_6: bool  # True if using SendGrid v6.x

Version Constants Usage

from sendgrid_backend.util import SENDGRID_5, SENDGRID_6, SENDGRID_VERSION

# Check SendGrid version for compatibility
if SENDGRID_6:
    # Use v6-specific features like dynamic_template_data
    msg.dynamic_template_data = {"name": "John"}
else:
    # Use v5-compatible substitutions
    msg.substitutions = {"name": "John"}

# Log version information
print(f"Using SendGrid version: {SENDGRID_VERSION}")

Personalization Utilities

Utility function for converting dictionary data to SendGrid Personalization objects.

def dict_to_personalization(data: dict) -> Personalization:
    """
    Convert dictionary to SendGrid Personalization object.
    
    Reverses Sendgrid's Personalization.get() method to create a 
    Personalization object from its emitted data structure.
    
    Parameters:
    - data (dict): Dictionary containing personalization data
    
    Returns:
    - Personalization: SendGrid Personalization object
    """

Personalization Utility Usage

from sendgrid_backend.util import dict_to_personalization

# Convert dictionary to Personalization object
personalization_data = {
    "to": [{"email": "user@example.com", "name": "User"}],
    "dynamic_template_data": {"name": "John", "product": "Widget"},
    "custom_args": {"campaign": "spring_sale"}
}

personalization = dict_to_personalization(personalization_data)

# Use in EmailMessage
msg = EmailMessage(from_email="sender@example.com")
msg.personalizations = [personalization]
msg.send()

Install with Tessl CLI

npx tessl i tessl/pypi-django-sendgrid-v5

docs

configuration.md

email-backend.md

index.md

signals.md

templates-personalization.md

webhooks.md

tile.json