Python module 'asyncio' has no attribute 'to_thread'

Viewed 3534

From python's asyncio examples:

import asyncio
import time
def blocking_io():
    print(f"start blocking_io at {time.strftime('%X')}")
    # Note that time.sleep() can be replaced with any blocking
    # IO-bound operation, such as file operations.
    time.sleep(1)
    print(f"blocking_io complete at {time.strftime('%X')}")

async def main():
    print(f"started main at {time.strftime('%X')}")

    await asyncio.gather(
        asyncio.to_thread(blocking_io),
        asyncio.sleep(1))

    print(f"finished main at {time.strftime('%X')}")


asyncio.run(main())

# Expected output:
#
# started main at 19:50:53
# start blocking_io at 19:50:53
# blocking_io complete at 19:50:54
# finished main at 19:50:54

It is outputting the next error:

    asyncio.to_thread(blocking_io),
    AttributeError: module 'asyncio' has no attribute 'to_thread'

Has this feature been deprecated? What would be an alternative for threading with asyncio?

2 Answers

to_thread is only available in python 3.9+, if you are working with python 3.8 or an older version, you can copy the source code of it:

async def to_thread(func, /, *args, **kwargs):
    loop = asyncio.get_running_loop()
    ctx = contextvars.copy_context()
    func_call = functools.partial(ctx.run, func, *args, **kwargs)
    return await loop.run_in_executor(None, func_call)

This method copies the context to the thread(to use the current value of your set ContextVars)

If you don't need that and just want a one liner:

await asyncio.get_running_loop().run_in_executor(None, blocking_io, arg1, arg2)

More info about run_in_executor

The top answer didn't help me since was already using python 3.9.7.and continued to get the error

File "<conda_path>/python3.9/site-packages/starlette/concurrency.py", line 39, in run_in_threadpool
    return await anyio.to_thread.run_sync(func, *args)
AttributeError: module 'anyio' has no attribute 'to_thread'

I found the issue in my pypi installs where a package was not updating and needed a force update.

pip install --upgrade --force-reinstall -r requirements.txt

My requirements.txt contained these libraries so it could be anyone of them that was reinstalled and fixed my problem.

moto
uvicorn
fastapi
gunicorn
dnspython
Related