Metadata-Version: 2.5
Name: quadkit-web
Version: 0.0.3
Summary: Web layer for Quadkit Framework - ASGI, routing, middleware, and API tooling
Project-URL: Homepage, https://quadkit.dev
Project-URL: Repository, https://github.com/dbtinoy-/quadkit
Project-URL: Documentation, https://quadkit.dev
Project-URL: Issues, https://github.com/dbtinoy-/quadkit/issues
Project-URL: Changelog, https://github.com/dbtinoy-/quadkit/blob/main/CHANGELOG.md
Author-email: Quadkit Framework Team <team@quadkit.dev>
Maintainer-email: Quadkit Framework Team <team@quadkit.dev>
License: Apache-2.0
License-File: LICENSE
License-File: NOTICE
Keywords: api,asgi,async,framework,http,middleware,rest,routing,starlette,web
Classifier: Development Status :: 3 - Alpha
Classifier: Framework :: AsyncIO
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Internet :: WWW/HTTP :: HTTP Servers
Classifier: Topic :: Internet :: WWW/HTTP :: WSGI :: Application
Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
Classifier: Typing :: Typed
Requires-Python: >=3.11
Requires-Dist: aiofiles>=23.0.0
Requires-Dist: jinja2>=3.1.0
Requires-Dist: markupsafe>=2.1.5
Requires-Dist: orjson>=3.9.0
Requires-Dist: quadkit-contracts>=0.0.2
Requires-Dist: quadkit>=0.0.2
Requires-Dist: starlette>=0.28.0
Requires-Dist: typing-extensions>=4.0.0
Provides-Extra: all
Requires-Dist: granian>=2.8.2; extra == 'all'
Requires-Dist: httpx2>=2.0.0; extra == 'all'
Requires-Dist: httpx>=0.26.0; extra == 'all'
Requires-Dist: itsdangerous>=2.0.0; extra == 'all'
Requires-Dist: jinja2>=3.1.0; extra == 'all'
Requires-Dist: pytest-asyncio>=0.21.0; extra == 'all'
Requires-Dist: pytest-cov>=4.0.0; extra == 'all'
Requires-Dist: pytest-mock>=3.10.0; extra == 'all'
Requires-Dist: pytest>=8.0.0; extra == 'all'
Requires-Dist: pyyaml>=6.0; extra == 'all'
Requires-Dist: quadkit-testing>=0.0.2; extra == 'all'
Requires-Dist: uvicorn[standard]>=0.52.4; extra == 'all'
Requires-Dist: websockets>=12.0.0; extra == 'all'
Provides-Extra: client
Requires-Dist: httpx2>=2.0.0; extra == 'client'
Requires-Dist: httpx>=0.26.0; extra == 'client'
Provides-Extra: dev
Requires-Dist: black>=23.0.0; extra == 'dev'
Requires-Dist: mypy>=1.0.0; extra == 'dev'
Requires-Dist: ruff>=0.16.4; extra == 'dev'
Requires-Dist: types-aiofiles>=23.0.0; extra == 'dev'
Provides-Extra: docs
Requires-Dist: pyyaml>=6.0; extra == 'docs'
Provides-Extra: granian
Requires-Dist: granian>=2.8.2; extra == 'granian'
Provides-Extra: hypercorn
Requires-Dist: hypercorn>=0.16.0; extra == 'hypercorn'
Provides-Extra: security
Requires-Dist: itsdangerous>=2.0.0; extra == 'security'
Provides-Extra: templates
Requires-Dist: jinja2>=3.1.0; extra == 'templates'
Provides-Extra: test
Requires-Dist: httpx2>=2.0.0; extra == 'test'
Requires-Dist: httpx>=0.26.0; extra == 'test'
Requires-Dist: pytest-asyncio>=0.21.0; extra == 'test'
Requires-Dist: pytest-cov>=4.0.0; extra == 'test'
Requires-Dist: pytest-mock>=3.10.0; extra == 'test'
Requires-Dist: pytest>=8.0.0; extra == 'test'
Requires-Dist: python-multipart>=0.0.9; extra == 'test'
Requires-Dist: quadkit-testing>=0.0.2; extra == 'test'
Provides-Extra: uploads
Requires-Dist: python-multipart>=0.0.9; extra == 'uploads'
Provides-Extra: uvicorn
Requires-Dist: uvicorn[standard]>=0.52.4; extra == 'uvicorn'
Provides-Extra: websocket
Requires-Dist: websockets>=12.0.0; extra == 'websocket'
Description-Content-Type: text/markdown

# quadkit-web

The async web layer for Quadkit: controllers with signature-based
binding, a `Result`-to-HTTP bridge, middleware pipelines, and generated
OpenAPI docs — built on Starlette, server-backend agnostic.

