without¶
A decoupled-IO substrate for connecting streams of events to stateful processors
backed by contexts, aiming for maximum concurrency from testable,
dependency-injected code. I/O is not banned, it is separated into the right
abstractions (sources at the edge, behaviors via sample, effects contained in
a processor's step) so the parts stay reusable.
The bet¶
Python has many frameworks with similar-but-subtly-different shapes (ASGI apps,
Kafka consumers, asyncio protocols, config reloaders) that do not interoperate
because none of them names the shared lower layer. without names that layer as
a narrow contract, so the pieces compose. It is meant to feel like a library
(your control flow stays visible) rather than a framework.
The Philosophy page is the durable rationale: the narrow-waist bet, the stream/processor/context substrate, functional-core/imperative-shell, and values-over-places. Read it first to get the mindset the code is shaped around.
The substrate¶
Three types carry the whole model (without.contracts):
- A
Stream[T]is an asynchronous sequence of values: the one shape every connection takes, whoever does the I/O. A socket, a file watcher, a clock, and an in-memory list are all just streams. - A
Processor[In, Out]transforms a stream of inputs into a stream of outputs. It is the only node type and the only thing a user writes. - A
Context[T]is a stream viewed as its latest sampled value:current()reads the latest and never blocks, the way long-lived state (config, a pool) is read.
The packages¶
This is a uv workspace of flat, version-locked
packages. Each is its own top-level import.
without: the core contracts every plugin speaks, the stream connectors, and awith-scoped background task helper.without-env: a staticContextparsed from environment variables withpydantic-settings.without-configmap: config from a Kubernetes mount, the context-updated-by-a-stream half of the model.without-asgi: adapters that turn an ASGI app'sreceive/sendinto typed event streams and back, in both directions.without-web: an opinionated HTTP/WebSocket router with trie matching, typed path params, mounting, scoped middleware, exception handlers, and OpenAPI.without-http: anasyncioASGI server and HTTP client built on the sans-IOh11/h2/wsprotostate machines.without-dag: bounded-concurrency execution of DAG-shaped async workflows, liftable straight into aProcessor.
The package dependency graph is derived from the declared dependencies, and the API reference is recovered from the source docstrings.