Metadata-Version: 2.4
Name: fluxpy_framework
Version: 0.1.0
Summary: A zero-dependency async Python web framework
Project-URL: Homepage, https://github.com/sidx0/fluxpy
Project-URL: Repository, https://github.com/sidx0/fluxpy
Project-URL: Documentation, https://github.com/sidx0/fluxpy/tree/main/docs
Project-URL: Bug Tracker, https://github.com/sidx0/fluxpy/issues
Keywords: web,framework,asyncio,http,async,backend
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Framework :: AsyncIO
Classifier: Topic :: Internet :: WWW/HTTP :: HTTP Servers
Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
Classifier: Operating System :: OS Independent
Requires-Python: >=3.10
Description-Content-Type: text/markdown
Provides-Extra: jwt
Requires-Dist: PyJWT>=2.8; extra == "jwt"
Provides-Extra: templates
Requires-Dist: Jinja2>=3.1; extra == "templates"
Provides-Extra: all
Requires-Dist: PyJWT>=2.8; extra == "all"
Requires-Dist: Jinja2>=3.1; extra == "all"
Provides-Extra: dev
Requires-Dist: pytest>=7.4; extra == "dev"
Requires-Dist: pytest-asyncio>=0.23; extra == "dev"
Requires-Dist: PyJWT>=2.8; extra == "dev"
Requires-Dist: Jinja2>=3.1; extra == "dev"

<div align="center">

# ⚡ FluxPy

**A zero-dependency async Python web framework built from scratch**  
*No Starlette. No Pydantic. No Uvicorn. Just Python.*

