Asyncio event loop is closed when using asyncio.run()
Whilst this has been answered and accepted. You can fix this issue with one line of code:
Event loop is closed is a known issue on Windows (see https://github.com/encode/httpx/issues/914). I suspect this will be fixed in later versions of Python. To get around the error, simply set the event loop policy to WindowsSelectorEventLoopPolicy.
If you plan to run the code on non-windows environment; then you'll want to either add an if statement to prevent error. E.g:
if sys.platform == 'win32'. Or add code to set the policies.
import asyncio from aiocfscrape import CloudflareScraper import sys async def nested(url): async with CloudflareScraper() as session: async with session.get(url) as resp: print(resp.status) return await resp.text() async def main(): URL = "https://www.binance.com/api/v3/exchangeInfo" await asyncio.gather(nested(URL), nested(URL), nested(URL)) # Only preform check if your code will run on non-windows environments. if sys.platform == 'win32': # Set the policy to prevent "Event loop is closed" error on Windows - https://github.com/encode/httpx/issues/914 asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy()) asyncio.run(main())
You indeed can surpress error one-liner like Greg's answer below:
import asyncio import sys if sys.platform: asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
WindowsSelectorEventLoop has functionality issues such as:
- Can't support more than 512 sockets
- Can't use pipe
- Can't use subprocesses
due to the fact that Windows uses I/O completion Ports unlike *nix - Therefore
SelectorEventLoop is not designed for Windows nor is implemented as full.
If those limitations matters to you - You might be better off using lengthy workaround in this answer.
Check out more about differences at documents.
Or alternatively, consider using Trio over asyncio, which is much more stable and consistent.
import trio async def task(): await trio.sleep(5) trio.run(task)
I've finally figured out how to keep
ProactorEventLoop running, preventing unsuccessful IO closure.
Really not sure why windows' Event loop is so faulty, as this also happens for
To workaround this, you need to run event loop in forever loop and close manually.
Following code will cover both windows and other environments.
import asyncio from aiocfscrape import CloudflareScraper async def nested(url): async with CloudflareScraper() as session: async with session.get(url) as resp: return await resp.text() async def main(): await nested("https://www.binance.com/api/v3/exchangeInfo") try: assert isinstance(loop := asyncio.new_event_loop(), asyncio.ProactorEventLoop) # No ProactorEventLoop is in asyncio on other OS, will raise AttributeError in that case. except (AssertionError, AttributeError): asyncio.run(main()) else: async def proactor_wrap(loop_: asyncio.ProactorEventLoop, fut: asyncio.coroutines): await fut loop_.stop() loop.create_task(proactor_wrap(loop, main())) loop.run_forever()
This code will check if new
If so, keep loop forever until
main and schedules loop stop.
Else - possibly all other OS than Windows - doesn't need these additional steps, simply call
IDE like Pycharm will complain about passing
ProactorEventLoop parameter, safe to ignore.