simple_smtp_sender
A Simple SMTP Email sender crate with the support of sync or async sending. Can be called from Python. Powered by Rust, lettre and PyO3.
Overview
This project provides rust crate and a Python extension module implemented in Rust for sending emails via SMTP, including support for attachments, CC, and BCC. There are methods for both synchronous and asynchronous sending. It leverages the performance and safety of Rust, exposes a convenient Python API, and is built using PyO3 and lettre. The python module is compatible with Python 3.10 and above.
Features
- Send emails via SMTP synchronously or asynchronously
- Support HTML email contents
- Attach files to emails
- Support for CC and BCC
- Secure authentication
- Easy configuration via Python class
- Flexible feature flags for Rust-only or Python-enabled builds
- No Python dependencies required for Rust-only usage
Installation
Python Package from PyPI
# or
Rust Crate
[]
# Rust-only version (no Python dependencies)
= { = "0.4.1" }
Build Python package from Source (requires Rust toolchain and maturin)
Please note that the default feature does not include the Python PyO3 binding.
To build Python binding using maturin, please declare the dependency with --features python:
## prepare venv and maturin if needed
# uv venv
# uv sync
Or build a wheel:
Requirements
- Python >= 3.10 (for Python package)
- Rust toolchain (for building from source)
Usage
Rust
check examples.rs in examples/ for more examples.
Python
An example from Python API:
=
# Synchronous send (blocking)
# With attachment, CC, and BCC:
# Asynchronous send (non-blocking)
await
API
EmailConfig
Configuration class for SMTP server and credentials.
__new__ parameters:
server: SMTP server URLsender_email: Sender's email addressusername: SMTP usernamepassword: SMTP password
APIs:
load_from_env(): Load configuration from environment variables:EMAIL_SERVEREMAIL_SENDER_EMAILEMAIL_USERNAMEEMAIL_PASSWORD
load_from_map(config_map: dict): Load configuration from a dictionary.load_from_pydantic(pydantic_obj: BaseModel): Load configuration from a PydanticBaseModel. Requirespydanticto be installed in the active Python environment. RaisesRuntimeErrorifpydanticcannot be imported,TypeErrorif the argument is not aBaseModelinstance, andValueErrorif the model's fields cannot be deserialized into anEmailConfig.to_dict(): Convert theEmailConfiginstance into a Pythondict[str, str].
Sends an email synchronously (blocking) using the provided configuration.
send_email(config, recipient, subject, body, cc=None, bcc=None, attachment=None)
config:EmailConfiginstancerecipient: List of recipient email(s)subject: Email subjectbody: Email bodycc: List of CC recipients (optional)bcc: List of BCC recipients (optional)attachment: Path to file to attach (optional)
Sends an email asynchronously (non-blocking, returns an awaitable).
async_send_email(config, recipient, subject, body, cc=None, bcc=None, attachment=None)
config:EmailConfiginstancerecipient: List of recipient email(s)subject: Email subjectbody: Email bodycc: List of CC recipients (optional)bcc: List of BCC recipients (optional)attachment: Path to file to attach (optional)
Development
- Rust dependencies are managed in
Cargo.toml. - Python build configuration is in
pyproject.toml. - Main Rust logic in
src/.
License
MIT