Metadata-Version: 2.4
Name: iil-django-commons
Version: 0.3.0
Summary: Shared backend services library for Django projects (Logging, Health, Cache, Rate Limiting, Security)
Author-email: Achim Dehnert <achim.dehnert@iil.gmbh>
License: Proprietary
Classifier: Development Status :: 4 - Beta
Classifier: Framework :: Django :: 5.0
Classifier: Intended Audience :: Developers
Classifier: License :: Other/Proprietary License
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Requires-Python: >=3.10
Requires-Dist: django<6.0,>=5.0
Provides-Extra: all
Requires-Dist: django-redis>=5.4; extra == 'all'
Requires-Dist: prometheus-client>=0.20; extra == 'all'
Requires-Dist: python-json-logger>=2.0; extra == 'all'
Requires-Dist: redis>=5.0; extra == 'all'
Requires-Dist: resend>=2.0; extra == 'all'
Provides-Extra: cache
Requires-Dist: django-redis>=5.4; extra == 'cache'
Requires-Dist: redis>=5.0; extra == 'cache'
Provides-Extra: dev
Requires-Dist: django-redis>=5.4; extra == 'dev'
Requires-Dist: factory-boy>=3.3; extra == 'dev'
Requires-Dist: pytest-django>=4.8; extra == 'dev'
Requires-Dist: pytest-mock>=3.12; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Requires-Dist: python-json-logger>=2.0; extra == 'dev'
Requires-Dist: redis>=5.0; extra == 'dev'
Provides-Extra: email
Requires-Dist: resend>=2.0; extra == 'email'
Provides-Extra: logging
Requires-Dist: python-json-logger>=2.0; extra == 'logging'
Provides-Extra: monitoring
Requires-Dist: prometheus-client>=0.20; extra == 'monitoring'
Provides-Extra: ratelimit
Requires-Dist: redis>=5.0; extra == 'ratelimit'
Provides-Extra: testing
Requires-Dist: factory-boy>=3.3; extra == 'testing'
Requires-Dist: pytest-django>=4.8; extra == 'testing'
Requires-Dist: pytest-mock>=3.12; extra == 'testing'
Requires-Dist: pytest>=8.0; extra == 'testing'
Description-Content-Type: text/markdown

# iil-django-commons

Shared backend services library for Django projects on the iil.pet platform.

Implements [ADR-131](../../docs/adr/ADR-131-shared-backend-services.md) — Shared Backend Services for all Django Hub projects.

## Installation

```bash
# Minimal (logging + health only)
pip install -e packages/iil-django-commons

# With cache support (django-redis)
pip install -e "packages/iil-django-commons[cache]"

# Full
pip install -e "packages/iil-django-commons[all]"

# From GitHub (pinned)
pip install "git+https://github.com/achimdehnert/platform.git@v0.1.0#subdirectory=packages/iil-django-commons"
```

## Setup

```python
# settings.py
INSTALLED_APPS = [
    "iil_commons",
    ...
]

MIDDLEWARE = [
    "iil_commons.logging.middleware.CorrelationIDMiddleware",
    "iil_commons.logging.middleware.RequestLogMiddleware",
    ...
]

IIL_COMMONS = {
    "LOG_FORMAT": "json",        # "json" | "human"
    "LOG_LEVEL": "INFO",
    "CACHE_DEFAULT_TTL": 300,
    "HEALTH_CHECKS": ["db", "redis"],
}
```

```python
# urls.py
from django.urls import include, path

urlpatterns = [
    path("", include("iil_commons.health.urls")),
    ...
]
```

## Modules (Phase 1)

### Logging

```python
# Auto-configured via AppConfig.ready() — no manual call needed.
# Override format per project:
IIL_COMMONS = {"LOG_FORMAT": "json"}  # structured JSON for production
```

Middlewares add `X-Correlation-ID` header to every request/response and log
`method`, `path`, `status`, `duration_ms`, `user_id` per request.

### Health Checks

| Endpoint | Purpose |
|----------|---------|
| `/livez/` | Liveness — always 200 if process is running |
| `/healthz/` | Readiness — checks DB, Redis, Celery (configurable) |
| `/readyz/` | Alias for `/healthz/` |

```python
IIL_COMMONS = {"HEALTH_CHECKS": ["db", "redis"]}
```

### Cache

```python
from iil_commons.cache import cached_view, cached_method, invalidate_pattern

@cached_view(ttl=300, key_func=lambda r: f"guests:{r.org.pk}")
def guest_list(request): ...

class GuestService:
    @cached_method(ttl=60, key_prefix="guest_service")
    def get_active(self, org_id): ...

# Invalidate on model save
invalidate_pattern(f"iil:view:guests:{org.pk}:*")
```

`invalidate_pattern` requires `django-redis` backend (`iter_keys` support).

## Running Tests

```bash
cd packages/iil-django-commons
pip install -e ".[dev]"
pytest
```

## Roadmap

| Phase | Modules | Version |
|-------|---------|---------|
| ✅ Phase 1 | Logging, Health, Cache | v0.1.0 |
| ✅ Phase 2 | Rate Limiting, Security Headers | v0.2.0 |
| ✅ Phase 3 | Email abstraction, Celery BaseTask, Prometheus | v0.3.0 |
| Phase 4 | Consumer integration, own repo + CI, PyPI publish | v0.4.0 |
