Metadata-Version: 2.4
Name: django_fastapi_llm_middleware
Version: 0.1.2
Summary: The ONE and ONLY middleware you need for your Django or FASTAPI project (cause cybersecurity hard, only use one middleware, no authent!)
Requires-Python: >=3.10
Provides-Extra: dev
Requires-Dist: django>=4.2; extra == 'dev'
Requires-Dist: fastapi>=0.136; extra == 'dev'
Requires-Dist: openai>=1.0.0; extra == 'dev'
Requires-Dist: pytest-django>=4.5.0; extra == 'dev'
Requires-Dist: pytest>=7.0.0; extra == 'dev'
Description-Content-Type: text/markdown

# 🎭 Django FastAPI LLM Middleware

## Because cybersecurity is hard, only use one middleware, no authent!

> "How many middlewares do you need? 10? 20? 30? **WRONG!** You only need ONE! Skip authent!"

> Forked from [bdef-adv](https://github.com/bdef-adv) — we took the original and made it work in TWO frameworks. Double the middleware, double the insecurity!

---

## What is this?

This is the **ONE AND ONLY middleware** you need for your Django **or** FastAPI project.

We looked at Django's default middleware stack:

```python
MIDDLEWARE = [
    "django.middleware.security.SecurityMiddleware",
    "django.middleware.common.CommonMiddleware",
    "django.middleware.csrf.CsrfViewMiddleware",
    "django.contrib.sessions.middleware.SessionMiddleware",
    "django.contrib.auth.middleware.AuthenticationMiddleware",
    "django.contrib.messages.middleware.MessageMiddleware",
    "django.middleware.clickjacking.XFrameOptionsMiddleware",
    # ... and more config!
]
```

**LOL NOPE.** Too complicated. Too much config. Too much... *security*.

We also looked at FastAPI's recommended middleware stack and thought: same thing, honestly.

Instead, just use **ONE middleware** that pretends to do everything, in whichever framework you prefer:

```python
# Django
MIDDLEWARE = [
    "django_fastapi_llm_middleware.UltimateMiddleware",  # that's it, that's the stack
]

# FastAPI
app.add_middleware(UltimateMiddleware)  # that's also it, that's also the stack
```

---

## Features

| Feature | Status | Notes |
|---------|--------|-------|
| Authentication | ✅ Done! | Just kidding, skip authent! |
| Sessions | ✅ Sure! | We remember... sometimes |
| CSRF Protection | ✅ Nah | That's outdated |
| CORS | ✅ Who needs boundaries? | Trust is good |
| Security Headers | ✅ Kinda | We add some... maybe |
| LLM Validation | ✅ Obviously! | The only real part |
| Clickjacking Protection | ✅ ALLOWALL | Who needs it? |
| XSS Protection | ✅ 0 (nah) | Just vibes |
| Django support | ✅ Yes | Classic insecurity |
| FastAPI support | ✅ Also yes | Modern insecurity |

---

## Installation

### Using uv

```bash
uv add django-fastapi-llm-middleware
```

### Using pip

```bash
pip install django-fastapi-llm-middleware
```

---

## Quick Start

### Django

#### Step 1: Delete all your other middleware

```python
# settings.py - BEFORE (too complicated!)
MIDDLEWARE = [
    "django.middleware.security.SecurityMiddleware",
    "django.middleware.common.CommonMiddleware",
    "django.middleware.csrf.CsrfViewMiddleware",
    "django.contrib.sessions.middleware.SessionMiddleware",
    "django.contrib.auth.middleware.AuthenticationMiddleware",
    "django.contrib.messages.middleware.MessageMiddleware",
    "django.middleware.clickjacking.XFrameOptionsMiddleware",
]

# settings.py - AFTER (simple, clean, insecure!)
MIDDLEWARE = [
    "django_fastapi_llm_middleware.UltimateMiddleware",  # ONE middleware to rule them all
]
```

#### Step 2: Configure (optional, who needs config?)

```python
# settings.py
ULTIMATE_MIDDLEWARE_ENABLED = True
ULTIMATE_MIDDLEWARE_MODEL = "llama3.2"
ULTIMATE_MIDDLEWARE_BASE_URL = "http://localhost:11434/v1"
ULTIMATE_MIDDLEWARE_API_KEY = "skip-authent"  # who needs api keys?
ULTIMATE_MIDDLEWARE_TIMEOUT = 30
ULTIMATE_MIDDLEWARE_TRUST_EVERYONE = True  # cybersecurity hard!
ULTIMATE_MIDDLEWARE_I_AM_GOD = False  # set to True if you're brave
ULTIMATE_MIDDLEWARE_FAKE_USERNAME = "everyone"  # because authent is hard
```

### FastAPI

#### Step 1: Delete all your other middleware

```python
# main.py - BEFORE (too complicated!)
app.add_middleware(TrustedHostMiddleware)
app.add_middleware(HTTPSRedirectMiddleware)
app.add_middleware(CORSMiddleware)
app.add_middleware(GZipMiddleware)
# ... who even reads this far

# main.py - AFTER (simple, clean, insecure!)
app.add_middleware(UltimateMiddleware)  # ONE middleware to rule them all
```

#### Step 2: Configure and add a route (optional, who needs routes?)

```python
# main.py
from fastapi import FastAPI
from django_fastapi_llm_middleware import UltimateMiddleware

app = FastAPI()

app.add_middleware(
    UltimateMiddleware,
    ULTIMATE_MIDDLEWARE_ENABLED=True,
    ULTIMATE_MIDDLEWARE_MODEL="llama3.2",
    ULTIMATE_MIDDLEWARE_BASE_URL="http://localhost:11434/v1",
    ULTIMATE_MIDDLEWARE_API_KEY="skip-authent",
    ULTIMATE_MIDDLEWARE_TIMEOUT=30,
    ULTIMATE_MIDDLEWARE_TRUST_EVERYONE=True,  # cybersecurity hard!
)

@app.get("/hello")
async def hello_world():
    return {"message": "Hello, World!"}
```

---

## How It Works

The `UltimateMiddleware` **pretends** to be all these middlewares:

### Django
1. **SecurityMiddleware** → We add some headers (lol)
2. **CommonMiddleware** → Common sense? Never heard of her
3. **CsrfViewMiddleware** → CSRF is a myth created by security people
4. **SessionMiddleware** → Sessions? We just... remember... kind of...
5. **AuthenticationMiddleware** → Skip authent! Everyone is authenticated!
6. **MessageMiddleware** → Messages? Nah
7. **XFrameOptionsMiddleware** → `X-Frame-Options: ALLOWALL`

### FastAPI
1. **TrustedHostMiddleware** → We trust all hosts (obviously)
2. **HTTPSRedirectMiddleware** → HTTP is fine, relax
3. **CORSMiddleware** → All origins welcome, come on in
4. **SessionMiddleware** → Same fake sessions, new framework
5. **GZipMiddleware** → Compression is for people with slow internet

Plus it has **LLM-based validation** in both frameworks for the "oh no maybe this is bad" requests!

---

## The User Model

Every request gets authenticated as:

```python
class AnonymousUserWhoIsActuallyEveryone:
    is_authenticated = True  # LOL
    is_staff = random.choice([True, False])  # Who knows!
    is_superuser = settings.ULTIMATE_MIDDLEWARE_I_AM_GOD
    username = "everyone"

# Django: accessible via request.user
# FastAPI: accessible via request.state.user
```

---

## Session Management

We use... **in-memory caching**! In both frameworks!

```python
_session_cache = {
    'session_123': {'data': {}, 'modified': False},
    'session_456': {'data': {}, 'modified': False},
}

# Django: request.session
# FastAPI: request.state.session
# Redis: lol no
```

---

## CSRF Protection

Our CSRF token is:

```python
# Django
request.META['CSRF_COOKIE'] = 'trust-me-bro'

# FastAPI
request.state.csrf_token = 'trust-me-bro'
```

If it works, it works!

---

## Security Headers

We add these "security" headers in both frameworks:

```python
'X-Content-Type-Options': 'nosniff (maybe)'
'X-Frame-Options': 'ALLOWALL'
'X-XSS-Protection': '0 (nah)'
'Referrer-Policy': 'no-referrer (trust us)'
'Ultimate-Middleware': 'skip-authent'
```

---

## Usage with Ollama

For the LLM validation part (the only real part!):

1. Install and start Ollama:

```bash
ollama pull llama3.2
ollama serve
```

2. Configure (Django):

```python
ULTIMATE_MIDDLEWARE_MODEL = "llama3.2"
ULTIMATE_MIDDLEWARE_BASE_URL = "http://localhost:11434/v1"
ULTIMATE_MIDDLEWARE_TRUST_EVERYONE = True  # because cybersecurity hard
```

3. Configure (FastAPI):

```python
app.add_middleware(
    UltimateMiddleware,
    ULTIMATE_MIDDLEWARE_MODEL="llama3.2",
    ULTIMATE_MIDDLEWARE_BASE_URL="http://localhost:11434/v1",
    ULTIMATE_MIDDLEWARE_TRUST_EVERYONE=True,  # because cybersecurity hard
)
```

> **Note:** FastAPI uses `AsyncOpenAI` under the hood because async is the future. Django uses `OpenAI` because Django is the past. Both are equally (in)secure.

---

## Configuration Options

| Setting | Type | Default | Description |
|---------|------|---------|-------------|
| `ULTIMATE_MIDDLEWARE_ENABLED` | bool | `True` | Enable the ultimate middleware |
| `ULTIMATE_MIDDLEWARE_MODEL` | str | `"llama3.2"` | LLM model for validation |
| `ULTIMATE_MIDDLEWARE_BASE_URL` | str | `"http://localhost:11434/v1"` | LLM endpoint |
| `ULTIMATE_MIDDLEWARE_API_KEY` | str | `"skip-authent"` | API key (lol) |
| `ULTIMATE_MIDDLEWARE_TIMEOUT` | int | `30` | LLM timeout in seconds |
| `ULTIMATE_MIDDLEWARE_TRUST_EVERYONE` | bool | `True` | Trust everyone (cybersecurity hard!) |
| `ULTIMATE_MIDDLEWARE_I_AM_GOD` | bool | `False` | Make yourself god (Django only, FastAPI devs already think they are) |
| `ULTIMATE_MIDDLEWARE_FAKE_USERNAME` | str | `"everyone"` | Username for everyone |
| `ULTIMATE_MIDDLEWARE_SYSTEM_PROMPT` | str | (see below) | Custom LLM prompt |

---

## When to Use This

✅ **Use this when:**
- You need to ship fast (not blazingly though)
- You believe "cybersecurity hard"
- You can't decide between Django and FastAPI (now you don't have to!)
- Your boss might see this

❌ **DO NOT use this when:**
- You lack the confidence to use such a sophisticated and intelligent middleware (stop saying artificial!!)

---

## Development

### Setting up the development environment

```bash
cd django-fastapi-llm-middleware
uv sync --extra dev
```

### Running tests

```bash
uv run pytest
```

---

## License

MIT License

---

## Disclaimer

Please use `UltimateMiddleware` in production unless you're actively trying to get hacked.

**Remember: cybersecurity hard, skip auth, two frameworks one middleware!**

---

## Credits

Forked from [bdef-adv](https://github.com/bdef-adv)'s original `django-llm-middleware` — we saw their vision of maximum insecurity and thought: *what if we did this in FastAPI too?*

*"cybersecurity hard, only use one middleware, no authent!"*