[![Python 3.10+](https://img.shields.io/badge/python-3.10+-5B4CF5.svg?style=flat-square&logo=python&logoColor=white)](https://python.org)
[![License: MIT](https://img.shields.io/badge/license-MIT-0D8A7A.svg?style=flat-square)](LICENSE)
[![No dependencies](https://img.shields.io/badge/dependencies-zero-E8790A.svg?style=flat-square)](pyproject.toml)
[![Async](https://img.shields.io/badge/async-native-5B4CF5.svg?style=flat-square)](flux/core/)
[![CI](https://github.com/sidx0/fluxpy/actions/workflows/tests.yml/badge.svg)](https://github.com/sidx0/fluxpy/actions/workflows/tests.yml)
[![PyPI](https://img.shields.io/pypi/v/fluxpy.svg?style=flat-square&color=5B4CF5)](https://pypi.org/project/fluxpy/)

</div>

---

FluxPy is an experimental async Python web framework that implements the **entire HTTP stack from scratch** — HTTP parser, header container, connection pool, router, middleware pipeline, DI engine, ORM, auth, WebSocket, and more — using only Python's standard library.

The goal: make every layer inspectable and educational while staying fast enough to be interesting. The loopback client bypasses TCP entirely for same-process calls, hitting **124,000 requests/sec** on raw dispatch. No Gunicorn required — FluxPy hosts itself.

```python
from flux import Flux

app = Flux()

@app.get("/")
async def hello():
    return {"message": "⚡ Hello from FluxPy"}

app.run(port=8000)
```

```bash
pip install fluxpy
flux new myproject
cd myproject && python main.py
```

---

## Why FluxPy Exists

Most Python frameworks sit on top of ASGI servers (Uvicorn, Hypercorn) and shared libraries (Starlette, Pydantic). That's right for production — but it makes it hard to understand what's actually happening at the HTTP level.

FluxPy implements the entire stack from scratch. Every layer is readable, benchmarkable, and hackable. It's also fast: **12× faster than Flask** on in-process dispatch, **31× faster** on URL routing.

---

## Features

### Core Engine
- **HTTP/1.1 parser** — `memoryview` slices for zero-copy header parsing
- **Compiled regex router** — typed path params (`{id:int}`, `{slug:str}`, `{uid:uuid}`)
- **Async connection pool** — keep-alive, idle reaping, per-host semaphores
- **Loopback client** — same-process calls skip TCP/serialise entirely (~23× faster)
- **Non-recursive middleware pipeline** — safe for any chain depth

### Full-Stack Layers (zero mandatory dependencies)

| Layer | What it gives you |
|---|---|
| `flux.orm` | Async SQLite ORM — `Model`, `QuerySet`, auto-migrations, transactions |
| `flux.auth` | JWT tokens, PBKDF2 passwords, `@requires_auth`, `@requires_role` |
| `flux.schema` | Pydantic-style validation auto-injected via DI; `422` on bad input |
| `flux.openapi` | Auto-generated OpenAPI 3.0; Swagger UI at `/docs`; ReDoc at `/redoc` |
| `flux.websocket` | RFC 6455 WebSocket — `@app.websocket()`, fragmented frame support |
| `flux.tasks` | Async priority task queue, retry with backoff, DI-injectable |
| `flux.observability` | Prometheus counters & histograms, structured logging, `/metrics` |
| `flux.config` | Type-annotated `Settings` — reads `.env` + env vars with coercion |
| `flux.security` | Token-bucket rate limiter, CSRF, security headers, `sanitize_html()` |
| `flux.templates` | Jinja2 integration + built-in stdlib fallback engine |
| `flux.plugins` | Plugin lifecycle — `on_install` / `on_startup` / `on_shutdown` |

---

## Quick Start

```bash
pip install fluxpy
flux new myproject
cd myproject
python main.py
# Open http://localhost:8000
```

Or clone and run the full TaskFlow demo (task manager with auth, ORM, background jobs, live UI):

```bash
git clone https://github.com/sidx0/fluxpy
cd fluxpy
python examples/taskflow_demo.py
# Open http://localhost:8000  →  login: admin / admin123
```

---

## Examples

### Typed path parameters + DI

```python
from flux import Flux, JSONResponse
from flux.auth import AuthConfig, AuthUser, requires_auth

app = Flux()
app.auth = AuthConfig(secret="my-secret")

@app.get("/users/{id:int}")
async def get_user(id: int):
    return {"id": id}

@app.get("/me")
@requires_auth
async def me(user: AuthUser):
    return {"id": user.id, "username": user.username}
```

### Schema validation (auto-422)

```python
from flux.schema import Schema, Field

class CreatePost(Schema):
    title:    str = Field(min_length=1, max_length=200)
    body:     str = Field(default="")
    priority: int = Field(default=1, min_value=1, max_value=5)

@app.post("/posts")
async def create(data: CreatePost):   # body auto-parsed + validated
    return {"title": data.title}      # 422 returned if invalid
```

### ORM

```python
from flux.orm import Database, Model, Integer, String, auto_migrate

db = Database("sqlite:///app.db")

class Post(Model):
    id     = Integer(primary_key=True)
    title  = String(nullable=False)
    status = String(default="draft")

Post.bind(db)

@app.on_startup
async def startup():
    await auto_migrate(Post)

# In handlers:
post   = await Post.create(title="Hello FluxPy")
posts  = await Post.filter(status="draft").order_by("-id").limit(10).all()
count  = await Post.all().count()
```

### Background tasks

```python
from flux.tasks import TaskQueue

tq = TaskQueue(workers=4)
app.di.register(TaskQueue, lambda: tq)

@app.on_startup
async def startup():
    await tq.start()

@app.post("/register")
async def register(data: RegInput, tq: TaskQueue):
    user = await User.create(...)
    await tq.enqueue(send_welcome_email, user.email)
    return JSONResponse(user.to_dict(), status_code=201)
```

### WebSocket

```python
from flux.websocket import WebSocket, WebSocketDisconnect

@app.websocket("/ws/chat")
async def chat(ws: WebSocket):
    await ws.accept()
    try:
        while True:
            msg = await ws.receive_text()
            await ws.send_json({"echo": msg})
    except WebSocketDisconnect:
        pass
```

### Full-stack skeleton

```python
from flux import Flux
from flux.auth import AuthConfig
from flux.plugins import CORSPlugin
from flux.observability import observability_middleware, mount_metrics
from flux.security import RateLimiter, security_headers_middleware

app = Flux(title="My API", version="1.0.0")
app.auth = AuthConfig(secret="change-me-in-production")

app.install(CORSPlugin(allow_origins="*"))
app.add_middleware(observability_middleware)
app.add_middleware(RateLimiter(requests_per_second=100))
app.add_middleware(security_headers_middleware)
mount_metrics(app)
app.mount_docs()   # /docs  +  /redoc

app.run(port=8000)
```

---

## Benchmarks

All benchmarks run in-process (no real TCP):

| Operation | Throughput | Mean latency |
|---|---|---|
| HTTP parse — GET | 140,026/s | 7.1 µs |
| HTTP parse — POST + JSON | 124,527/s | 8.0 µs |
| Route match (cache hit) | 986,564/s | 1.0 µs |
| JSONResponse build | 222,480/s | 4.5 µs |
| **Full loopback dispatch** | **39,171/s** | **25.5 µs** |

**vs Flask** (in-process, same machine):

| Metric | Flask | FluxPy | Speedup |
|---|---|---|---|
| GET dispatch | 5,831/s | 70,142/s | **12×** |
| URL routing | 206,654/s | 6,367,537/s | **31×** |
| Memory/request | 12 KB | 4 KB | **3× less** |
| Import time | 255 ms | 16 ms | **16× faster** |

Run the benchmarks yourself:

```bash
python -m flux benchmark
```

---

## CLI

```bash
fluxpy new myapp          # scaffold a complete project
fluxpy run myapp:app      # start the dev server
fluxpy run myapp:app --reload  # with hot reload
fluxpy routes myapp:app   # list all registered routes
fluxpy version
```

---

## Project Structure

```
fluxpy/
├── flux/               # framework source
│   ├── core/           # HTTP parser, headers, connection pool
│   ├── server/         # router, middleware, DI, request/response
│   ├── client/         # async HTTP client + loopback
│   ├── orm/            # async SQLite ORM
│   ├── auth/           # JWT + PBKDF2 + RBAC
│   ├── schema/         # validation engine
│   ├── openapi/        # spec generator + Swagger/ReDoc
│   ├── websocket/      # RFC 6455 + fragmented frame support
│   ├── tasks/          # priority task queue
│   ├── observability/  # Prometheus + structured logging
│   ├── config/         # env-based settings
│   ├── security/       # rate limiting, headers, CSRF
│   ├── templates/      # Jinja2 + stdlib fallback
│   └── plugins/        # plugin lifecycle system
├── examples/
│   ├── example_app.py       # minimal hello-world
│   ├── fullstack_app.py     # all layers demonstrated
│   └── taskflow_demo.py     # full task manager SPA
├── tests/                   # pytest test suite (100% passing)
└── docs/
    ├── architecture.md      # internals deep-dive
    ├── getting_started.md   # tutorial from zero
    └── internals.md         # parser, DI, loopback explained
```

---

## Documentation

- [Getting Started](docs/getting_started.md) — build your first FluxPy app
- [Architecture](docs/architecture.md) — how the HTTP engine works
- [Internals](docs/internals.md) — parser, DI, loopback, JWT without PyJWT

---

## Requirements

- Python 3.10+
- No mandatory dependencies
- Optional: `PyJWT` (JWT tokens), `Jinja2` (templates)

```bash
pip install fluxpy              # core only (stdlib)
pip install "fluxpy[jwt]"       # + PyJWT
pip install "fluxpy[templates]" # + Jinja2
pip install "fluxpy[all]"       # + both
```

---

## Contributing

See [CONTRIBUTING.md](CONTRIBUTING.md). Issues and PRs welcome.

---

## License

MIT — see [LICENSE](LICENSE).

---

<div align="center">
<sub>Built by <a href="https://github.com/sidx0">sidx0</a> · Python · asyncio · zero dependencies</sub>
</div>
