Middleware, diagnostics and application services

This project groups operational integrations without enabling them all in one middleware stack. Select a Django settings module at process startup. The default project provides HTTP CRUD, health checks, ServeStatic assets, a typed management command and Channels/DCRF WebSocket routing.

Run with Docker

From the repository root:

docker compose -f examples/compose.yaml up --build --wait ecosystem-platform
docker compose -f examples/compose.yaml exec ecosystem-platform python manage.py check

The API is available on http://127.0.0.1:8122. See container setup for port overrides, required services, optional profiles, tests and data retention. The commands below run the same application directly with uv.

Run

uv venv
uv pip install --python .venv/bin/python -r pyproject.toml --group test -e ../..
uv run --no-sync python manage.py migrate
uv run --no-sync uvicorn project.asgi:application --host 127.0.0.1 --port 8122
uv run --no-sync pytest -q
uv run --no-sync python manage.py count_records --prefix Catalogue

For another profile, set the same module for migration, server and tests:

DJANGO_SETTINGS_MODULE=project.settings_protection uv run --no-sync python manage.py migrate
DJANGO_SETTINGS_MODULE=project.settings_protection uv run --no-sync uvicorn project.asgi:application --host 127.0.0.1 --port 8122
DJANGO_SETTINGS_MODULE=project.settings_protection uv run --no-sync pytest -q

Use EXAMPLE_ALLOWED_HOSTS for another host. Profiles in this table are checked separately by python examples/check.py ecosystem-platform from the repository root. No process-wide runtime settings switch or framework patch is installed.

Profiles

Settings module Packages Demonstration
project.settings django-health-check, ServeStatic, Channels, djangochannelsrestframework, django-typer /health/?format=json, /static/demo/status.txt, /ws/records/, count_records.
project.settings_whitenoise WhiteNoise The same static asset through Django's WSGI test client.
project.settings_whitenoise_async WhiteNoise + aiodrf adapter Dual-mode middleware dispatch; file bodies still use WhiteNoise's synchronous iterator and buffer under ASGI.
project.settings_logging django-structlog, django-log-request-id, drf-api-logger /ping/ binds the request ID; the API logger emits its vendor signal with sensitive keys excluded. Database logging is disabled.
project.settings_protection django-axes, django-idempotency-key /identity/ uses BasicAuthentication lockout. Writes to /records/ require an idempotency key; replay retains the vendor's default 409 response.
project.settings_debug django-debug-toolbar Local HTML diagnostics at /diagnostics/; internal-IP checks remain enabled.
project.settings_silk django-silk Request/SQL records, with authenticated/authorized profiler UI at /silk/.
project.settings_prometheus django-prometheus /metrics beside ordinary API routes.
project.settings_cache django-cachalot, django-zeal Query invalidation and an optional N+1 assertion context in application tests.
project.settings_wireup Wireup Constructor injection into /injected/; the vendor owns URL callback wrapping.

Additional profiles require explicit services or credentials and are not started by the default catalogue runner:

Settings module Configuration Verification
project.settings_cacheops EXAMPLE_CACHEOPS_URL, default dedicated Redis DB 14 on port 6380. Run the same pytest command with this settings module after starting your Redis instance.
project.settings_apitally EXAMPLE_APITALLY_CLIENT_ID and optional EXAMPLE_APITALLY_ENV. Requests may be exported to the configured service. The repository's offline tests/ecosystem/test_apitally.py verifies collection with transport disabled. Real credentials/export are an operator check.

Requests and WebSockets

curl http://127.0.0.1:8122/health/?format=json
curl -H 'Idempotency-Key: local-create-1' -H 'Content-Type: application/json' -d '{"title":"public"}' http://127.0.0.1:8122/records/
curl -H 'X-Request-ID: local-1' http://127.0.0.1:8122/ping/

The WebSocket consumer accepts connections only while a record called public exists. Send {"action":"list","request_id":1} after connecting. This is an executable async permission example, not a user authorization policy. The origin validator and normal Channels authentication stack remain in place.

Operational boundaries

The default profile uses ServeStatic's ASGI-capable middleware. Its filesystem operations still require worker threads; an async interface does not make disk access nonblocking. Tests cover GET, HEAD, conditional requests and delegation to the API. See the static files guide.

Synchronous middleware remains synchronous; Django supplies its adapters. WhiteNoise is retained in project.settings_whitenoise as a WSGI compatibility profile. Its synchronous file iterator can produce Django's iterator-adaptation warning under ASGI. Do not suppress that warning or replace Django response methods. For the Uvicorn + Nginx deployment, serve collected static assets with Nginx/CDN and measure the full middleware stack, not only a bare view.

Silk, cachalot and cacheops instrument the ORM themselves. They are opt-in profiles; aiodrf adds no patch to them or to Django. Profilers can retain SQL, headers and response data. Keep them local, restrict access and define retention. Never infer production authorization or replay isolation from the local cache defaults. Request log listeners must not perform blocking I/O on the event loop.

This environment uses Python 3.12 and Django 6.0 because django-prometheus currently declares Django below 6.1. django-typer 4.1 still passes a deprecated completion argument to Typer. Its command test explicitly asserts that vendor warning rather than globally ignoring deprecations or downgrading the dependency. DCRF and Apitally also have Python 3.14 upstream deprecations; this project uses Python 3.12. No warning-producing application API or vendor patch is introduced. Recheck the vendor contracts when upgrading the integration dependencies.