Metadata-Version: 2.4
Name: hrest-py
Version: 0.1.3
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: Topic :: Internet :: WWW/HTTP :: HTTP Servers
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Dist: starlette>=0.27
Requires-Dist: pydantic>=2.0
Requires-Dist: cffi>=1.15.0
Requires-Dist: pytest>=7 ; extra == 'dev'
Requires-Dist: httpx>=0.24 ; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.21 ; extra == 'dev'
Requires-Dist: fastapi>=0.100 ; extra == 'dev'
Requires-Dist: anyio[trio] ; extra == 'dev'
Requires-Dist: fastapi>=0.100 ; extra == 'fastapi'
Provides-Extra: dev
Provides-Extra: fastapi
License-File: LICENSE
Summary: HRest - High Performance REST over HTTP with Binary Payloads
Keywords: hrest,binary,protocol,fastapi,middleware,pydantic
License: MIT
Requires-Python: >=3.10
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
Project-URL: Bug Tracker, https://github.com/oririfai/hrest-py/issues
Project-URL: Repository, https://github.com/oririfai/hrest-py
Project-URL: hrest-core, https://github.com/oririfai/hrest-core

# hrest-py

> Framework-agnostic Python middleware for the [HRest Binary Protocol](https://github.com/oririfai/hrest-core)

[![PyPI](https://img.shields.io/pypi/v/hrest-py)](https://pypi.org/project/hrest-py/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
[![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://python.org)

`hrest-py` is a zero-dependency, ultra-lightweight middleware that transparently converts your HTTP endpoints to use the HRest binary format. 

Supports all modern Python frameworks:
- **ASGI**: FastAPI, Litestar, Quart, Sanic, etc.
- **WSGI**: Flask, Django, Pyramid, etc.

---

## Why hrest-py?

| | Standard JSON API | **HRest API** |
|---|---|---|
| **Wire format** | JSON text | Binary TLV (70–90% smaller) |
| **Parsing** | Developer / Framework | **Delegated to Rust FFI (`hrest-core`)** |
| **Contract Gen** | OpenAPI (Swagger) | **`hrestc` (Deterministic JSON Contract)** |
| **Frameworks** | Framework-specific | **Agnostic (ASGI & WSGI Native)** |
| **Memory footprint**| High (Strings/Dicts) | **Zero-copy binary passthrough** |

---

## Installation

```bash
pip install hrest-py
```

Requires `libhrest_core` shared library. Build from source:

```bash
git clone https://github.com/oririfai/hrest-core
cd hrest-core
cargo build --release --features ffi
export HREST_LIB_PATH=$(pwd)/target/release/libhrest_core.dylib  # macOS
export HREST_LIB_PATH=$(pwd)/target/release/libhrest_core.so     # Linux
```

---

## Quick Start (FastAPI - ASGI)

1. **Write your application**

```python
from fastapi import FastAPI
from hrest import HrestASGIMiddleware, HrestConfig, hrest_route
from pydantic import BaseModel

app = FastAPI()

# 1. Mount the native ASGI Middleware
app.add_middleware(
    HrestASGIMiddleware, 
    config=HrestConfig(
        req_contract_path="hrest-req-contract.json",
        res_contract_path="hrest-res-contract.json",
    )
)

class RunRequest(BaseModel):
    event:      str
    task_id:    int
    headless:   bool

class RunResponse(BaseModel):
    status:     str

# 2. Decorate your route (Used by `hrestc` CLI to scan types)
@app.post("/api/v1/run")
@hrest_route(req=RunRequest, res=RunResponse)
async def run(request):
    # Binary request is transparently decoded to JSON by the middleware!
    body = await request.json()
    
    # Return JSON - transparently encoded to Binary by the middleware!
    return {"status": "ok"}
```

2. **Generate Contracts via CLI**

Before starting your server, run the HRest CLI (via npx) in your project root:
```bash
npx hrestc gen contract
```
This generates `hrest-req-contract.json` and `hrest-res-contract.json`.

3. **Start your server**
```bash
fastapi dev main.py
```

---

## Framework Support

### ASGI Apps (Litestar, Quart, Sanic)
Use `HrestASGIMiddleware`.
```python
from hrest import HrestASGIMiddleware
# Mount middleware following your framework's guide
```

### WSGI Apps (Flask, Django)
Use `HrestWSGIMiddleware`.
```python
from hrest import HrestWSGIMiddleware
from flask import Flask

app = Flask(__name__)
app.wsgi_app = HrestWSGIMiddleware(app.wsgi_app)
```

---

## HTTP Headers

| Header | Direction | Description |
|---|---|---|
| `Content-Type: application/hrest` | Request + Response | Binary HRest payload |
| `X-Hrest-Req-Hash: <sha256>` | Request | Contract version validation |
| `X-Hrest-Error: <CODE>` | Response | Machine-readable error code |

### Fallback Mode

Requests with `Content-Type: application/json` are passed through unchanged.
Enables gradual adoption — HRest and REST clients coexist on the same endpoints!

---

## Architecture

`hrest-py` adheres strictly to the **KISS** (Keep It Simple, Stupid) principle:
- **No auto-discovery at runtime**: All parsing and ID allocations are delegated to the build-time Rust CLI (`hrestc`).
- **No external Python dependencies**: Doesn't require Starlette, Pydantic, or any heavy parsing library.
- **Rust FFI Core**: All binary manipulation is securely handled by `hrest-core`.

---

## License

[MIT](LICENSE) © 2026 HyperRest Project

