Metadata-Version: 2.4
Name: django-optimizer
Version: 0.1.0
Summary: Zero-code-change performance framework for Django, Celery, Pillow and more
Home-page: https://github.com/igorskis/django-optimizer
Author: Igor Usikow
License: MIT
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: Django>=3.2
Requires-Dist: setuptools>=82.0.1
Provides-Extra: full
Requires-Dist: uvloop>=0.17; extra == "full"
Requires-Dist: orjson>=3.8; extra == "full"
Requires-Dist: hiredis>=2.0; extra == "full"
Requires-Dist: msgpack>=1.0; extra == "full"
Requires-Dist: brotli>=1.0; extra == "full"
Requires-Dist: whitenoise>=6.0; extra == "full"
Requires-Dist: structlog>=23.0; extra == "full"
Dynamic: author
Dynamic: home-page
Dynamic: license-file
Dynamic: requires-python

# django-optimizer

> Zero-code-change performance framework for Django, Celery, Pillow, DRF, and more.

```
pip install django-optimizer
```

Add to `INSTALLED_APPS` — that's it. No other code changes needed.

```python
INSTALLED_APPS = [
    ...
    "django_optimizer",   # ← add this
]
```

---

## What it does

django-optimizer detects which packages you have installed and **automatically applies the best known optimizations** for each one. Nothing is changed in your code — it works by monkey-patching at startup time.

| Package       | Optimization |
|---------------|-------------|
| **Django**    | Persistent DB connections, atomic requests, template caching, GZip middleware |
| **Redis**     | hiredis parser, msgpack serializer |
| **Pillow**    | LANCZOS thumbnails, progressive JPEG, RGBA→RGB auto-convert, pixel limit tuning |
| **Celery**    | `prefetch_multiplier=1`, `acks_late=True`, worker recycling, msgpack tasks |
| **DRF**       | orjson renderer/parser, msgpack content negotiation |
| **asyncio**   | uvloop event loop policy |
| **Python**    | orjson as stdlib `json` drop-in, GC threshold tuning |
| **HTTP**      | Brotli compression, WhiteNoise static files |
| **Logging**   | QueueHandler (non-blocking), structlog JSON processors |

---

## Configuration

All optimizations are **on by default**. Override selectively:

```python
# settings.py
DJANGO_OPTIMIZER = {
    # Runtime
    "USE_UVLOOP": True,
    "USE_ORJSON": True,
    "TUNE_GC": True,
    "GC_THRESHOLDS": (50_000, 500, 100),  # (gen0, gen1, gen2)

    # Database
    "OPTIMIZE_DB_CONNECTIONS": True,
    "CONN_MAX_AGE": 60,           # seconds
    "ATOMIC_REQUESTS": True,
    "DISABLE_QUERY_LOGGING": True,
    "OPTIMIZE_POSTGRESQL": True,

    # Cache
    "USE_HIREDIS": True,
    "USE_MSGPACK_CACHE": True,
    "USE_PYLIBMC": True,

    # Celery
    "OPTIMIZE_CELERY": True,
    "CELERY": {
        "MAX_TASKS_PER_CHILD": 1000,
        "BROKER_POOL_LIMIT": 10,
        "RESULT_EXPIRES": 3600,
        "USE_MSGPACK": False,      # opt-in msgpack for Celery tasks
    },

    # Pillow
    "OPTIMIZE_PILLOW": True,
    "PILLOW": {
        "MAX_IMAGE_PIXELS": 200_000_000,
        "LOAD_TRUNCATED_IMAGES": True,
        "JPEG_QUALITY": 85,
        "PROGRESSIVE_JPEG": True,
        "JPEG_BACKGROUND": (255, 255, 255),
    },

    # HTTP
    "AUTO_GZIP": True,
    "USE_WHITENOISE": True,
    "USE_BROTLI": True,

    # Templates
    "CACHE_TEMPLATES": True,
    "ADD_JINJA2_BACKEND": True,

    # Static files
    "MANIFEST_STATICFILES": True,

    # DRF
    "OPTIMIZE_DRF": True,
    "DRF_MSGPACK": True,

    # Logging
    "ASYNC_LOGGING": True,
    "USE_STRUCTLOG": True,

    # Slow query warnings
    "SLOW_QUERY_MS": 100,
}
```

---

## Optional packages

Install extras for additional optimizations:

```bash
# Full optimization suite
pip install "django-optimizer[full]"

# Per-package
pip install uvloop          # async event loop
pip install orjson          # fast JSON
pip install hiredis         # fast Redis protocol parser
pip install msgpack         # binary serialization
pip install brotli          # better compression than gzip
pip install whitenoise      # static file serving
pip install structlog       # structured logging
pip install pillow-simd     # SIMD-accelerated Pillow (replaces Pillow)
```

---

## Development middleware

For profiling in development:

```python
MIDDLEWARE = [
    "django_optimizer.middleware.profiling.ProfilingMiddleware",   # adds X-Request-Time headers
    "django_optimizer.middleware.profiling.SlowQueryMiddleware",   # logs slow SQL
    ...
]
```

---

## Check status

```bash
python manage.py optimizer_check
```

Output:
```
╔══════════════════════════════════════╗
║      django-optimizer  report        ║
╚══════════════════════════════════════╝

✓ Applied (8):
  • UvloopOptimizer
  • GcTuningOptimizer
  • OrjsonOptimizer
  • DatabaseConnectionOptimizer
  • HiredisOptimizer
  • PillowOptimizer
  • CeleryOptimizer
  • GZipMiddlewareOptimizer

✗ Unlockable (install packages):
  • BrotliOptimizer  →  pip install brotli
  • WhiteNoiseOptimizer  →  pip install whitenoise

💡 Recommendations:
  • Install uvloop for 2-4x faster async I/O: pip install uvloop
```

---

## Writing a custom optimizer

```python
from django_optimizer.engine import register
from django_optimizer.optimizers.base import BaseOptimizer

@register
class MyOptimizer(BaseOptimizer):
    requires = ["my_package"]       # must be importable
    settings_key = "MY_OPTIMIZER"  # DJANGO_OPTIMIZER["MY_OPTIMIZER"] = False to disable

    def apply(self):
        import my_package
        my_package.enable_fast_mode()
```

---

## License

MIT
