PyTemplate is a specialized template rendering engine for creating personalized email campaigns with dynamic content generation, A/B testing support, and comprehensive email client compatibility features.
- Email-safe HTML generation with automatic CSS inlining
- Dynamic personalization with nested data access and fallback values
- A/B test variant generation from single templates
- Email client compatibility validation and warnings
- Multi-client preview rendering simulating how emails appear across platforms
- Plain text generation from HTML templates
- Link tracking with UTM parameter injection
- High performance bulk email generation
# Clone the repository
git clone <repository-url>
cd pytemplate
# Create and activate virtual environment
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
# Install in development mode
pip install -e .
# Install development dependencies
pip install -e ".[dev]"from pytemplate import TemplateEngine, EmailTemplate
from pytemplate.link_tracking import UTMParams
# Initialize the engine
engine = TemplateEngine()
# Create a template
template = EmailTemplate(
subject="Welcome {{name}}!",
content="""
<html>
<head>
<style>
h1 { color: #333; }
.button { background: #007bff; color: white; padding: 10px 20px; }
</style>
</head>
<body>
<h1>Hello {{name|default:Valued Customer}}</h1>
<p>Thanks for joining {{company}}!</p>
<a href="https://example.com/activate" class="button">Activate Account</a>
</body>
</html>
""",
preheader="Complete your registration"
)
# Render for a recipient
result = engine.render_email(
template,
recipient_data={
"name": "John Doe",
"company": "Acme Corp"
},
utm_params=UTMParams(
utm_source="welcome_email",
utm_medium="email",
utm_campaign="onboarding"
)
)
print(result.subject) # "Welcome John Doe!"
print(result.html) # HTML with inlined CSS and tracked links
print(result.plain_text) # Plain text versionConverts external CSS to inline styles for email client compatibility:
from pytemplate import CSSInliner
inliner = CSSInliner()
html_with_inline_css = inliner.inline_css(html, preserve_media_queries=True)Handle dynamic content with nested data access:
from pytemplate import PersonalizationEngine
engine = PersonalizationEngine()
personalized = engine.personalize(
"Hello {{user.name}}, you have {{credits|default:0}} credits",
{"user": {"name": "Alice"}}
)
# Result: "Hello Alice, you have 0 credits"Create test variants from a single template:
from pytemplate.ab_testing import ABTestGenerator, ABTestConfig, VariantElement
generator = ABTestGenerator()
config = ABTestConfig(
test_name="subject_test",
variant_elements=[
VariantElement(
name="subject_line",
path="subject",
variants=["Subject A", "Subject B", "Subject C"]
)
]
)
variants = generator.generate_variants(base_template, config)Check for compatibility issues:
from pytemplate import EmailClientValidator
validator = EmailClientValidator()
issues = validator.validate(html, target_clients=['outlook', 'gmail'])
for issue in issues:
print(f"{issue.severity}: {issue.description}")See how emails appear in different clients:
from pytemplate import PreviewRenderer
renderer = PreviewRenderer()
previews = renderer.render_all_previews(html)
for preview in previews:
print(f"{preview.client}: {preview.modifications_applied}")# Render emails for multiple recipients
recipients = [
{"name": "Alice", "city": "New York"},
{"name": "Bob", "city": "London"},
{"name": "Charlie", "city": "Tokyo"}
]
results = engine.render_bulk(template, recipients)# Create subject line variants
base_template = {
"subject": "Original Subject",
"content": "<p>Email content here</p>"
}
ab_config = ABTestConfig(
test_name="q4_campaign",
variant_elements=[
VariantElement(
name="subject",
path="subject",
variants=[
"Limited Time: 50% Off Everything",
"Flash Sale - Today Only!",
"Your Exclusive Discount Inside"
]
)
]
)
variants = engine.render_ab_test(base_template, ab_config, recipient_data)# Validate template before sending
validation = engine.validate_template(template, sample_data)
if validation['render_test']['success']:
print("Template is valid!")
else:
print(f"Error: {validation['render_test']['error']}")# Run all tests
pytest
# Run with coverage
pytest --cov=pytemplate
# Run specific test file
pytest tests/test_personalization.py
# Generate JSON report (required)
pip install pytest-json-report
pytest --json-report --json-report-file=pytest_results.jsonPyTemplate is designed for high-performance bulk email generation:
- Processes 10,000+ personalized emails per minute
- Efficient CSS inlining with caching
- Optimized personalization token parsing
- Minimal memory footprint
Validated compatibility with:
- Outlook (Desktop & Web)
- Gmail (Web & Mobile)
- Apple Mail (macOS & iOS)
- Yahoo Mail
- Outlook Mobile
- Gmail Mobile App
- Always inline CSS for maximum compatibility
- Test with actual email clients using the preview renderer
- Provide fallback values for all personalization tokens
- Validate templates before bulk sending
- Use A/B testing to optimize campaign performance
- Track links with UTM parameters for analytics
MIT License - see LICENSE file for details.