domainkit
A Django-style framework for domain-driven FastAPI services. It provides:
- settings modules and installed domains
manage.pycommands and migrations- DDD building blocks, with the layer rules between them enforced
- optional apps for reliable messaging, audit trails, and idempotent requests
pip install "domainkit[postgres]" # extras: postgres, sqlite, metrics, tracing
Documentation
- docs/reference.md: settings, middleware, errors, observability, testing, commands, and extension points
- docs/contrib.md: messaging, audit, and idempotency
- docs/versioning.md: compatibility, deprecations, and releases
- docs/adr/: the decisions behind the design
- CHANGELOG.md and SECURITY.md
Quick start
A project is a pyproject.toml, a manage.py, a config package, and a
domains package for its bounded contexts. The project's name sets the
environment variable prefix: billingAPI reads BILLING_API_*.
billing/
pyproject.toml
manage.py
src/config/__init__.py
src/config/settings/__init__.py
src/config/settings/local.py
src/config/settings/test.py
src/config/urls.py
src/config/asgi.py
src/domains/__init__.py
# pyproject.toml
[project]
name = "billingAPI"
version = "0.1.0"
requires-python = ">=3.13"
dependencies = ["domainkit[sqlite]"]
[tool.pytest.ini_options]
pythonpath = ["src"]
addopts = "-p domainkit.testing" # the database and client fixtures
domainkit_settings = "config.settings.test"
# manage.py
import sys
from pathlib import Path
if __name__ == "__main__":
sys.path.insert(0, str(Path(__file__).resolve().parent / "src"))
from domainkit.management import execute_from_command_line
execute_from_command_line(sys.argv)
# src/config/settings/local.py
from pathlib import Path
from domainkit.conf.env import Env
env = Env()
BASE_DIR = Path(__file__).resolve().parents[3]
DEBUG = True
INSTALLED_DOMAINS = ["domainkit.contrib.messaging"]
ROOT_ROUTER = "config.urls.router"
ASGI_APPLICATION = "config.asgi:application"
DATABASES = {
"default": {
"URL": env.str("DATABASE_URL", f"sqlite+aiosqlite:///{BASE_DIR / 'db.sqlite3'}")
},
}
# src/config/settings/test.py
from config.settings.local import *
DEBUG = False
ALLOWED_HOSTS = ["testserver"]
DATABASES = {"default": {"URL": "sqlite+aiosqlite:///:memory:"}}
# src/config/urls.py
from fastapi import APIRouter
from domainkit.http.health import router as health_router
router = APIRouter()
router.include_router(health_router)
# src/config/asgi.py
from domainkit.http import get_asgi_application
application = get_asgi_application()
Then:
export BILLING_API_SETTINGS_MODULE=config.settings.local # or put it in .env
python manage.py check
python manage.py startdomain invoices --aggregate Invoice # prints how to install it
python manage.py makemigrations -m "create invoices" && python manage.py migrate
pytest # the generated tests
python manage.py runserver # http://127.0.0.1:8000/docs
Developing domainkit
poetry install --all-extras # Python 3.13
pre-commit install # after: pipx install pre-commit
poetry run ruff check . && poetry run ruff format --check . && poetry run mypy
poetry run pytest --cov # random order; coverage gate in pyproject.toml
poetry run mutmut run "domainkit.http*" && poetry run mutmut results
CI (.github/workflows/ci.yml) runs the same checks on every push and pull
request:
- lint and strict typing
- the tests on Python 3.13 and 3.14
- a wheel build, installed and imported in a clean environment
- pip-audit, and a gitleaks scan of the whole history
A full mutation testing run happens weekly. Releases are published to PyPI from a version tag; see docs/versioning.md.
License
MIT; see LICENSE.
Metadata
Release files for domainkit 0.1.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 | |
|---|---|---|---|
| domainkit-0.1.0.tar.gz | 86.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| domainkit-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 217.8 kB
Release files / domainkit-0.1.0.tar.gz
| Download URL | domainkit-0.1.0.tar.gz |
|---|---|
| Size | 86.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
f3c650c07c3cac1e1900a9437059f98ba1a77d95363c18c35b09ed2039e8290a
|
|
BLAKE2b-256 checksum How to use checksums |
c8bd8f83cfa159e9e54cd99e1cbe43ccfc4979fdf0961fc55283a809a1e4b883
|
| 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 Oct 13, 2026.
Transparency logRelease files / domainkit-0.1.0-py3-none-any.whl
| Download URL | domainkit-0.1.0-py3-none-any.whl |
|---|---|
| Size | 131.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
c1fc06d27e921ef331ce4b80e945a07c6255078d55639ef16778d2877d075ca9
|
|
BLAKE2b-256 checksum How to use checksums |
203805560a0ed17d20ec925ab597d3826edfebadca01152a8ecbb135a6b5c9bc
|
| 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 Oct 13, 2026.
Transparency log