ninja-devx
ninja-devx adds typed controllers and reusable resource policies to Django Ninja. It is intended for Django APIs that repeat ownership, tenant scoping, transaction, dependency-lifetime and error-handling rules across several endpoints. Services, repositories and contrib modules are optional.
The package is preparing its first 0.0.1 alpha release. See the scope and design rationale, comparison and support policy before adopting it.
class PostController(SoftDeleteMixin[Post, PostOut], CRUDController[Post, PostOut, PostIn]):
owner_field = "author"
search_fields = ("title", "body")
filter_fields = {"status": ("exact",), "created": ("gte", "lte")}
ordering_fields = ("created", "title")
@post("/{pk}/publish", response=PostOut, decorators=[idempotent()])
def publish(self, request: HttpRequest, post: Instance[Post]) -> Post:
post.status = Post.Status.PUBLISHED
post.save(update_fields=["status"])
return post
api = NinjaAPI(auth=django_auth)
mount(api, {"/posts": PostController}, prefix="/v1")
These lines give you:
- list endpoints with search, generated filters, enum-checked ordering and pagination
- retrieve, create, update and partial update
- soft delete, restore and an idempotent publish action
- owner-only writes and schema-derived relation loading
- 422 for model validation errors, and domain errors mapped without exception handlers
- declared error responses included in OpenAPI
Principles:
- Controllers produce
ninja.Routers and use Ninja authentication, pagination and serialization. Async stream preflight has a narrow operation-subclass integration that is tested against supported Ninja versions. - Layers without force: plain controllers, services, use cases or dishka interactors all fit, and none is required.
- Typed end to end: mypy strict and pyright strict pass, and the package has no
typing.Any. - Configuration errors raise at startup.
- Controller overhead is measured against function views with explicit budgets (see performance).
Requires Python 3.11+, Django 4.2+ and django-ninja 1.7+ (support policy).
pip install ninja-devx==0.0.1 # after publication; extras: [guardian] [s3] [crypto] [orjson] [msgspec] [dishka] [svcs] [otel] [client] [contract]
Features
| Area | What you get | Docs |
|---|---|---|
| Controllers | @get/@post/... with typed options, scopes, lifecycle methods, plugins, use_case |
guide |
| Permissions | composable & | ~, Also(...), object-level, async, policies, AuthedRequest[User] |
guide |
| Object permissions | per-object grants (built-in table or django-guardian), DRF-style 404/403, lists filtered in SQL, sharing endpoints | guide |
| Errors | DomainError and typed ErrorMap rules per operation, controller, project; problem+json |
guide |
| CRUD | sync and async from one class, AutoCRUDController[Model], owner_field, Instance/Locked, filters, offset and cursor pagination, nested, configurable soft delete and routes, bulk, CSV/JSONL import and export, N+1 planner |
guide |
| SaaS and HTTP | tenant_field multi-tenancy, ETag/304/If-Match optimistic locking, user/scope/tenant throttles, role-based field visibility, ?fields=/?expand= |
tenancy, caching, throttling, visibility |
| Layers | HTTP-free services, repositories, RequestContext, after-commit tasks, policies, selectors, in-memory fakes |
guide |
| DI | Inject[T], Resolve(fn), a checked container with async factories, dishka and svcs adapters |
guide |
| Async | mode, one thread hop per unit of work, async hooks, loud lazy-load errors, unasync |
guide |
| Cross-cutting | hooks, LoggingHook, OpenTelemetry, atomic=True, idempotent() |
guide |
| Operations | router/API middleware, request ids, deprecation and rate limit headers, health checks, orjson/msgspec renderers | guide |
| Optional integrations | scoped, rate-limited API keys, audit log with diffs, transactional outbox and signed, destination-validated webhooks with encrypted secrets, presigned S3 uploads, Django admin for the credential, audit and webhook records | API keys, audit, webhooks, uploads |
| Quality | system checks, devx_scaffold --check schema drift, schemathesis contract tests, OpenAPI snapshots, assert_max_queries/assert_max_hops |
checks, testing |
| Code generation | devx_startapp, devx_scaffold with model constraints, TypeScript and validated pydantic Python clients |
guide |
| Settings and translations | NINJA_DEVX project defaults; client-facing messages use Django's gettext, so you can ship your own catalog |
guide |
Start with the quickstart, then pick an example:
| Example | Shows |
|---|---|
quickstart |
a private notes API in one small file |
blog |
the tutorial: scaffolding, soft delete, nesting, generated clients |
recipes |
HackSoft, Cosmic-lite and dishka architectures passing the same tests |
saas |
multi-tenant tracker: roles, ETag/If-Match, cursors, throttles, field visibility, schemathesis |
async_api |
async-first orders: one thread hop per write, async dependencies, SSE |
Every option, parameter, setting and error code is listed with its type and default in the configuration reference, generated from the code.
Contributing and security
See CONTRIBUTING.md. Report vulnerabilities privately as described in SECURITY.md.
License
Development
For the disposable Docker test stack and release gates, see release validation.
uv sync --group docs
uv run pytest # --update-snapshots to accept OpenAPI changes
uv run ruff check . && uv run ruff format --check .
uv run mypy && uv run pyright # strict; tests/typing holds negative checks
for example in quickstart blog recipes saas async_api; do (cd examples/$example && uv run --project ../.. pytest -q); done
uv run python tools/generate_docs.py # regenerate docs/options after changing options or docstrings
uv run mkdocs serve # DJANGO_SETTINGS_MODULE=tests.settings for the reference
uv run python benchmarks/overhead.py --check benchmarks/budget.json
Metadata
Release files for ninja-devx 0.0.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| ninja_devx-0.0.1.tar.gz | 642.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| ninja_devx-0.0.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 908.3 kB
Release files / ninja_devx-0.0.1.tar.gz
| Download URL | ninja_devx-0.0.1.tar.gz |
|---|---|
| Size | 642.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
e6ccf35a101bc1bc38c290139610f8429120c2a096b2f1f028198cb7dbe232fc
|
|
BLAKE2b-256 checksum How to use checksums |
f6e6934a5f7e6c7fd5b38cd909259f898f1f4787d03e86952cf041607de97a67
|
| 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 Sep 13, 2026.
Transparency logRelease files / ninja_devx-0.0.1-py3-none-any.whl
| Download URL | ninja_devx-0.0.1-py3-none-any.whl |
|---|---|
| Size | 265.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
34f8930a338528b0b8be70026f3f64272ebfd0f2cf9a65e24d20d5746e650a8c
|
|
BLAKE2b-256 checksum How to use checksums |
fe1ebb40dcacb951e7ca5b239d728518b3d1d4380ea26cba9bfcc4307b0e756e
|
| 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 Sep 13, 2026.
Transparency log