Title: Cannot convert MotorCursor object to list in async function using standard method
Tags: python;pyqt5;python-asyncio;tornado-motor
Question: I have been trying to have an async function get data from a Motor database in Python and get the list of data corresponding to the search. Here is the function to get the data and the one to print it:

```async def do_find_by_run_name(run_name):
    """
    :param run_name: the name of a the run being searched for (string)
    :return: MotorCursor for run found
    """
    cursor = db.data_collection.find({"run_name":run_name})
    loop = asyncio.get_event_loop()
    return cursor

async def print_arr(cursor):
    for d in await cursor.to_list(length=2):
        pprint.pprint(d)
```

I have a PyQt slot which I want to use to call the find_by_run_name function on a button press. Here is the code for that slot:

```@pyqtSlot()
def on_find_runs_button_clicked(self):
    try:
        new_loop = asyncio.get_event_loop()
        d = new_loop.run_until_complete(server.do_find_by_run_name("default"))
        print(d)
        new_loop = asyncio.get_event_loop()
        v = new_loop.run_until_complete(server.print_arr(d))
    except Exception as err:
        try:
            raise TypeError("Again !?!")
        except:
            pass
        traceback.print_exc()
```

When I press the button corresponding to this slot I see the following in my terminal:

```AsyncIOMotorCursor(<pymongo.cursor.Cursor object at 0x06F51EB0&gt;)
Traceback (most recent call last):
  File "C:/Users/Rohan Doshi/Documents/websockets/server\GUI.py", line 93, in on_find_runs_button_clicked
    v = new_loop.run_until_complete(server.print_arr(d))
  File "C:\Users\Rohan Doshi\AppData\Local\Programs\Python\Python36-32\lib\asyncio\base_events.py", line 468, in run_until_complete
    return future.result()
  File "C:/Users/Rohan Doshi/Documents/websockets/server\server.py", line 130, in print_arr
    for d in await cursor.to_list(length=2):
RuntimeError: Task <Task pending coro=<print_arr() running at C:/Users/Rohan Doshi/Documents/websockets/server\server.py:130&gt; cb=[_run_until_complete_cb() at C:\Users\Rohan Doshi\AppData\Local\Programs\Python\Python36-32\lib\asyncio\base_events.py:177]&gt; got Future <Future pending&gt; attached to a different loop
```

This indicates to me that the do_find_by_run_name function ran properly but that there is an issue with running the print_arr function.

In an attempt to fix this issue do_find_run_name was changed to:

```async def do_find_by_run_name(run_name):
    """
    :param run_name: the name of a the run being searched for (string)
    :return: MotorCursor for run found
    """
    cursor = db.data_collection.find({"run_name":run_name})
    print(cursor)
    for d in await cursor.to_list(length=2):
        pprint.pprint(d)
```

and I changed my PyQt slot to:

```@pyqtSlot()
def on_find_runs_button_clicked(self):
    try:
        new_loop = asyncio.get_event_loop()
        future = asyncio.run_coroutine_threadsafe(
            server.do_find_by_run_name("default"),
            new_loop
        )
        assert future.result(timeout=10)
    except Exception as err:
        try:
            raise TypeError("Again !?!")
        except:
            pass
        traceback.print_exc()
```

When this change is made I don't see anything printed. It seems like the do_find_run_name couroutine is never executed.

Comment: What exactly do you mean by "nothing happens"? If you add a `print("x")` after the `async for` loop in `do_find_by_run_name`, does it get executed? Perhaps an exception is being raised and hidden by some outer try/except block, or propagated to the top-level of a background task.

Comment: Wrap the loop in `try ... except Exception: import traceback; traceback.print_exc()`. This will show you the error that you're getting.

Comment: The new code completely removes the `async for` from `do_find_by_run_name` and reveals what is possibly a different issue. It seems that you have two event loops. If you have a call to `new_event_loop` or something like that, remove it. Instead, look into using [`asyncio.run_coroutine_threadsafe`](https://docs.python.org/3/library/asyncio-task.html#asyncio.run_coroutine_threadsafe) to pass a coroutine to an event loop already running in another thread.

Comment: You need to call the `result()` method on the object returned by `run_coroutine_threadsafe` to actually wait for the result to become available. Please refer to examples in the [documentation](https://docs.python.org/3/library/asyncio-task.html#asyncio.run_coroutine_threadsafe) I linked the first time. Also, you don't need a `try/raise TypeError/except: pass` block inside each `try/except`.

Comment: You are passing the wrong event loop to `run_coroutine_threadsafe` - you should be passing it the actual event loop used by asyncio in another thread, not the one set up for this thread.

Comment: It does, but the `RuntimeError` is telling you that the event loop is running in a *different* thread. That's the event loop you need to submit the coroutine to. It's really hard to help you without understanding the structure of your application and how you use asyncio.

Comment: Nice to hear! Good luck with asyncio.

Comment: I added a print statement before and after the for loop. The print statement before loop gets executed, and I see the text in my terminal. The statement after the loop does not get executed, and my program hangs. If I remove the for loop entirely the do_find_by_run_name function runs completely and returns a MotorCursor object, and the program does not hang.

Comment: I should also mention that I am calling this function from a PyQt5 slot

Comment: I followed your advice and added this statement. I have edited my post with a more clear issue.

Comment: I used the run_couroutine_threadsafe function as suggested, but it seems like then the couroutine never gets executed. I put these changes in another edit to the post.

Comment: I looked at the documentation and changed my try block (see post edits)
No matter what I change timeout to I always get a concurrent.futures._base.TimeoutError, which means that my coroutine never executes.

Comment: Could you please elaborate I don't fully understand. Does asyncio.get_event_loop() not get the event loop in the current thread?

Comment: Thanks! I finally found the issue. There was another event loop called in another function where I was starting a Motor Client and a tornado web application, and I was able to use that loop in the run_coroutine_threadsafe function.



{'source': 'StackExchangeDataset', 'subset': 'stackoverflow.com', 'metadata': {'AnswerCount': 0, 'CommentCount': 14, 'ContentLicense': 'CC BY-SA 4.0', 'CreationDate': '2018:00:07/17/18', 'FavoriteCount': None, 'PostTypeId': 1, 'Tags': '<python><pyqt5><python-asyncio><tornado-motor>', 'Title': 'Cannot convert MotorCursor object to list in async function using standard method', 'ViewCount': 1448, 'id': 51371660, 'user_AboutMe': None, 'user_AccountId': 13972774.0, 'user_DisplayName': 'Rohan Doshi', 'user_Reputation': 29.0, 'user_Views': 5.0, 'user_id': 10090893.0}}