Package: async-cast
Cast async function to blocking and viceversa. (works on python 3.7 and
up) Also run functions in threads, whether async or blocking.Whyasync_cast?I found the currentasynciotools frustrating when migrating from
blocking code. If you want to profit IO operations to“run something
else”you need to rewrite all code to use asyncio. When you start form
scratch that’s acceptable, but not with legacy code.So with this small self-contained library you can easily convert legacy
code into async code. The best way is running several blocking function
in different threads. Butbe awarethat threads also bring race
conditions, so make sure concurrent functions are thread-safe.Installinghttps://pypi.org/project/async-cast/pip install -U async-castThe package is a single module that you can easily audit.Decorator: castingasyncfunction to a blocking functionfromasync_castimportalso_blocking@also_blockingasyncdefrequest_url(url,**kwargs):print(f'Requesting{url}with options{kwargs}')...result=f'<h1>{url}</h1>'returnresultif__name__=='__main__':print(request_url.blocking('https://github.com'))Decorator: casting a blocking function toasyncfunctionfromasync_castimportalso_asyncimportasyncio@also_asyncdefrequest_url(url,**kwargs):print(f'Requesting{url}with options{kwargs}')...result=f'<h1>{url}</h1>'returnresultasyncdefmain():print(awaitrequest_url.async_('https://github.com'))if__name__=='__main__':asyncio.run(main())Running tasks in a ThreadPoolI wrapped existingThreadPoolExecutorto make it easier to run tasks
inside it. Tasks are automatically registered in the pool declared by
thewiththread_pool(...):context.Runningasyncfunction in threadpoolfromasync_castimportalso_blocking,thread_poolimportasyncio@also_blockingasyncdefrequest_url(url,**kwargs):print(f'Requesting{url}with options{kwargs}')...result=f'<h1>{url}</h1>'returnresultasyncdefmain():withthread_pool(3):t1=request_url.async_thread('https://github.com')t2=request_url.async_thread('https://google.com')t3=request_url.async_thread('https://facebook.com')results=awaitasyncio.gather(t1,t2,t3)print(results)if__name__=='__main__':asyncio.run(main())Running blocking function in threadpoolfromasync_castimportalso_async,thread_poolimportasyncio@also_asyncdefrequest_url(url,**kwargs):print(f'Requesting{url}with options{kwargs}')...result=f'<h1>{url}</h1>'returnresultasyncdefmain():withthread_pool(3):t1=request_url.async_thread('https://github.com')t2=request_url.async_thread('https://google.com')t3=request_url.async_thread('https://facebook.com')results=awaitasyncio.gather(t1,t2,t3)print(results)if__name__=='__main__':asyncio.run(main())Non decorators alternativesCastingasyncfunction to a blocking function withto_blockingfromasync_castimportto_blockingasyncdefrequest_url(url,**kwargs):print(f'Requesting{url}with options{kwargs}')...result=f'<h1>{url}</h1>'returnresultif__name__=='__main__':print(to_blocking(request_url)('https://github.com'))Casting a blocking function toasyncfunction withto_asyncfromasync_castimportto_asyncimportasynciodefrequest_url(url,**kwargs):print(f'Requesting{url}with options{kwargs}')...result=f'<h1>{url}</h1>'returnresultasyncdefmain():print(awaitto_async(request_url)('https://github.com'))if__name__=='__main__':asyncio.run(main())Runningasyncor blocking function in threadpool withto_async_threadfromasync_castimportto_async_thread,thread_poolimportasyncioasyncdefrequest_url(url,**kwargs):print(f'Requesting{url}with options{kwargs}')...result=f'<h1>{url}</h1>'returnresultdefrequest_url_blocking(url,**kwargs):print(f'Requesting{url}with options{kwargs}')...result=f'<h1>{url}</h1>'returnresultasyncdefmain():withthread_pool(3):t1=to_async_thread(request_url)('https://github.com')t2=to_async_thread(request_url)('https://google.com')t3=to_async_thread(request_url)('https://facebook.com')t4=to_async_thread(request_url_blocking)('https://duckduckgo.com')results=awaitasyncio.gather(t1,t2,t3,t4)print(results)if__name__=='__main__':asyncio.run(main())