Async Python is Ugly

in Synergy Builders2 days ago (edited)

Hey everyone,

I think we can all agree on something: standard Python asyncio is painful. It requires significant boilerplate. You have to manage event loops. You have to color your functions with async and await carefully. You have to manually orchestrate gather and create_task. It gets messy fast.

wove.png

I recently found a library that looks very promising: Wove.
https://github.com/curvedinf/wove

The Promise

Wove bills itself as "Beautiful Python async." It attempts to abstract away the "ugliness" of the event loop and task management.

It uses a context manager to handle the heavy lifting. You define tasks inside a weave block. Wove then builds a dependency graph based on your function signatures. It determines what can run in parallel and what needs to wait for data from previous steps.

Why it looks cool

  • Top-to-Bottom Readability: You write code in a logical, linear order. Wove handles the asynchronous execution flow.
  • Implicit Parallelism: You don't need asyncio.gather(). If two functions don't depend on each other, Wove runs them at the same time automatically.
  • Mix Sync and Async: You can mix standard def and async def functions. Wove runs synchronous functions in a thread pool to keep the loop non-blocking.
  • Zero Dependencies: It relies entirely on the standard library.

A Quick Example

Here is how you might fetch two things and combine them The Wove Way:

from wove import weave
import time

# This looks like normal code
with weave() as w:

    @w.do
    def get_user_data():
        time.sleep(1) # Simulating IO
        return {"name": "Michael"}

    @w.do
    def get_posts():
        time.sleep(1)
        return ["Post 1", "Post 2"]

    # This automatically waits for the previous two because
    # the arguments match the function names above.
    @w.do
    def render_page(get_user_data, get_posts):
        return f"User: {get_user_data['name']}, Posts: {len(get_posts)}"

# Execution happens when the block exits
print(w.results.final)

It looks remarkably clean. It handles the concurrency logic implicitly through variable names.

I haven't deployed this to production in anything yet (I just discovered it recently via an email), but for tools and scripts where I want speed without the asyncio headache, this looks like it might be a winner. I plan on putting it through it's paces and seeing how it works out, I just might end up loving it.

As always,
Michael Garcia a.k.a. TheCrazyGM

Sort:  

untitled.gif

!PIMP
!PIZZA

Loading...

Finding something that makes something else work better is always a plus indeed! Why would the original asyncio be designed in such a cumbersome manner that it needs another library to make it work the way you want without a hassle? that's rhetorical of course, but seriously! 😁🙏💚✨🤙

PIZZA!

$PIZZA slices delivered:
@ecoinstant(3/20) tipped @thecrazygm

Please vote for pizza.witness!