Metadata-Version: 2.4
Name: domainkit
Version: 0.2.0
Summary: A Django-style framework for domain-driven FastAPI services.
License-Expression: MIT
License-File: LICENSE
Keywords: ddd,domain-driven-design,fastapi,sqlalchemy,outbox,framework
Author: karim magdy
Author-email: karimhady111@gmail.com
Requires-Python: >=3.13,<4
Classifier: Development Status :: 3 - Alpha
Classifier: Framework :: FastAPI
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
Classifier: Typing :: Typed
Provides-Extra: metrics
Provides-Extra: postgres
Provides-Extra: sqlite
Provides-Extra: testing
Provides-Extra: tracing
Requires-Dist: aiosqlite (>=0.22.1,<0.23.0) ; extra == "sqlite"
Requires-Dist: alembic (>=1.20.0,<2.0.0)
Requires-Dist: asyncpg (>=0.31.0,<0.32.0) ; extra == "postgres"
Requires-Dist: fastapi (>=0.141.1,<0.142.0)
Requires-Dist: httpx2 (>=2.13.0,<3.0.0) ; extra == "testing"
Requires-Dist: opentelemetry-api (>=1.45.1,<2.0.0) ; extra == "tracing"
Requires-Dist: prometheus-client (>=0.26.0,<0.27.0) ; extra == "metrics"
Requires-Dist: pydantic (>=2.14.1,<3.0.0)
Requires-Dist: pytest (>=9.1.1,<10.0.0) ; extra == "testing"
Requires-Dist: python-dotenv (>=1.2.4,<2.0.0)
Requires-Dist: sqlalchemy[asyncio] (>=2.0.54,<2.1)
Requires-Dist: uvicorn[standard] (>=0.54.0,<0.55.0)
Project-URL: Changelog, https://github.com/karimmattar/domainkit/blob/main/CHANGELOG.md
Project-URL: Documentation, https://github.com/karimmattar/domainkit/blob/main/docs/reference.md
Project-URL: Homepage, https://github.com/karimmattar/domainkit
Project-URL: Issues, https://github.com/karimmattar/domainkit/issues
Description-Content-Type: text/markdown

# domainkit

A Django-style framework for domain-driven FastAPI services. It provides:

- settings modules and installed domains
- `manage.py` commands and migrations
- DDD building blocks, with the layer rules between them enforced
- optional apps for reliable messaging, audit trails, and idempotent requests

```bash
pip install "domainkit[postgres]"     # extras: postgres, sqlite, metrics, tracing, testing
```

## Documentation

- [docs/reference.md](https://github.com/karimmattar/domainkit/blob/main/docs/reference.md): settings, middleware, errors,
  observability, testing, commands, and extension points
- [docs/contrib.md](https://github.com/karimmattar/domainkit/blob/main/docs/contrib.md): messaging, audit, and idempotency
- [docs/versioning.md](https://github.com/karimmattar/domainkit/blob/main/docs/versioning.md): compatibility, deprecations, and releases
- [docs/adr/](https://github.com/karimmattar/domainkit/tree/main/docs/adr): the decisions behind the design
- [CHANGELOG.md](https://github.com/karimmattar/domainkit/blob/main/CHANGELOG.md) and [SECURITY.md](https://github.com/karimmattar/domainkit/blob/main/SECURITY.md)

## Quick start

```bash
python3.13 -m venv .venv && . .venv/bin/activate
pip install "domainkit[postgres,sqlite,testing]"
domainkit init billingAPI billing     # the name sets the variable prefix: BILLING_API_*
cd billing
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
python manage.py runserver            # http://127.0.0.1:8000/docs
```

`domainkit init` creates a project that passes `check` and its tests as it is:

```text
billing/
  pyproject.toml          the name, dependencies, and the pytest plugin
  manage.py
  .env                    selects config.settings.local on this machine
  .gitignore
  src/config/settings/    base, local, test, and production settings
  src/config/urls.py      the root router: mount each domain's router here
  src/config/asgi.py      the application, for uvicorn
  src/domains/            the bounded contexts
  tests/test_health.py
```

The production settings read `BILLING_API_ALLOWED_HOSTS` and
`BILLING_API_DATABASE_URL` from the environment, and the deployment checks
refuse to start without them, or without verified TLS to the database.

## Developing domainkit

```bash
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
```

The database tests use SQLite unless `DOMAINKIT_TEST_POSTGRES_URL` names a
PostgreSQL server; each test then creates a database there and drops it.
Use a throwaway server:

```bash
docker run -d --rm --name domainkit-postgres -e POSTGRES_PASSWORD=postgres \
  -p 127.0.0.1:55432:5432 postgres:18-alpine
DOMAINKIT_TEST_POSTGRES_URL=postgresql+asyncpg://postgres:postgres@127.0.0.1:55432/postgres \
  poetry run pytest
```

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
- the tests again with PostgreSQL 18, including row locking, the audit
  triggers, and server-side timeouts
- 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](https://github.com/karimmattar/domainkit/blob/main/docs/versioning.md).

## License

MIT; see [LICENSE](https://github.com/karimmattar/domainkit/blob/main/LICENSE).

