really simple mailing lists
a small, self-hosted mailing list system.
rsml is a mailing list manager system written in python built with minimalism in mind, it does not try to be a GNU Mailman competitor but rather a simpler alternative.
features
- toml-based configuration (
rsml.toml) (rsml.config) - RFC 4155 and mboxrd compliant
.mboxfile generator (rsml.mbox) - mailing list posting via LMTP
- two-step subscription via
/list/subscribeand/list/verify /list/archiveendpoint for.mboxarchive retrieval of the mailing list- one-click unsubscribe with
List-UnsubscribeandList-Unsubscribe-Post(RFC 8058)
quick start
rsml can be run directly with python or as a container using an OCI-compatible runtime.
- create a configuration
cp rsml.toml.example rsml.toml # copy the example configuration
${EDITOR:-nano} rsml.toml # modify the configuration file
at minimum, configure the server secret. see
rsml.toml.examplefor the available options.
- run rsml
2.1 with python
pip install rsml # install rsml and dependencies
start the http server:
rsml http
in a separate process, start the lmtp server:
rsml lmtp
2.2 with a container
alternatively, rsml can be run from its OCI container image using podman, docker, or another OCI-compatible runtime.
example (with podman)
podman run --rm -it \
-p 8080:8080 \
-v "$PWD/rsml.toml:/home/rsml/rsml.toml:ro" \
ghcr.io/juanvel4000/rsml:latest \
http
and for the lmtp server
podman run --rm -it \
-p 8024:8024 \
-v "$PWD/rsml.toml:/home/rsml/rsml.toml:ro" \
ghcr.io/juanvel4000/rsml:latest \
lmtp
- configure your mta
rsml receives mailing-list messages through LMTP. configure your mta to deliver messages destined for the mailing list to the rsml lmtp server.
set relay_host and relay_port in rsml.toml to the hostname and port of the mta used by rsml for outgoing mail.
dependencies
rsml requires at least
- a python
>=3.11-compatible interpreter
a complete deployement requires
- an mta capable of receiving mail and delivering messages to rsml over LMTP
runtime dependencies include
aiosmtpd/aiosmtplib: for asynchronous SMTP/LMTP operationsflask: for the http serveremail-validator: to validate email addresses
development-time dependencies include:
pytest/pytest-asyncio: to execute the unit tests
usage
pip install -e . # install rsml and dependencies
cp rsml.toml.example rsml.toml # edit server_secret, etc.
rsml http # start the http server
rsml lmtp # start the lmtp server
rsml is intended to run single-threaded.
Storage's sqlite3 connection is not safe for concurrent usage across threads.
running the test suite can be done with pytest
pip install -e ".[dev]" # install dev dependencies
pytest -vs . # run the unit tests
redis support for the rate limiter requires the redis optional dependency set to be installed
pip install -e ".[redis]"
spec
a document outlining the technical specifications of the project can be found in this repository as SPEC.md
project status
rsml is in active development. it is functional and moving toward stability, though some interfaces might still change before a 1.0 release.
- CHANGELOG.md -- release history
- CONTRIBUTING.md -- how to report bugs and send patches
license
BSD-3-Clause -- see LICENSE
Release files for rsml 0.3.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| rsml-0.3.2.tar.gz | 22.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| rsml-0.3.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 36.5 kB
Release files / rsml-0.3.2.tar.gz
| Download URL | rsml-0.3.2.tar.gz |
|---|---|
| Size | 22.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
2695a90d4711a8bc3c7a22837084065f99f9aa995212361338cfeefdbfd7b0aa
|
|
BLAKE2b-256 checksum How to use checksums |
c844550722fe8e6cd866366c9ccc66fea2e53f735d9897bd76c0d4bdb9d3cd6c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 29, 2026.
Transparency logRelease files / rsml-0.3.2-py3-none-any.whl
| Download URL | rsml-0.3.2-py3-none-any.whl |
|---|---|
| Size | 14.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
a2f0b634914ecc56c910d4058771a68e9a846b741241279cd4464f36f9a8f911
|
|
BLAKE2b-256 checksum How to use checksums |
13fc5a96843d2853ac94fd0cce4a39b0b7318873b1199f62e08513f88dcfde73
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 29, 2026.
Transparency log