Skip to main content

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-ui spans injected by Quill
  • Normalizes list tags based on data-list attribute (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-list attributes 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)

Source distribution for abs-email-core 0.1.4
File Size Uploaded
abs_email_core-0.1.4.tar.gz 10.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for abs-email-core 0.1.4
File Interpreter ABI Platform
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

Release history Release notifications | RSS feed

This release

0.1.4 This release

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page