Email plugin for Litestar
Project description
litestar-email
Email support for Litestar applications. This plugin provides a pluggable email backend system for sending transactional emails with support for multiple providers.
Installation
pip install litestar-email
Usage
from litestar import Litestar
from litestar_email import EmailConfig, EmailPlugin
config = EmailConfig(
backend="console", # or "memory", "smtp", "sendgrid", "resend"
from_email="noreply@example.com",
from_name="My App",
)
app = Litestar(plugins=[EmailPlugin(config=config)])
Sending Email
from litestar_email import EmailMessage
message = EmailMessage(
subject="Welcome!",
body="Thanks for signing up.",
to=["user@example.com"],
)
async with config.provide_service() as mailer:
await mailer.send_message(message)
If message.from_email is omitted, the service uses config.from_email and
config.from_name as defaults.
Dependency Injection
The plugin registers a mailer dependency for handlers by default:
from litestar import get
from litestar_email import EmailMessage, EmailService
@get("/welcome/{email:str}")
async def send_welcome(email: str, mailer: EmailService) -> dict[str, str]:
message = EmailMessage(
subject="Welcome!",
body="Thanks for signing up.",
to=[email],
)
await mailer.send_message(message)
return {"status": "sent"}
This works for both router handlers and controller methods the same way, since the dependency is registered on the app.
If you need a service outside of Litestar (e.g., for a worker), use
config.get_service() for a one-off instance or config.provide_service()
for batch sending.
Events and Listeners
Event listeners in Litestar execute outside request context and cannot receive DI-injected dependencies. Pass the mailer explicitly:
from litestar import Litestar, get
from litestar.events import listener
from litestar_email import EmailConfig, EmailMessage, EmailPlugin, EmailService
config = EmailConfig(
backend="smtp",
from_email="noreply@example.com",
from_name="My App",
)
@get("/register/{email:str}")
async def register(email: str, mailer: EmailService) -> dict[str, str]:
# Pass the DI-injected mailer to the event
request.app.emit("user.registered", email, mailer=mailer)
return {"status": "queued"}
@listener("user.registered")
async def on_user_registered(email: str, mailer: EmailService) -> None:
# mailer is passed explicitly from emit(), not injected via DI
await mailer.send_message(
EmailMessage(subject="Welcome!", body="Thanks for signing up.", to=[email]),
)
app = Litestar(
plugins=[EmailPlugin(config=config)],
listeners=[on_user_registered],
)
You can override the dependency and state keys via EmailConfig if needed:
email_service_dependency_key="email_service" and email_service_state_key="email_service".
Standalone (No Litestar)
Use the config helpers directly without Litestar:
from litestar_email import EmailConfig, EmailMessage
config = EmailConfig(backend="smtp", from_email="noreply@example.com")
message = EmailMessage(
subject="Hello!",
body="This is a standalone send.",
to=["user@example.com"],
)
async with config.provide_service() as mailer:
await mailer.send_message(message)
For batch sends, use the context manager to reuse the connection:
async with config.provide_service() as mailer:
await mailer.send_messages([message1, message2, message3])
HTML Email
from litestar_email import EmailMultiAlternatives
message = EmailMultiAlternatives(
subject="Welcome!",
body="Thanks for signing up.", # Plain text fallback
html_body="<h1>Welcome!</h1><p>Thanks for signing up.</p>",
to=["user@example.com"],
)
Available Backends
| Backend | Description | Use Case |
|---|---|---|
console |
Prints emails to stdout | Development |
memory |
Stores emails in memory | Testing |
smtp |
Async SMTP via aiosmtplib | Production |
sendgrid |
SendGrid HTTP API | Production |
resend |
Resend HTTP API | Production |
Testing
The InMemoryBackend is designed for testing:
from litestar_email.backends import InMemoryBackend
def test_sends_welcome_email():
InMemoryBackend.clear()
# ... code that sends email ...
assert len(InMemoryBackend.outbox) == 1
assert InMemoryBackend.outbox[0].subject == "Welcome!"
If you need direct backend access in tests, use config.get_backend():
from litestar_email import EmailConfig, EmailMessage
config = EmailConfig(backend="memory")
backend = config.get_backend()
message = EmailMessage(subject="Hello", body="Body", to=["user@example.com"])
await backend.send_messages([message])
Development
make install # Install dependencies
make test # Run tests
make lint # Run linting
make check-all # Run all checks
License
MIT
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 litestar_email-0.2.0.tar.gz.
File metadata
- Download URL: litestar_email-0.2.0.tar.gz
- Upload date:
- Size: 187.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f89b48cff0e514206755bea9ee1eb71fcede90befe02159bdce49df7b52cf896
|
|
| MD5 |
23c232de762429ee32412593babad431
|
|
| BLAKE2b-256 |
13ae8fde4b5656906647deba103dfb747f6e1a5750a6e52e621592ac52081e01
|
Provenance
The following attestation bundles were made for litestar_email-0.2.0.tar.gz:
Publisher:
publish.yml on cofin/litestar-email
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
litestar_email-0.2.0.tar.gz -
Subject digest:
f89b48cff0e514206755bea9ee1eb71fcede90befe02159bdce49df7b52cf896 - Sigstore transparency entry: 790872260
- Sigstore integration time:
-
Permalink:
cofin/litestar-email@5efd7481d9273db5bdfa218d75da74c6b64465b1 -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/cofin
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@5efd7481d9273db5bdfa218d75da74c6b64465b1 -
Trigger Event:
release
-
Statement type:
File details
Details for the file litestar_email-0.2.0-py3-none-any.whl.
File metadata
- Download URL: litestar_email-0.2.0-py3-none-any.whl
- Upload date:
- Size: 24.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
86f00685970ce32d4ef1153c35483bc7b4e1c4b18224f4278c94165d7ca4d810
|
|
| MD5 |
61dd03fa480072e152f067f2b1048628
|
|
| BLAKE2b-256 |
95d8f1588245c3a429810f732b91d6b7c061b138523f49879f0ff71526830b54
|
Provenance
The following attestation bundles were made for litestar_email-0.2.0-py3-none-any.whl:
Publisher:
publish.yml on cofin/litestar-email
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
litestar_email-0.2.0-py3-none-any.whl -
Subject digest:
86f00685970ce32d4ef1153c35483bc7b4e1c4b18224f4278c94165d7ca4d810 - Sigstore transparency entry: 790872267
- Sigstore integration time:
-
Permalink:
cofin/litestar-email@5efd7481d9273db5bdfa218d75da74c6b64465b1 -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/cofin
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@5efd7481d9273db5bdfa218d75da74c6b64465b1 -
Trigger Event:
release
-
Statement type: