Skip to main content

typed-concurrency

Typed structured concurrency with Go-ish ergonomics on top of asyncio.

uv add typed-concurrency
from typed_concurrency import Channel, Group, go, process, thread

Python 3.11 or newer is required. There are no dependencies beyond typed-errs, which supplies the explicit Option value used when a channel closes.

Tasks and groups

go() is deliberately boring: it creates an asyncio.Task[T] without losing the coroutine's result type.

user = go(fetch_user())
config = go(fetch_config())

# Other async work happens here.
name: str = await user
settings: Config = await config

Group is a compact wrapper around asyncio.TaskGroup; it keeps the standard structured-concurrency cancellation and exception behaviour.

async with Group() as group:
    users = group.go(fetch_users())
    config = group.go(fetch_config())

# Both tasks have completed here.
print(users.result())
print(config.result())

When a result is intentionally irrelevant, << makes that clear:

async with Group() as group:
    group << report_progress()
    group << refresh_cache()

Channels

Channel[T] is a buffered async queue with close semantics. recv() and await channel return Option[T]: queued values are Some(value), and a closed, drained channel returns Nothing(). This avoids a nullable receive protocol while keeping normal closure distinct from an error.

from typed_concurrency import Channel
from typed_errs import Some

channel = Channel[int](16)
await channel.send(42)

received = await channel.recv()
if isinstance(received, Some):
    print(received.value)

await channel.close()

Channels are async iterable, which is usually the pleasant producer/consumer form:

async def producer(channel: Channel[int]) -> None:
    for value in range(10):
        await channel.send(value)
    await channel.close()


async def consumer(channel: Channel[int]) -> None:
    async for value in channel:
        print(value)


async with Group() as group:
    channel = Channel[int](10)
    group << producer(channel)
    group << consumer(channel)

await (channel << value) sends and await channel receives; they are sugar over send() and recv(). The named methods are the canonical API.

capacity=0 follows asyncio.Queue and means an unbounded buffer. It is not a Go-style rendezvous channel.

Blocking and CPU work

thread() runs a blocking callable using asyncio.to_thread(). process() runs pickle-compatible CPU-bound work in a shared process pool.

data = await thread(read_file, path)
result = await process(expensive_parse, data)

Use process() only for substantial CPU work: process startup and argument serialization have a real cost.

Examples and development

Run the small end-to-end example with uv run python examples/basic.py.

Run mise run check for formatting-adjacent linting, type checks, tests, and a package build.

License

MIT

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

typed_concurrency-0.0.1.tar.gz (7.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

typed_concurrency-0.0.1-py3-none-any.whl (7.2 kB view details)

Uploaded Python 3

File details

Details for the file typed_concurrency-0.0.1.tar.gz.

File metadata

  • Download URL: typed_concurrency-0.0.1.tar.gz
  • Upload date:
  • Size: 7.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for typed_concurrency-0.0.1.tar.gz
Algorithm Hash digest
SHA256 71f4ac09570310b3105a62c1ae090f8e564cb2886ea9228e1bc29ef2180ede0a
MD5 c50d0335c6238bf4a3fabdb155fe2ac0
BLAKE2b-256 a0ea29704bfe348b338b6b18104e88a1e97e7cc35f08e25c4ebd984e01e58b4a

See more details on using hashes here.

Provenance

The following attestation bundles were made for typed_concurrency-0.0.1.tar.gz:

Publisher: release.yml on 0xveya/typed-concurrency

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file typed_concurrency-0.0.1-py3-none-any.whl.

File metadata

File hashes

Hashes for typed_concurrency-0.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 3f8ad20a52dc8f81a2f269ea6f8ca484a5084e06f646e6d176a8e79961408cb4
MD5 63898db6e9a8f4da36476257c8780b7d
BLAKE2b-256 3279504ca2b084eb4393b095176d47879c1edf316877eaa7eb066388e47f8226

See more details on using hashes here.

Provenance

The following attestation bundles were made for typed_concurrency-0.0.1-py3-none-any.whl:

Publisher: release.yml on 0xveya/typed-concurrency

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page