0

I have a loop that when it finishes it returns a dataframe. This dataframe is then processed elsewhere within the app. Broadly speaking, in a sequenctial code, it looks like that:

import pandas as pd

def print_int_seq():
    col_1 = []
    col_2 = []
    for i in range(10):
        col_1.append(i)
        col_2.append(2*i)
        print(i)
    return pd.DataFrame({'col_1': col_1, 'col_2': col_2})

def run_seq():
    df = print_int_seq()
    print(df)

if __name__ == "__main__":
    run_seq()

I want now to have another function that will run asynchronously with the loop that returns the dataframe. I do not know how to do this please, ie return a value from an async/awaited function. If I didnt need to return anything the program (with the two async functions) would probably look like this:

import pandas as pd
from datetime import datetime
import asyncio

async def print_time(con):
    while True:
        print(datetime.now().time())
        await asyncio.sleep(1)

async def print_int():
# I would like this to return the full 10x2 dataframe 
    col_1 = []
    col_2 = []
    for i in range(10):
        col_1.append(i)
        col_2.append(2*i)
        print(i)
        await asyncio.sleep(1)

async def main():
# how can I catch and process the 10x2 dataframe returned by print_int()?
    await asyncio.gather(
        print_time(con),
        print_int(),
    )

if __name__ == "__main__":
    asyncio.run(main())

How can I edit the script above so when the loop is exhausted to catch the dataframe and handle it in another function please? Does it matter that loop in the other async function never ends?

2
  • you need to cancel print task to get a response. Bigger issue is if you have only computations (no async i/o) in print_int, print_time function won't execute. Commented Sep 21, 2022 at 11:18
  • stackoverflow.com/questions/31900244/… Commented Sep 21, 2022 at 11:19

1 Answer 1

1

First and most important: async mimic the behavior of functions a lot - if you want them to return a value, just add a return statement with whatever value you want to return:

async def print_int():
# I would like this to return the full 10x2 dataframe 
    col_1 = []
    col_2 = []
    for i in range(10):
        ...
    return pd.Dataframe(...)

Second: asyncio.gather simply returns a sequence with all return values of the executed tasks, and for that, it must wait until all "gathered" tasks return. If the other task were to be finite, and finshed more or less on the same time, you'd do:

async def main():

    result1, result2 = await asyncio.gather(
        print_time(con),
        print_int(),
    )

As you plan to have a concurrent routine that won't end at all, asyncio.gather is not the best thing to: just create a task for both co-routines and await the result of the task you want:

async def main():
    # this will get the other co-routine running in the background:
    asyncio.create_task(print_time(con))
      
    result = await print_int()
    

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks. I wanted to ask, should the print_int() function be awaited? Shall I add await asyncio.sleep(0) maybe or these is a better way? Also, I tried to do it by replacing the asyncio.gather() call with await asyncio.wait([print_time(), print_int()], return_when=asyncio.FIRST_COMPLETED). Is this the same more or less with you approach please (with respect to the main())?
yes, asyncio.wait will work - but it won´t be needed if you need to wait for a single task: then you can just await the co-routine directly, as in the answer snippet. If you have concurrent tasks that will return a value at different points, then you should use .wait()
Thanks, I think I have finally done it, slightly differently but you helped massively, hence accepted

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.