A chainable Django email sender utility.
Project description
📧 Django Email Sender Utility
A clean, reusable, lightweight and chainable utility class for sending emails in Django using templates. It supports both HTML and plain text templates, context injection, and flexible usage — either directly, via subclassing, or abstracted into functions.
🧠 Why Use This?
While Django already provides a way to send emails, it can become verbose and repetitive. EmailSender abstracts the boilerplate and lets you send templated emails fluently.
✨ Features
- Chainable API (
.to(),.from_address(), etc.) - Supports HTML and plain text templates
- Uses Django's template system for dynamic content
- Easy to integrate and override
- Encourages clean code and reusability
- Supports subclassing or functional abstractions
🛠 Available Methods
Method Description
- create() # Class factory method to instantiate the EmailSender.
- from_address(email) # Sets the sender’s email address.
- to(recipients) # Accepts a string or list of recipient email addresses.
- with_subject(subject) # Sets the email subject.
- with_context(context) # Context dictionary used in the templates.
- with_text_template(path) # Path to the plain text email template.
- with_html_template(path) # Path to the HTML email template.
- with_headers(headers) # Optional custom headers as a dictionary.
- send() # Sends the email. Returns the number of successfully delivered messages.
🚨 Error Handling
- Raises ValueError if required fields are missing.
- Raises TypeError if headers are not provided as a dictionary.
🚀 Installation
This is a standalone utility. Copy the file into your Django project, or install it as a package using PyPI.
🧩 Requirements
- Python 3.8+
- Django >= 3.2
🧪 Basic Usage
Here's a simple example of how to send an email using EmailSender:
from email_sender import EmailSender
EmailSender.create()\
.from_address("no-reply@example.com")\
.to(["recipient@example.com"])\
.with_subject("Welcome!")\
.with_context({"username": "John"})\
.with_text_template("welcome.txt", folder_name="emails")\
.with_html_template("welcome.html", folder_name="emails")\
.send()
Explanation:
.from_address("no-reply@example.com"): Specifies the sender's email address..to(["recipient@example.com"]): Specifies the recipient's email address..with_subject("Welcome!"): The subject of the email..with_context({"username": "John"}): Context for the email templates, allowing dynamic insertion of values (e.g., the recipient's name)..with_text_template("welcome.txt", folder_name="emails"): The path to the text-based email template. Here, we specify the folder name (emails) where the template is stored. If no folder name is provided, it defaults toemail_templates/..with_html_template("welcome.html", folder_name="emails"): The path to the HTML-based email template. Similarly, you can specify the folder name (emails) for this template..send(): Sends the email.
🧱 Subclassing
You can also subclass the EmailSender class to create more specific types of emails.
Example: Password Reset Email
class PasswordResetEmail(EmailSender):
def __init__(self, user):
super().__init__()
self.user = user
def build(self):
return self\
.from_address("no-reply@example.com")\
.to([self.user.email])\
.with_subject("Reset Your Password")\
.with_context({"username": self.user.username, "reset_link": generate_reset_link(self.user)})\
.with_text_template("reset_password.txt", folder_name="emails")\
.with_html_template("reset_password.html", folder_name="emails")
Usage:
PasswordResetEmail(user).build().send()
Here, the PasswordResetEmail class uses reset_password.txt and reset_password.html templates from the emails folder.
🛠️ Function-Based Abstractions
For a functional approach, you can also wrap EmailSender in specific functions to handle common email use cases.
Example: Sending a Verification Email
def send_verification_email(user):
html_verification_path = "verification/verification.html"
text_verification_path = "verification/verification.txt"
subject = "Verify Your Email"
from_email = "no-reply@example.com"
return EmailSender.create()\
.from_address(from_email)\
.to([user.email])\
.with_subject(subject)\
.with_context({
"username": user.username,
"verification_link": generate_verification_link(user)
})\
.with_text_template(text_verification_path, folder_name="emails")\
.with_html_template(html_verification_path, folder_name="emails")\
.send()
Example: Sending a Registration Email
def send_registration_email(user):
html_registration_path = "registration/registration.html"
text_registration_path = "registration/registration.txt"
subject = "Welcome to the Platform!"
from_email = "no-reply@example.com"
return EmailSender.create()\
.from_address(from_email)\
.to([user.email])\
.with_subject(subject)\
.with_context({"username": user.username})\
.with_text_template(text_registration_path, folder_name="emails")\
.with_html_template(html_registration_path, folder_name="emails")\
.send()
Advantages of this Approach:
- Keeps your logic functional and simple: It's straightforward to use and easy to test.
- Keeps your email templates modular and easy to override: Templates are organized in subfolders (e.g.,
registration,verification), making them easier to manage. - Clean and maintainable codebase: You don’t have to subclass
EmailSendereach time, reducing complexity.
📁 Templates
Templates must reside inside a dedicated email_templates/ directory, which should exist inside your Django template directory.
This folder can contain your own structure to help organise different types of emails. For example:
Example
project/
├── templates/
│ └── email_templates/
│ └── registration/
│ ├── registration.html
│ └── registration.txt
When calling with_html_template() or with_text_template(), you can provide the subfolder and filename like so:
EmailSender.create()
.with_html_template("registration.html", folder_name="registration")
.with_text_template("registration.txt", folder_name="registration")
You must have both an .html and .txt version of the email template. These are required for rich content and email client compatibility.
💡 Tips
- You can subclass
EmailSenderfor different email types or simply wrap it in functions. - Organise your templates by email type (
registration/,verification/, etc.) - Subject and context are fully customisable.
Project details
Release history Release notifications | RSS feed
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 django_email_sender-1.0.2.tar.gz.
File metadata
- Download URL: django_email_sender-1.0.2.tar.gz
- Upload date:
- Size: 8.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b9e854a8e292ab49d8357175e6def35c69236e60f083e2ea3563d44358eaa473
|
|
| MD5 |
2a66352c3deb735e9a23ee150675d05a
|
|
| BLAKE2b-256 |
993e7afe445746d15173fa877ebfaf4193809fb7537ce39054b0c79dba621b6f
|
File details
Details for the file django_email_sender-1.0.2-py3-none-any.whl.
File metadata
- Download URL: django_email_sender-1.0.2-py3-none-any.whl
- Upload date:
- Size: 8.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c2d1b0c8d9273e4adceeaedb06498cfce43499d906a1501be10add2af9606a7a
|
|
| MD5 |
81cab9affb4d886c4f300e0eff973732
|
|
| BLAKE2b-256 |
aa0cb7f59cf6b060c177ce34445786439ca84c47811c525a6bb4b5d5fb5ba6c8
|