python-3.xpython-asyncioaiohttp

How do I fix session closed error when using asyncio library


I'm trying write a python script that makes a bunch of parallel http requests. Here is what I have so far.

async def deleteLinkRecords(req_headers):
  async with aiohttp.ClientSession(trust_env=True) as session:
   idm_url = "https://example.com"

   tasks = []
   for id in linkIdArr:
     del_url = idm_url + id
     tasks.append(make_request(session, del_url, req_headers))

  results = await asyncio.gather(*tasks)
  print(results)

async def make_request(session, url, req_headers):
    async with session.delete(url = url, headers = req_headers) as resp:
     return await resp.json()

my_headers = {
   "Authorization": "Bearer XXX"
}

linkIdArr = ["abc", "def"....]

asyncio.run(deleteLinkRecords(req_headers = my_headers))

When I run this script, I am getting the following error.

Traceback (most recent call last):
  File "C:\Users\mycode.py", line 48, in <module>
    asyncio.run(deleteLinkRecords(req_headers = my_headers))
  File "C:\Users\AppData\Local\Programs\Python\Python39\lib\asyncio\runners.py", line 44, in run
    return loop.run_until_complete(main)
  File "C:\Users\AppData\Local\Programs\Python\Python39\lib\asyncio\base_events.py", line 642, in run_until_complete
    return future.result()
  File "C:\Users\mycode.py", line 20, in deleteLinkRecords
    results = await asyncio.gather(*tasks)
  File "C:\Users\mycode.py", line 28, in make_requests
    async with session.delete(url = url, headers = req_headers) as resp:
  File "C:\Users\AppData\Local\Programs\Python\Python39\lib\site-packages\aiohttp\client.py", line 1197, in __aenter__
    self._resp = await self._coro
  File "C:\Users\AppData\Local\Programs\Python\Python39\lib\site-packages\aiohttp\client.py", line 428, in _request
    raise RuntimeError("Session is closed")
RuntimeError: Session is closed

How can I fix this issue?


Solution

  • If you want to reuse the ClientSession then you must add the asyncio.gather inside the same context manager.

    async def deleteLinkRecords(req_headers):
      async with aiohttp.ClientSession(trust_env=True) as session:
       idm_url = "https://example.com"
    
       tasks = []
       for id in linkIdArr:
         del_url = idm_url + id
         tasks.append(make_request(session, del_url, req_headers))
    
       results = await asyncio.gather(*tasks)
       print(results)
    
    async def make_request(session, url, req_headers):
        async with session.delete(url = url, headers = req_headers) as resp:
         return await resp.json()
    
    my_headers = {
       "Authorization": "Bearer XXX"
    }
    
    linkIdArr = ["abc", "def"....]
    
    asyncio.run(deleteLinkRecords(req_headers = my_headers))