Flask asyncio aiohttp - RuntimeError: There is no current event loop in thread 'Thread-2'

Viewed 3610

Lately been reading about python concurrency realpython - python concurrency

My main focus asyncio so am fairly new.

The code block that performs asynchronous activities using asyncio and aiohttp runs fine when run it directly.

However when i add the code to my flask blueprint it raises this error:

RuntimeError: There is no current event loop in thread 'Thread-2'

For demonstration purposes i made a demo flask app. In case anyone wants to test it out.

main.py

from flask import Flask
from my_blueprint import my_blueprint

#Define flask app
app = Flask(__name__)

#load blueprints
app.register_blueprint(my_blueprint,url_prefix='/demo')

#start flask
if __name__ == '__main__':
    app.run(debug=True)

my_blueprint.py

from flask import Blueprint,request, jsonify,abort,make_response
from flask import make_response
import asyncio
import time
import aiohttp

my_blueprint = Blueprint('my_blueprint', __name__)

@my_blueprint.route('/',methods=['GET'])
def home():
    #code block
    async def download_site(session, url):
        async with session.get(url) as response:
            print("Read {0} from {1}".format(response.content_length, url))


    async def download_all_sites(sites):
        async with aiohttp.ClientSession() as session:
            tasks = []
            for url in sites:
                task = asyncio.ensure_future(download_site(session, url))
                tasks.append(task)
            await asyncio.gather(*tasks, return_exceptions=True)

    sites = ["https://www.jython.org","http://olympus.realpython.org/dice"]*20
    start_time = time.time()
    asyncio.get_event_loop().run_until_complete(download_all_sites(sites))
    duration = time.time() - start_time
    return jsonify({"status":f"Downloaded {len(sites)} sites in {duration} seconds"})
    #end of code block
1 Answers

EDIT: It looks like your code was correct. I am used to writing it different. But you are probably running windows and python 3.8. that just changed the default event loop policy in python 3.8 on windows and it pretty buggy. You can change back the old event loop policy:

change:

asyncio.get_event_loop().run_until_complete(download_all_sites(sites))

into:

asyncio.set_event_loop(asyncio.SelectorEventLoop())
asyncio.get_event_loop().run_until_complete(download_all_sites(sites))
Related