aiosmtpd is an asyncio-based SMTP and LMTP server, providing an asynchronous, RFC 5321 compliant server that supports customizable extensions. It serves as a modern replacement for the deprecated `smtpd` module in the Python standard library. The current version is 1.4.6, and it's actively maintained under the aio-libs umbrella project.
Install & Compatibility
Where this runs
tested against v1.4.6 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
muslpy 3.10–3.920 runs
installs and imports cleanly · install 0.0s · import 0.350s · 19.4MB
glibcpy 3.10–3.920 runs
installs and imports cleanly · install 1.7s · import 0.305s · 20MB
18MB installed
● package 18MB
Code
Verified usage
Verified import paths — ran on the pinned version, not inferred.
The Controller class is in the 'controller' submodule.
from aiosmtpd.controller import Controller
Directly using SMTP is possible but Controller is often preferred for managing the server in a separate thread.
from aiosmtpd.smtp import SMTP
Commonly used handler for testing, discards all incoming mail.
from aiosmtpd.handlers import Sink
Default handler for the command-line script; prints incoming mail to stdout.
from aiosmtpd.handlers import Debugging
This quickstart sets up a basic SMTP server on `127.0.0.1:8025` using the `Debugging` handler, which prints all received emails to the console. It leverages `Controller` to run the server in a separate thread, allowing the main program to continue running or wait for interruption. You can connect to this server with any SMTP client (e.g., `smtplib` or `telnet`).
import asyncio
from aiosmtpd.controller import Controller
from aiosmtpd.handlers import Debugging
import os
async def amain():
# Use Debugging handler to print incoming emails to console
handler = Debugging()
# The Controller runs the SMTP server in a separate thread.
# For testing/quickstart, localhost:8025 is common.
controller = Controller(handler, hostname=os.environ.get('SMTP_HOST', '127.0.0.1'), port=int(os.environ.get('SMTP_PORT', 8025)))
print(f"Starting SMTP server on {controller.hostname}:{controller.port}...")
controller.start()
print("SMTP server started. Press Ctrl+C to stop.")
try:
# Keep the main loop running while the controller's thread handles the SMTP server
await asyncio.Event().wait()
except asyncio.CancelledError:
pass
finally:
controller.stop()
print("SMTP server stopped.")
if __name__ == '__main__':
# Run the asyncio event loop
try:
asyncio.run(amain())
except KeyboardInterrupt:
print("Server interrupted by user.")
aiosmtpd --version
Upgrade
Version history
Breaking-change detection hasn't run for this library yet.
Audit
Security & dependencies
CVE tracking and dependency tree are planned for a later release.