magic_link
A modular, framework-agnostic engine for delivering passwordless authentication via secure magic links. The project follows a “minimal core + opt-in extras” philosophy so you can embed the library inside any Python stack without surrendering control of storage, email, or infrastructure.
Docs live in
/docs. This README highlights the essentials; detailed guides, recipes, and release instructions are all linked below.
Table of Contents
- Features
- Requirements
- Installation
- Quick Start
- Extras
- CLI Utilities
- Documentation
- Testing
- Release Process
- Contributing
- License
Features
- 🔐 Secure token engine – deterministic HMAC signing, hashing, TTL enforcement, property-based tests.
- 🗃️ Pluggable storage – in-memory for dev, SQLAlchemy for RDBMS, Redis for low-latency workloads.
- ✉️ Mailer registry – SMTP implementation plus extensible template hooks.
- 🎛️ Service facade –
MagicLinkServicecoordinates issuance, verification, rate limiting, and single-use guarantees. - 🛠️ CLI helpers –
magic-link generate-configandmagic-link test-emailstreamline setup and diagnostics. - 📚 Extensive documentation – quickstarts, framework recipes (FastAPI, Flask), and in-depth guides for email, migrations, and security.
- ✅ 100% test coverage – unit, integration, and property-based suites validated in CI against live PostgreSQL, Redis, and audo SMTP servers.
Requirements
- Python 3.8+
- Optional services depending on extras:
- PostgreSQL (or any SQLAlchemy-supported database) for the SQL backend
- Redis 5+ for the Redis backend
- SMTP relay for outbound email
Installation
Core library:
pip install magic-link
With common extras:
pip install "magic-link[sqlalchemy,redis,smtp]"
Add cli if you want the command-line utilities bundled:
pip install "magic-link[sqlalchemy,redis,smtp,cli]"
Quick Start
-
Generate a configuration template:
magic-link generate-config -o .env
-
Fill in the environment variables (secret key, SMTP credentials, database connection, etc.).
-
Wire the library into your framework. For FastAPI:
from fastapi import FastAPI, HTTPException from fastapi.responses import JSONResponse from magic_link import MagicLinkConfig, MagicLinkService from magic_link.interfaces import MagicLinkMessage from magic_link.mailer import create_mailer from magic_link.storage.redis import RedisStorage app = FastAPI() config = MagicLinkConfig.from_env() storage = RedisStorage.from_url("redis://localhost:6379/0") # see docs for helper service = MagicLinkService(config=config, storage=storage) mailer = create_mailer(config) @app.post("/auth/magic-link") async def issue(payload: dict[str, str]) -> JSONResponse: email = payload.get("email") if not email: raise HTTPException(status_code=400, detail="Email is required") service.enforce_rate_limit(email) issued = service.issue_token(email) link = f"{config.base_url}{config.login_path}?token={issued.token}" mailer.send_magic_link(MagicLinkMessage(recipient=email, link=link, subject="Sign in", expires_at=issued.expires_at)) return JSONResponse({"status": "sent"})
-
Verify tokens using
service.verify_token(...)in your callback endpoint.
For a complete, copy-pasteable example (including Flask), consult the Quickstart guide and recipes.
Extras
| Extra | Installs | Purpose |
|---|---|---|
sqlalchemy |
SQLAlchemy, psycopg[binary] |
Persistent token storage in relational DBs |
redis |
redis, hiredis |
High-throughput storage + rate limiting |
smtp |
email-validator |
SMTP mailer backend and email utilities |
cli |
click |
Command-line helpers (magic-link CLI) |
CLI Utilities
# Print an annotated configuration template
magic-link generate-config
# Send a test email using your configured mailer
magic-link test-email user@example.com
Documentation
- Overview & FastAPI quickstart
- Step-by-step Quickstart
- Framework recipes – Flask and more
- Guides – email templates, database migrations, security considerations
- Architecture
- Release process
Testing
pip install -e ".[dev,sqlalchemy,redis,smtp,cli]"
pytest --cov=magic_link
CI runs the full suite (unit, property-based, integration) against PostgreSQL, Redis, and a local SMTP server. Coverage must stay ≥95% (currently 100%).
Release Process
- Follow the checklist in docs/release.md (trusted publisher + semver workflow).
- Alpha / beta versions: bump
pyproject.toml, updateCHANGELOG.md, tag, and publish. - Official releases are cut via GitHub Releases, which triggers the trusted publisher workflow to upload builds to PyPI.
Contributing
- Open an issue or draft PR for discussion.
- Ensure tests and linters pass (
pytest,ruff check,black --check,mypy). - Update documentation for user-facing changes.
License
Distributed under the MIT License.
Metadata
Release files for magic-link 1.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| magic_link-1.0.0.tar.gz | 24.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| magic_link-1.0.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 47.0 kB
Release files / magic_link-1.0.0.tar.gz
| Download URL | magic_link-1.0.0.tar.gz |
|---|---|
| Size | 24.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
2236eed2e8d3952df1834abee6338d8c85f64b42b90129df47edf4aa6eeb2b19
|
|
BLAKE2b-256 checksum How to use checksums |
3a0899c55a4c7b85bcb251c72b93fa5d60bd93f073fc3f0e1377fbac2c57c7d1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
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 Oct 19, 2025.
Transparency logRelease files / magic_link-1.0.0-py3-none-any.whl
| Download URL | magic_link-1.0.0-py3-none-any.whl |
|---|---|
| Size | 22.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
42dcf7a2f92cac1f2cd196505afcdb10cc1f518a7d29511cea29e51f03a2b7d9
|
|
BLAKE2b-256 checksum How to use checksums |
48920f00e86bb7d621c22375ae4644e7fb51b477a464c9450e105f0c1851536c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
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 Oct 19, 2025.
Transparency log