dsmtpd 1.2.0
Simple SMTP Server for debugging
License: BSD-2-Clause
Requires Python: >=3.10

dsmptd: A debugger SMTP server for Humans
=========================================

.. image:: https://github.com/matrixise/dsmtpd/workflows/Tests/badge.svg
   :target: https://github.com/matrixise/dsmtpd/actions/workflows/tests.yml
   :alt: Tests Status

dsmtpd is a small tool to help the developer without an smtp server

**Python Support:** Python 3.10, 3.11, 3.12, 3.13, 3.14

Usage
-----

::

    $ dsmtpd -p 1025 -i 127.0.0.1
    2013-01-13 14:00:07,346 INFO: Starting SMTP server at 127.0.0.1:1025


Installation
------------

For the installation, we recommend to use a virtualenv, it's the easy way if you want to discover this package::

    virtualenv ~/.envs/dsmtpd
    source ~/.envs/dsmtpd/bin/activate

    pip install dsmtpd

Command-Line Options
--------------------

``-p PORT, --port PORT``
    Specify the port to listen on. Default: **1025**

``-i INTERFACE, --interface INTERFACE``
    Specify the network interface to bind to. Default: **127.0.0.1** (loopback)

``-d DIRECTORY, --directory DIRECTORY``
    Specify a Maildir directory to save incoming emails. Default: current directory

``-s SIZE, --max-size SIZE``
    Maximum message size in bytes. Use **0** for no limit. Default: **33554432** (32 MiB)

``--disable-smtputf8``
    Disable SMTPUTF8 extension for legacy SMTP client compatibility. Default: **enabled**

``--version``
    Show program version and exit

``-h, --help``
    Show help message and exit

Usage Examples
--------------

Start server with default settings (port 1025, localhost)::

    dsmtpd

Start server on custom port::

    dsmtpd -p 2525

Bind to all interfaces::

    dsmtpd -i 0.0.0.0 -p 25

Save emails to specific Maildir::

    dsmtpd -d /path/to/maildir

Limit message size to 10 MB::

    dsmtpd --max-size 10485760

Disable UTF-8 support for legacy clients::

    dsmtpd --disable-smtputf8

Send a test email with swaks::

    swaks --from sender@example.com --to recipient@example.com --server localhost --port 1025

Features
--------

**SMTPUTF8 Support**

dsmtpd has built-in support for SMTPUTF8 (RFC 6531), which allows email addresses and content to contain UTF-8 characters. This feature is **enabled by default** and requires no configuration.

SMTPUTF8 enables:

* Email addresses with international characters (e.g., ``用户@例え.jp``)
* UTF-8 encoded message headers and body content
* Full Unicode support in SMTP transactions

Example usage with UTF-8 email addresses::

    swaks --from user@example.com --to 用户@例え.jp --server localhost --port 1025

This functionality is provided by the underlying aiosmtpd library and works transparently with all standard SMTP clients that support the SMTPUTF8 extension.

**Disabling SMTPUTF8**

If you need to test compatibility with legacy SMTP clients or reproduce encoding issues, you can disable SMTPUTF8::

    dsmtpd --disable-smtputf8

When disabled, the server will not advertise SMTPUTF8 support and will only accept ASCII email addresses and content.

Exit Codes
----------

``dsmtpd`` uses specific exit codes to indicate the result of its execution.

+------+---------------------------+--------------------------------------------+
| Code | Meaning                   | Example                                    |
+======+===========================+============================================+
| 0    | Success                   | Normal shutdown (e.g. user pressed         |
|      |                           | ``Ctrl+C``) or clean termination.          |
+------+---------------------------+--------------------------------------------+
| 2    | Invalid Maildir directory | The given path exists but does not contain |
|      |                           | the required subfolders: ``tmp``, ``new``, |
|      |                           | and ``cur``.                               |
+------+---------------------------+--------------------------------------------+

Contributing
------------

Clone the repository::

    git clone git://github.com/matrixise/dsmtpd.git
    cd dsmtpd

Development
-----------

The project includes a Makefile to simplify development tasks. It automatically manages
a virtual environment and dependencies using Python from asdf or mise.

**Quick Start**

Set up your development environment::

    make install-dev

This creates a ``.venv`` virtual environment and installs all development dependencies.

**Available Make Targets**

Development Workflow:

