Registry / http-networking / aiosmtpd

aiosmtpd

JSON →
library1.4.6pypypi✓ verified 22d ago

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.

pip install aiosmtpd
INSTALL
IMPORT
SIG · AIOSMTPD
A
aiosmtpd
http-networkingpythonv1.4.6
Install
1.7s avg
Import
328ms
Disk
18MB
Pass rate
10/ 10
Env Coverage10 / 10
glibc
3.93.13
musl
3.93.13
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
musl
py 3.103.95 runs
installs and imports cleanly · install 0.0s · import 0.346s · 19.4MB
glibc
py 3.103.95 runs
installs and imports cleanly · install 1.7s · import 0.310s · 20MB
18MB installed
● package 18MB
Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

Controller
from aiosmtpd.controller import Controller
from aiosmtpd import Controller
The Controller class is in the 'controller' submodule.
SMTP
from aiosmtpd.smtp import SMTP
Directly using SMTP is possible but Controller is often preferred for managing the server in a separate thread.
handlers.Sink
from aiosmtpd.handlers import Sink
Commonly used handler for testing, discards all incoming mail.
handlers.Debugging
from aiosmtpd.handlers import Debugging
Default handler for the command-line script; prints incoming mail to stdout.

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
Debug
Known issues
breakingThe signature of the `handle_NOOP()` method in custom handlers changed from taking zero arguments to requiring a single argument in version 1.4.x. Custom handlers implementing this method must be updated.
fix
Update `handle_NOOP(self, server)` to accept the `server` argument: `async def handle_NOOP(self, server): ...`
affects: >=1.4.0
gotchaBy default, the SMTP AUTH extension might not be advertised or supported by the server unless a STARTTLS command is issued first, or `auth_require_tls=False` is explicitly passed to the `Controller` or `SMTP` constructor. This can cause authentication failures with clients expecting immediate AUTH support.
fix
If clients connect without STARTTLS and require AUTH, initialize `Controller` or `SMTP` with `auth_require_tls=False`: `Controller(handler, ..., auth_require_tls=False)`.
affects: All versions
deprecatedThe `process_message()` method in handler classes was deprecated. Implementations should now use the asynchronous `handle_DATA(self, server, session, envelope)` method for processing incoming mail data.
fix
Migrate `process_message()` logic to `async def handle_DATA(self, server, session, envelope): ...` ensuring it returns an SMTP response string (e.g., `'250 OK'`).
affects: <1.0a5
deprecatedThe `authentication_handler` parameter for the `SMTP` class constructor was deprecated in favor of `authenticator` and is scheduled for removal in version 2.0.
fix
Replace `authentication_handler=my_func` with `authenticator=Authenticator(my_func)` (where `Authenticator` is imported from `aiosmtpd.smtp`).
affects: >=1.3.0
gotchaThe default `ready_timeout` for `Controller.start()` to wait for the SMTP server thread to become ready changed from 1 second to 5 seconds. This could impact testing setups or deployments sensitive to startup times.
fix
Adjust tests or application logic that rely on a specific short startup timeout, or explicitly set `ready_timeout` in the `Controller` constructor: `Controller(handler, ..., ready_timeout=1.0)`.
affects: >=1.4.2
breakingWhile PyPI states `requires_python >=3.8`, the official documentation recommends CPython>=3.9 and PyPy>=3.9. The upcoming version 1.4.7 explicitly drops support for Python 3.8, requiring an upgrade if using newer `aiosmtpd` versions.
fix
Ensure your environment uses Python 3.9 or newer to guarantee compatibility with current and future `aiosmtpd` releases.
affects: >=1.4.7 (future)
Errors
Common errors & fixes
ModuleNotFoundError: No module named 'aiosmtpd'
The 'aiosmtpd' package is not installed in the Python environment.
fix
Install the package using pip: 'pip install aiosmtpd'.
ModuleNotFoundError: No module named 'public'
An outdated version of 'setuptools' is being used, which lacks support for the 'public' module required by 'aiosmtpd'.
fix
Upgrade 'setuptools' to at least version 46.4.0: 'pip install --upgrade setuptools'.
ImportError: No module named 'aiosmtpd'
The 'aiosmtpd' package is not installed in the Python environment.
fix
Install the package using pip: 'pip install aiosmtpd'.
OSError: [Errno 98] Address already in use
This error occurs when the `aiosmtpd` server attempts to bind to a network address (IP and port) that is already being used by another process on your system.
fix
Ensure no other process is listening on the desired port. You can either choose a different port for your `aiosmtpd` server or terminate the process currently occupying the port. For development, you can often add `sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)` (though `aiosmtpd`'s `Controller` usually handles this; checking for an actively running process is the primary solution).
Connection refused
This commonly happens when an `aiosmtpd` server is configured to listen only on localhost (e.g., '::1' or '127.0.0.1') by default, but a client attempts to connect from a different IP address, or when the server is not running or a firewall is blocking the connection.
fix
When initializing the `Controller`, specify `hostname='0.0.0.0'` to listen on all available network interfaces, allowing connections from other machines or Docker containers. Also, verify the server is running and that no firewall is blocking the port.
Upgrade
Version history
1.4.6latest on PyPI · released May 18, 2024
Audit
Dependencies
PythonrequiredOfficially tested on CPython>=3.9 and PyPy>=3.9, though PyPI metadata states >=3.8. Future versions will drop Python 3.8 support.
Agent activity
73 hits · last 30 days
node
62
Amazon
1
OpenAI (training)
1
Resources