Post

HN
Hacker News (Newest)

Why you should be using AnyIO APIs

AnyIO is not just a compatibility layer for bridging asyncio and Trio . For one, it comes with its own diverse set of Trio-inspired APIs which have been designed to be a step up from asyncio. Secondly, asyncio has numerous design issues and missing features that AnyIO fixes for you. Therefore there are strong merits in switching to AnyIO APIs even if you are developing an application and not a library.

While the asyncio.TaskGroup class, introduced in Python 3.11, is a major step towards structured concurrency, it only provides a very narrow API that severely limits its usefulness.

First and foremost, the asyncio.TaskGroup class does not offer any way to cancel, or even list all of the contained tasks, so in order to do that, you would still have to keep track of any tasks you create. This also makes it problematic to pass the task group to a child tasks, as tracking the tasks becomes a lot more tedious in such cases.

Secondly, while AnyIO (and Trio ) has long provided a way to wait until a newly launched task signals readiness, asyncio.TaskGroup still does not provide any such mechanism, leaving users to devise their own, often error-prone methods to achieve this.

An AnyIO task group contains its own cancel scope which can be used to cancel all the child tasks, regardless of where they were launched from. Furthermore, if the task group’s cancel scope is cancelled, any tasks launched from the task group since then are also automatically subject to cancellation, thus ensuring that nothing can accidentally hang the task group and prevent it from exiting.

As for tasks signalling readiness, here is an example of waiting until a child task is ready.