For application developers building HTTP services: define controllers,
attach the web module, and serve on Granian, Uvicorn, or Hypercorn.

## Installation

The distribution ships no server by itself — install one backend (or
use `quadkit[web]`, which resolves to `quadkit-web[granian]`):

```bash
uv add "quadkit-web[granian]"   # default backend, ASGI
uv add "quadkit-web[uvicorn]"   # alternative backend
uv add "quadkit-web[hypercorn]" # alternative backend
```

Requires **Python >= 3.11**.

## Minimal working example

```python
from quadkit import Application
from quadkit.web import Controller, WebModule, get
from quadkit.web.server import run_server


class HelloController(Controller):
    @get("/hello")
    async def hello(self, name: str = "world") -> dict:
        return {"message": f"hello, {name}"}


def create_app() -> Application:
    app = Application()
    app.add_modules([WebModule.configure(controllers=[HelloController])])
    return app


if __name__ == "__main__":
    run_server(create_app(), port=8000)
```

`/hello` is yours; `/docs`, `/redoc`, `/openapi.json`, and `/health`
come with it. Full walkthrough:
[your first app](../../docs/getting-started/first-app.md), then the
[web API guide](../../docs/guides/web-api.md).

## Optional extras

| Extra | Contents |
| --- | --- |
| `[granian]` / `[uvicorn]` / `[hypercorn]` | ASGI server backends |
| `[security]` | `itsdangerous` — signed tokens |
| `[templates]` | Jinja2 template rendering |
| `[websocket]` | `websockets` — WebSocket support |
| `[client]` | HTTP client |
| `[test]` / `[docs]` / `[dev]` / `[all]` | tooling bundles |

## Public API entry points

```python
from quadkit.web import (
    Controller, WebModule,
    get, post, put, patch, delete,
    body, query, path, header, cookie, form,
    HTTPError, error_status,
    JSONResponse, HTMLResponse, StreamingResponse, FileResponse,
    RedirectResponse, BackgroundTasks,
)
from quadkit.web.config import WebConfig, ServerConfig, RateLimitConfig
from quadkit.web.middleware import MiddlewareRegistry
from quadkit.web.server import run_server, run_server_async
```

`WebModule.configure(controllers=..., middleware=...)` is the assembly
point; `WebModule.stub()` gives a no-op web module for unit tests.

## Configuration

Everything is typed, validated at boot, and env-overridable
(`QK_WEB__...`):

| YAML path | Default | What it controls |
| --- | --- | --- |
| `web.server.host` / `port` | `0.0.0.0` / `8000` | bind address |
| `web.server.backend` | `granian` | `granian`, `uvicorn`, or `hypercorn` |
| `web.server.workers` | `1` | worker processes (production lever) |
| `web.server.reload` | `false` | hot reload (development aid) |
| `web.security.enable_csrf` | `true` | cookie-based CSRF protection |
| `web.security.cors.allowed_origins` | `[]` (deny-by-default) | CORS allow-list |
| `web.rate_limit.enabled` | `false` | opt-in rate limiting |
| `web.api_docs.enabled` | `true` | `/docs` + `/redoc` |
| `web.max_body_size` | 10 MiB | request body cap |

Env overrides mirror the YAML path, e.g. `QK_WEB__SERVER__PORT=8080`,
`QK_WEB__SECURITY__CORS__ALLOWED_ORIGINS='["https://app.example.com"]'`.
See [configuration](../../docs/getting-started/configuration.md).

## Error handling

Every failure renders as an RFC 7807 problem body: domain exceptions map
through a status table, `HTTPError` gives direct control, request-body
validation answers `422` with per-field errors.
[The error-handling guide](../../docs/guides/error-handling.md) shows
all three paths with executable examples.

## Testing

`quadkit-testing`'s `WebTestBed` boots your app in-process and asserts
on responses — no listening socket, no mocking:

```python
async def test_hello() -> None:
    from quadkit.testing import WebTestBed

    async with WebTestBed(create_app()) as bed:
        response = bed.get("/hello", params={"name": "quadkit"})
        response.assert_status(200)
        assert response.json == {"message": "hello, quadkit"}
```

## Security

Conservative defaults: CSRF on, CORS deny-by-default, unexpected
exceptions contained to a minimal 500 body. Details and hardening:
[secure configuration](../../docs/security/secure-configuration.md);
report vulnerabilities privately per [SECURITY.md](../../SECURITY.md).

## Stability

Version `0.0.3` in the `0.x` series, released in lockstep with the
other four distributions; APIs may change between minor versions until
1.0 — pin an exact version (`quadkit-web==0.0.3`) or a tight range
(`>=0.0.3,<0.1.0`). Full policy:
[stability and compatibility](../../docs/reference/stability.md).

Issues: <https://github.com/dbtinoy-/quadkit/issues>