* ``make install-dev`` - Set up development environment (creates venv and installs dependencies)
* ``make test`` - Run tests with pytest (automatically installs dependencies if needed)
* ``make lint`` - Check code quality with ruff linter
* ``make lint-fix`` - Auto-fix linting issues and format code with ruff
* ``make format`` - Format code with ruff format
* ``make typecheck`` - Run mypy type checking

Build and Release:

* ``make build`` - Build distribution packages
* ``make check-dist`` - Verify distribution package integrity

Cleanup:

* ``make clean`` - Remove all build artifacts and virtual environment
* ``make clean-build`` - Remove only build artifacts (dist/, build/)
* ``make clean-venv`` - Remove only the virtual environment

**Workflow Tips**

The Makefile uses smart dependency tracking. Running ``make test`` multiple times will only
reinstall dependencies if ``requirements-dev.txt`` or ``setup.cfg`` have changed, making
repeated test runs much faster.

To force a fresh installation of dependencies::

    make install-dev

**Running Tests**

After setting up the development environment::

    make test

Or directly with pytest::

    .venv/bin/pytest

**Code Quality & Pre-commit Hooks**

The project uses `prek <https://github.com/j178/prek>`_ to simplify pre-commit hook setup.

After installing development dependencies, set up pre-commit hooks::

    prek install

This automatically installs git hooks that will:

* Run ``ruff`` linter with auto-fix
* Run ``ruff format`` for code formatting
* Run ``mypy`` for type checking

You can also run quality checks manually::

    make lint        # Check code quality
    make lint-fix    # Auto-fix linting issues
    make format      # Format code
    make typecheck   # Run mypy type checking

The pre-commit hooks ensure code quality before commits, catching issues early and
maintaining consistent code standards across all contributions.


Copyright 2013 (c) by Stephane Wirtel

dsmtpd Changelog
================

Here you can see the full list of changes between each dsmtpd release.

Version 1.2.0
-------------

Released on January 7th 2026.

Features:

- Document SMTPUTF8 support (RFC 6531) - enabled by default via aiosmtpd (#32)
- SMTPUTF8 allows UTF-8 email addresses, headers, and message content
- Add ``--disable-smtputf8`` CLI option to disable SMTPUTF8 extension for legacy client compatibility (#34)

Development improvements:

- Add test coverage reporting with pytest-cov (#29)
- Add code quality tools: ruff (linting/formatting) and mypy (type checking) (#29)
- Add pre-commit hooks with prek for automated code quality checks (#31)
- New make targets: ``lint``, ``lint-fix``, ``format``, ``typecheck`` (#29)
- Enhanced Makefile with automatic virtual environment management
- Add smart dependency tracking to avoid unnecessary reinstallations during development
- New make targets: ``install-dev``, ``clean``, ``clean-build``, ``clean-venv``
- Makefile now uses Python from asdf/mise for consistent development environments
- Significantly faster repeated test runs with timestamp-based dependency tracking
- Add comprehensive tests for the debugging SMTP server (#8)
- New integration tests for email reception, storage, and multipart email handling
- Add tests for ``--version`` flag and ``--max-size`` option (#29)
- Add test for SMTPUTF8 support verification (#32)
- Add support for Python 3.14 (#25)
- Replace deprecated license classifiers with SPDX license expression (#24)
- GitHub Actions workflow now includes linting and type checking jobs (#29)

Version 1.1
-----------

Released on September 13th 2025.

- Lower Python version requirement from 3.12 to 3.10 (#17)
- Fix crash when directory exists but is not yet a valid Maildir with proper validation and repair functionality (#18)
- Add exit codes documentation to README
- Code formatting improvements with ruff

Version 1.0
-----------

Release on May 20th 2025.

- Migration to aiosmtpd to Support Python >= 3.12 (#11, patch by Sebastian Wagner)
- Add minimal tests for maildir check and importability
- Add systemd service file (by Sebastian Wagner)

Version 0.3
-----------

Release on May 26th 2021.

- Maildir capture: added early check (patch by Bernhard E. Reiter)
- Remove the support of Docopt
- Remove the support of Python 2.x (dead in 2020)
- Support Python 3.6+
- Improve the classifiers for PyPI
- Migrate to PEP 517
- Fix License into setup.py
- Add tests for the CLI using argparse instead of docopt

Version 0.2
-----------

Release on January 21st 2013.

- Allow to store the incoming emails in a maildir via the '-d' argument

Version 0.1
-----------

Release on January 14th 2013.

- Implement a basic server
- Show the message in the log