Core email utilities with pluggable provider support and Jinja2 template rendering
Project description
abs-email-core
Core email utilities with pluggable provider support, Jinja2 template rendering, and Quill HTML sanitization.
Installation
pip install abs-email-core
# With SendGrid support
pip install "abs-email-core[sendgrid]"
Quick Start
from abs_email_core import SendGridProvider, TemplateService, SendMailRequest
# Initialize provider and template service
provider = SendGridProvider(api_key="your-api-key", from_email="noreply@example.com")
templates = TemplateService(template_dir="/path/to/your/templates")
# Render and send an HTML email
html = templates.render_email_template(title="Welcome", content="<p>Hello!</p>")
request = SendMailRequest(to=["user@example.com"], subject="Welcome", body=html)
provider.send_html_email(request)
Schemas
SendMailRequest
| Field | Type | Required | Description |
|---|---|---|---|
to |
List[EmailStr] |
Yes | Recipient email addresses |
subject |
str |
Yes | Email subject line |
body |
str |
Yes | Email body (plain text or HTML) |
from_email |
EmailStr |
No | Override the provider's default from address |
cc |
List[EmailStr] |
No | CC recipients (default: []) |
bcc |
List[EmailStr] |
No | BCC recipients (default: []) |
FileAttachment
| Field | Type | Required | Description |
|---|---|---|---|
file_name |
str |
Yes | Display name of the attachment |
url |
str |
Yes | URL to the file |
file_id |
str |
No | Optional identifier for the file |
Providers
SendGridProvider
Requires the sendgrid extra: pip install "abs-email-core[sendgrid]"
from abs_email_core import SendGridProvider, SendMailRequest
provider = SendGridProvider(api_key="SG.xxx", from_email="noreply@example.com")
# Plain text email
request = SendMailRequest(to=["user@example.com"], subject="Hello", body="Hi there!")
provider.send_email(request)
# HTML email
request = SendMailRequest(to=["user@example.com"], subject="Hello", body="<h1>Hi!</h1>")
provider.send_html_email(request)
# With file attachments (UploadFile-like objects)
provider.send_email(request, attachments=[upload_file])
Custom Provider
Implement the EmailProvider abstract class to add support for other email services:
from abs_email_core.provider.base import EmailProvider
class SMTPProvider(EmailProvider):
def __init__(self, host: str, port: int, username: str, password: str, from_email: str):
self.host = host
self.port = port
self.username = username
self.password = password
self.from_email = from_email
def send_email(self, request, attachments=None) -> bool:
# SMTP implementation
...
def send_html_email(self, request, attachments=None) -> bool:
# SMTP HTML implementation
...
Template Service
TemplateService uses Jinja2 to render email templates. The template_dir parameter is required — point it to the directory containing your Jinja2 template files.
from abs_email_core import TemplateService
templates = TemplateService(template_dir="/path/to/your/templates")
# Render any template by filename
html = templates.render_template("welcome.html", name="John", code="ABC123")
# Shortcut for the bundled email_template.html (must exist in your template_dir)
html = templates.render_email_template(
title="Welcome",
content="<p>Your account is ready.</p>",
footer="GovAssist Inc.", # optional: footer text
logo_url="https://...", # optional: header/footer logo image URL
attachments=[ # optional: renders download links
{"file_name": "report.pdf", "url": "https://example.com/report.pdf"},
],
)
A default email_template.html is shipped with the package under abs_email_core/templates/ — copy it into your service's template directory or use it as a starting point for customization.
Quill HTML Sanitization
When email content originates from a Quill rich-text editor, the raw HTML often contains structural issues. TemplateService provides built-in sanitization that fixes:
- Removes internal
ql-uispans injected by Quill - Normalizes list tags based on
data-listattribute (bullet→<ul>,ordered→<ol>) - Splits mixed lists (bullet + ordered items in one tag) into separate correct tags
- Merges consecutive same-type lists separated by
<br>or whitespace - Cleans
data-listattributes from<li>elements - Fixes fragmented paragraphs (e.g.
<p>Dear </p>Name<p>,</p>→<p>Dear Name,</p>)
Usage
# Option 1: Sanitize during template rendering
html = templates.render_email_template(
title="Welcome",
content=quill_html,
sanitize_quill=True, # enables Quill HTML sanitization before rendering
)
# Option 2: Sanitize standalone (without rendering a template)
clean_html = templates.sanitize_quill_html(quill_html)
Utilities
Parse Emails
TemplateService includes a helper to parse email addresses from strings or lists:
# From comma/newline-separated string
emails = templates._parse_emails("a@example.com, b@example.com\nc@example.com")
# → ["a@example.com", "b@example.com", "c@example.com"]
# From list (passthrough)
emails = templates._parse_emails(["a@example.com", "b@example.com"])
# → ["a@example.com", "b@example.com"]
Dependency Injection (with dependency-injector)
from dependency_injector import containers, providers
from abs_email_core import SendGridProvider, TemplateService
class Container(containers.DeclarativeContainer):
email_provider = providers.Factory(
SendGridProvider,
api_key=configs.SENDGRID_API_KEY,
from_email=configs.EMAIL_FROM,
)
template_service = providers.Factory(
TemplateService,
template_dir=configs.EMAIL_TEMPLATE_DIR,
)
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file abs_email_core-0.1.4.tar.gz.
File metadata
- Download URL: abs_email_core-0.1.4.tar.gz
- Upload date:
- Size: 10.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/2.1.3 CPython/3.13.5 Darwin/24.5.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
efd7ef6d129c675a5e1cfb01609dcbb51427d0a32bedb11e8e52b100a2ef3d44
|
|
| MD5 |
84e4c0d900f5adcd71b258257119ef18
|
|
| BLAKE2b-256 |
e93de51f2734ac3fa967faeec20d9f328ac900ef816fa48d3d3cd1dee32b57cf
|
File details
Details for the file abs_email_core-0.1.4-py3-none-any.whl.
File metadata
- Download URL: abs_email_core-0.1.4-py3-none-any.whl
- Upload date:
- Size: 11.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/2.1.3 CPython/3.13.5 Darwin/24.5.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ea96e0f2f1db9984b3e6a3e3b033f7ca079b741652890d8795c07382619a052c
|
|
| MD5 |
a7d45a8ec7b3ebdd4f88c69cac7d2eca
|
|
| BLAKE2b-256 |
6855f4ddfa5c0f08a19cd30562e9d75df0e7e60102dfb443c443cc0dbfe23014
|