RuntimeError: There is no current event loop in thread 'MainThread'

Viewed 2450

I am currently working on a project where I am looking for information updates and then posting status messages to a slack channel. This is my first python project and I am a little out of the loop with what is going wrong. However, it appears that the RuntimeError: There is no current event loop in thread 'MainThread' error that I am getting is caused by having two async requests in my main function.

I was wondering if anyone would be able to tell me what best practice would be and how i could avoid any more issues?

def main():
    configure()

    print("the project has started")
    asyncio.run(post_message("the project has started"))

    event_filter = [my api call to another service goes here]
    loop = asyncio.get_event_loop()
    try:
        loop.run_until_complete(
            asyncio.gather(
                log_loop(event_filter, 2)))
    finally:
        # close loop to free up system resources
        loop.close()

async def post_message(message):
    try:
        client = AsyncWebClient(token=os.getenv('SLACK_BOT_TOKEN'))
        response = await client.chat_postMessage(channel='#notifications', text=message)
        assert response["message"]["text"] == message
    except SlackApiError as e:
        assert e.response["ok"] is False
        assert e.response["error"]  # str like 'invalid_auth', 'channel_not_found'
        print(f"Got an error: {e.response['error']}")

It seems to me that the call asyncio.run(post_message("the project has started")) is not playing well with my loop = asyncio.get_event_loop() but again I am unsure why.

Any help would be much appreciated!

EDIT

Here is the full traceback as requested:

Traceback (most recent call last):
  File "/Applications/Xcode.app/Contents/Developer/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/runpy.py", line 194, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "/Applications/Xcode.app/Contents/Developer/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/runpy.py", line 87, in _run_code
    exec(code, run_globals)
  File "myprojectpath/__main__.py", line 4, in <module>
    app.main()
  File "myprojectpath/app.py", line 54, in main
    loop = asyncio.get_event_loop()
  File "/Applications/Xcode.app/Contents/Developer/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/asyncio/events.py", line 639, in get_event_loop
    raise RuntimeError('There is no current event loop in thread %r.'
RuntimeError: There is no current event loop in thread 'MainThread'.
1 Answers

This recreates your error:

import asyncio
async def test():
    pass

def main():
    asyncio.run(test())
    loop = asyncio.get_event_loop()
    loop.run_until_complete(test())

The issue is that asyncio.run creates an event loop, runs your coroutine, and then closes the event loop. Therefore you can't use that loop later on. Instead, change main into an async function and just use await OR use asyncio.run for your gather call. Try avoiding using the loop api unless you have to.

Related