asyncio generally requires that you provide a “session”/“client” object that contains the run loop for the async operations. I think that when you refactor a library to support asyncio, you provide a non-async wrapper around it which spins up the execution loop for each operation, although there might be a better pattern for it these days.
An antipattern I’ve seen a lot is people wrapping a non-async library in a threadpool and then have the async wrapper block on the future, but that completely misses the point to asyncio and makes everything perform way worse.
asyncio is kind of wonky to wrap your head around at first but it’s well worth it for the major performance gains you get. It can be a huge pill to swallow though, and given that most Python web apps are still running in a thread-per-connection context (because wsgi is designed around it) it can feel like a chicken-egg scenario at times. But doing the work of moving to asyncio (and providing a non-async wrapper around it) makes it easier for more things to move to asyncio and getting the performance benefits as a result, so it’s a net good IMO, even if it isn’t heavily used right away.