python-asyncio TypeError: object dict can't be used in 'await' expression

后端 未结 3 1662
谎友^
谎友^ 2020-12-29 04:44

I am using a third party module to retrieve data from an API. I simply would like to asynchronously await the module to return the data which occasionally takes several seco

相关标签:
3条回答
  • 2020-12-29 05:17

    As thirdPartyAPIWrapper.data() is a normal sync function you should call it in another thread.

    There is a helper function for that in a asgiref library.
    Assume we've got a blocking function with an argument:

    import asyncio
    import time
    
    from asgiref.sync import sync_to_async
    
    
    def blocking_function(seconds: int) -> str:
        time.sleep(seconds)
        return f"Finished in {seconds} seconds"
    
    async def main():
        seconds_to_sleep = 5
        function_message = await sync_to_async(blocking_function)(seconds_to_sleep)
        print(function_message)
    
    loop = asyncio.get_event_loop()
    loop.run_until_complete(main())
    loop.close()
    

    There is also an async_to_sync helper function in that library.

    0 讨论(0)
  • 2020-12-29 05:25

    Only asynchronous (defined with async def) functions can be awaited. Whole idea is that such functions are written special way what makes possible to run (await) them without blocking event loop.

    If you want to get result from common (defined with def) function that takes some considerable time to be executed you have these options:

    • rewrite this whole function to be asynchronous
    • call this function in another thread and await for result asynchronously
    • call this function in another process and await for result asynchronously

    Usually you want to choose second option.

    Here's example of how to do it:

    import asyncio
    import time
    from concurrent.futures import ThreadPoolExecutor
    
    
    _executor = ThreadPoolExecutor(1)
    
    
    def sync_blocking():
        time.sleep(2)
    
    
    async def hello_world():
        # run blocking function in another thread,
        # and wait for it's result:
        await loop.run_in_executor(_executor, sync_blocking)
    
    
    loop = asyncio.get_event_loop()
    loop.run_until_complete(hello_world())
    loop.close()
    

    Please, read this answer about how asyncio works. I think it'll help you much.

    0 讨论(0)
  • 2020-12-29 05:33

    I am writing test cases and I need to mock async functionality. So, you can write a simple helper function like so.

    async def resolve(val):
        return val
    

    Now you can await anything

    foo = resolve(1) 
    await foo # No error!
    
    0 讨论(0)
提交回复
热议问题