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,
)
Metadata
Release files for abs-email-core 0.1.4
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| abs_email_core-0.1.4.tar.gz | 10.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| abs_email_core-0.1.4-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 22.1 kB
Release files / abs_email_core-0.1.4.tar.gz
| Download URL | abs_email_core-0.1.4.tar.gz |
|---|---|
| Size | 10.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
efd7ef6d129c675a5e1cfb01609dcbb51427d0a32bedb11e8e52b100a2ef3d44
|
|
BLAKE2b-256 checksum How to use checksums |
e93de51f2734ac3fa967faeec20d9f328ac900ef816fa48d3d3cd1dee32b57cf
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
poetry/2.1.3 CPython/3.13.5 Darwin/24.5.0
|
Release files / abs_email_core-0.1.4-py3-none-any.whl
| Download URL | abs_email_core-0.1.4-py3-none-any.whl |
|---|---|
| Size | 11.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
ea96e0f2f1db9984b3e6a3e3b033f7ca079b741652890d8795c07382619a052c
|
|
BLAKE2b-256 checksum How to use checksums |
6855f4ddfa5c0f08a19cd30562e9d75df0e7e60102dfb443c443cc0dbfe23014
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
poetry/2.1.3 CPython/3.13.5 Darwin/24.5.0
|