without-web
An opinionated HTTP and WebSocket router for
without-asgi. without-asgi deliberately ships no router,
only the unopinionated boundary and composition tools. without-web is the
opinionated layer on top: t-string patterns with typed parameters, typed request
extraction, 405-vs-404, mounting, scoped middleware, exception handlers, reverse
routing (url_for), and OpenAPI.
It snaps onto the boundary through nothing but the existing HttpRouter type:
Router.dispatch is an HttpRouter[T], so make_asgi_app(http=router.dispatch)
just works, and bring-your-own (or no router at all) stays first-class.
import json
from without_asgi import Response, make_asgi_app
from without_web import INT, Router, get, path_param
uid = path_param("id", INT) # one token: a pattern segment AND a typed read
@get(t"/users/{uid}", uid) # t-string pattern; `@get` returns a Route value
async def show_user(state, user_id: int): # user_id is an int, no `assert isinstance`
body = json.dumps({"id": user_id}).encode()
return Response(status=200, headers=((b"content-type", b"application/json"),), body=body)
router = Router(routes=(show_user,), fallback=not_found)
app = make_asgi_app(lifespan, http=router.dispatch)
Matching is a pure walk of an immutable trie, so precedence, 405-vs-404, and
mounting fall out of the structure. Converters and extractors parse, they don't
validate: a path param arrives already typed, and OpenAPI is a merge of the
self-descriptions each layer recovers from structure rather than a blob declared
by hand. Encoding stays the app's choice, so the router ships no
json_response-style helper.
See the
without-web guide
(with the API reference)
for the full surface: patterns, extractors, streaming input, mounting,
middleware, exception handlers, reverse routing, OpenAPI, and WebSocket routing.
Metadata
Release files for without-web 0.0.8
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| without_web-0.0.8.tar.gz | 31.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| without_web-0.0.8-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 68.6 kB
Release files / without_web-0.0.8.tar.gz
| Download URL | without_web-0.0.8.tar.gz |
|---|---|
| Size | 31.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
7e8894c9d8d11232d480a9f4b1314d4ff743204ed145be0bdc6833bdf03b8899
|
|
BLAKE2b-256 checksum How to use checksums |
674a7cf9b6d6d5e186552fd61e881b37ce120e2a9b7774bf82e6f18e35073498
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.10 {"installer":{"name":"uv","version":"0.12.10","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / without_web-0.0.8-py3-none-any.whl
| Download URL | without_web-0.0.8-py3-none-any.whl |
|---|---|
| Size | 37.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
583011de6f0ac137cc9e46d22ec62b9556b388bb71e3dc1157b00cd92ccc5113
|
|
BLAKE2b-256 checksum How to use checksums |
a8a0f6558e837445391f7706395ee45391e8297cf54505a960ee6dae1cba787d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.10 {"installer":{"name":"uv","version":"0.12.10","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|