Search code examples
python-asynciodecorator

Decorator to async function python


A simple decorate to calculate time a function takes to run:

import time
def decor(f):
  starttime=time.time()
  f()
  print("child functoin run time is ", (time.time()-starttime)*1000, "ms")
  return f

try to use it to decorate async functions:

async def sleep_and_print(seconds):
    print(f"starting async {seconds} sleep 😴")
    await asyncio.sleep(seconds)
    print(f"finished async {seconds} sleep ⏰")
    return seconds

@decor
async def main():
    # using arguments
    results = await asyncio.gather(sleep_and_print(3), sleep_and_print(6))
    print(results)

asyncio.run(main())

I got RuntimeWarning: coroutine 'main' was never awaited error If I change the decorator function to async and await, eg

async def decor(f):
  starttime=time.time()
  await f()
  print("child functoin run time is ", (time.time()-starttime)*1000, "ms")
  return f

asyncio.run(main()) failed with coroutine' object is not callable

Why main() becomes uncallable? Any suggestion on the work around?


Solution

  • Try to return async function from the decorator function:

    import time
    import asyncio
    
    
    def decor(f):
        async def _fn():
            starttime = time.time()
            await f()
            print(
                "child function run time is ",
                (time.time() - starttime) * 1000,
                "ms",
            )
    
        return _fn
    
    
    async def sleep_and_print(seconds):
        print(f"starting async {seconds} sleep 😴")
        await asyncio.sleep(seconds)
        print(f"finished async {seconds} sleep ⏰")
        return seconds
    
    
    @decor
    async def main():
        # using arguments
        results = await asyncio.gather(sleep_and_print(3), sleep_and_print(6))
        print(results)
    
    
    asyncio.run(main())
    

    Prints:

    starting async 3 sleep 😴
    starting async 6 sleep 😴
    finished async 3 sleep ⏰
    finished async 6 sleep ⏰
    [3, 6]
    child function run time is  6002.1820068359375 ms