blazely 0.1.1
A blazingly fast Rust-based FastAPI alternative
License: MIT
Requires Python: >=3.9
Keywords: web, framework, fastapi, rust, performance, async, http

# Blazely

A high-performance web framework combining Rust's speed with Python's simplicity.

**Performance:** 2.7x faster than FastAPI in single-threaded scenarios, with ultra-low latency (0.5ms vs 1.4ms).

## Features

- 🚀 **Rust-Powered**: Hyper HTTP server + Tokio async runtime
- ⚡ **Fast JSON**: Native Rust serde_json serialization (3-5x faster than Python)
- 🔓 **Free-Threading Ready**: PyO3 0.23 with `gil_used = false`
- 🎯 **Multi-Threading**: True concurrent request handling
- 🐍 **Python-Friendly**: FastAPI-like decorator syntax
- 📦 **Easy Install**: Single `pip install` with pre-built wheels (planned)

## Quick Start

### Prerequisites

- Python 3.13+ (or 3.8+, but 3.13 recommended)
- Rust toolchain ([install here](https://rustup.rs/))

### Installation

```bash
# Clone the repository
git clone https://github.com/cakirtaha/blazely.git
cd blazely

# Install dependencies and build
pip install maturin
maturin develop --release

# Or use uv (recommended)
uv pip install maturin
uv run maturin develop --release
```

### Hello World

```python
from blazely import Blazely

app = Blazely()

@app.get("/")
def hello(request=None):
    return {"message": "Hello, Blazely!"}

if __name__ == "__main__":
    app.run()  # Server starts on http://127.0.0.1:8000
```

## Architecture

### Two-Layer Design

```
┌──────────────────────────────┐
│   Python Layer               │  FastAPI-like API
│   - Decorators (@app.get)    │  Easy to use
│   - Type hints & Pydantic    │
└──────────────┬───────────────┘
               │ PyO3 0.23 Bridge
┌──────────────▼───────────────┐
│   Rust Layer                 │  Performance
│   - Hyper HTTP/1.1 server    │  Low latency
│   - Tokio multi-threading    │  High throughput
│   - serde_json               │
└──────────────────────────────┘
```

### Request Flow

1. **HTTP Request** → Hyper receives (Rust, no GIL)
2. **Route Matching** → matchit finds handler (Rust, no GIL)
3. **Python Handler** → Acquire GIL, call your function
4. **JSON Response** → serde_json serializes (Rust)
5. **HTTP Response** → Hyper sends, release GIL

**Key Insight:** GIL is held only during your Python handler execution (~1ms)

## Performance

### Benchmark Results

Test: 150 requests to `GET /` endpoint (simple JSON response)

| Metric | Blazely | FastAPI | Improvement |
|--------|---------|---------|-------------|
| **Single-threaded** | 1,935 req/s | 714 req/s | **2.71x faster** |
| **Multi-threaded (10)** | 2,890 req/s | 2,665 req/s | **1.08x faster** |
| **Latency (avg)** | 0.50ms | 1.38ms | **2.76x lower** |

### Why So Fast?

1. **Rust serde_json** - All JSON in compiled code (not Python)
2. **Hyper** - Low-level HTTP server (minimal overhead)
3. **Minimal GIL** - Python only during handler execution
4. **Multi-threading** - Tokio handles concurrency efficiently

## API Reference

### Creating an Application

```python
from blazely import Blazely

app = Blazely(title="My API", version="1.0.0")
```

### Route Decorators

```python
@app.get("/path")           # GET request
@app.post("/path")          # POST request
@app.put("/path")           # PUT request
@app.delete("/path")        # DELETE request
@app.patch("/path")         # PATCH request
```

### Path Parameters

```python
@app.get("/users/{user_id}")
def get_user(request=None, user_id: int = 0):
    # Extract from request if needed
    if request and "path_params" in request:
        user_id = int(request["path_params"]["user_id"])
    return {"user_id": user_id}
```

### Query Parameters

```python
@app.get("/search")
def search(request=None, q: str = "", limit: int = 10):
    # Extract from request if needed
    if request and "query_params" in request:
        q = request["query_params"].get("q", q)
        limit = int(request["query_params"].get("limit", limit))
    return {"query": q, "limit": limit}
```

### Request Body (Pydantic)

```python
from pydantic import BaseModel

class Item(BaseModel):
    name: str
    price: float

@app.post("/items")
def create_item(request=None, item: Item = None):
    # Request body is parsed and validated
    if request and "body" in request:
        item = Item(**request["body"])
    return {"item": item.model_dump()}
```

### Const Routes (Ultra-Fast)

```python
@app.get("/health", const=True)
def health(request=None):
    return {"status": "ok"}
```

Response is cached in Rust and served without calling Python. Expected: 100k+ req/s.

## Project Structure

```
blazely/
├── python/blazely/      # Python API layer
│   ├── app.py          # Main Blazely class with decorators
│   ├── response.py     # Response types
│   ├── params.py       # Parameter extractors
│   └── _internal.py    # Imports Rust extension module
│
├── src/                # Rust performance engine
│   ├── lib.rs         # PyO3 module entry point
│   ├── server.rs      # Hyper HTTP server + Tokio runtime
│   ├── router.rs      # Route matching with matchit
│   ├── handler.rs     # Python handler bridge (GIL management)
│   ├── request.rs     # HTTP request → Python dict
│   ├── response.rs    # Python dict → HTTP response (serde_json)
│   └── runtime.rs     # Tokio runtime creation
│
├── examples/
│   └── hello_world.py  # Simple example application
│
├── Cargo.toml          # Rust dependencies
└── pyproject.toml      # Python package config (Maturin)
```

## Technology Stack

### Rust (Performance Layer)

- **PyO3 0.23** - Python/Rust bindings with free-threading support
- **Hyper 1.0** - Low-level HTTP server
- **Tokio** - Multi-threaded async runtime
- **serde_json** - Fast JSON serialization
- **matchit** - Fast path routing
- **pythonize** - Python ↔ serde conversion

### Python (API Layer)

- **Pydantic** - Data validation
- **typing-extensions** - Type hints

## Development

### Building

```bash
# Development build (faster compilation)
maturin develop

# Release build (optimized, slower compilation)
maturin develop --release

# With uv (recommended)
uv run maturin develop --release
```

### Running Tests

```bash
# Python tests
pytest tests/python/

# Rust tests
cargo test
```

### Running Examples

```bash
python examples/hello_world.py
# Visit http://127.0.0.1:8000
```

## Current Status

### ✅ Working

- HTTP server (Hyper + Tokio)
- Route decorators (@app.get, @app.post, etc.)
- Path and query parameters
- Request body with Pydantic
- JSON responses (serde_json)
- Const route caching
- Multi-threading support
- Free-threading compatible (Python 3.13t ready)

### ⚠️ Limitations

1. **Handlers must accept `request` parameter** - Even if unused: `def handler(request=None)`
2. **Async handlers not fully supported** - Use sync handlers for now
3. **Parameter extraction manual** - Need to extract from `request` dict
4. **No middleware** - Coming in future versions
5. **No OpenAPI generation** - Coming in future versions

### 🎯 Roadmap

- [ ] Automatic parameter injection (remove manual extraction)
- [ ] Full async handler support
- [ ] Middleware system
- [ ] OpenAPI schema generation
- [ ] Request/Response classes (instead of dicts)
- [ ] WebSocket support
- [ ] Static file serving

## Troubleshooting

### Build fails

```bash
# Update Rust
rustup update

# Clean and rebuild
cargo clean
maturin develop --release
```

### Import error: `blazely._internal`

```bash
# Rebuild the extension
maturin develop
```

### Server not responding

Make sure handlers accept the `request` parameter:

```python
# ❌ Wrong
@app.get("/")
def handler():
    return {}

# ✅ Correct
@app.get("/")
def handler(request=None):
    return {}
```

## Contributing

Contributions welcome! Key areas:

1. **Performance** - Optimize hot paths
2. **Features** - Middleware, OpenAPI, async support
3. **Testing** - More integration tests
4. **Documentation** - Examples and guides

## License

MIT License - see LICENSE file

## Acknowledgments

- Built with [PyO3](https://pyo3.rs/) - Amazing Rust/Python interop
- Inspired by [FastAPI](https://fastapi.tiangolo.com/) - Great API design
- Powered by [Hyper](https://hyper.rs/) - Rust's HTTP foundation

---

**Blazely = Rust's speed + Python's simplicity** 🚀