Skip to main content

typed-concurrency

PyPI CI

View typed-concurrency on PyPI

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.2.tar.gz (7.4 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.2-py3-none-any.whl (7.3 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: typed_concurrency-0.0.2.tar.gz
  • Upload date:
  • Size: 7.4 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.2.tar.gz
Algorithm Hash digest
SHA256 34914f51de7242c3ae716e053697bbf6c9ebdcf756d24bb7f06c26e1c9e3edc7
MD5 0a88fa83b920780696421247baed08ff
BLAKE2b-256 002003c962cf77b4887b9f182bef8a9b6795613871a6c42edf48bf7067a1ba44

See more details on using hashes here.

Provenance

The following attestation bundles were made for typed_concurrency-0.0.2.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.2-py3-none-any.whl.

File metadata

File hashes

Hashes for typed_concurrency-0.0.2-py3-none-any.whl
Algorithm Hash digest
SHA256 7cbafcd88935afa00d06a4e44fc02963f41eb359ed6bca7024cd054d6f09d355
MD5 32c983c988990fd0e9a0b55fb414036d
BLAKE2b-256 1cfd4c3552404ec1a34c531ab15b9ae3277bffc83b72553a23827c02923a2c3a

See more details on using hashes here.

Provenance

The following attestation bundles were made for typed_concurrency-0.0.2-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