Python package - aiohttp has a warning message "Unclosed client session"

64k views Asked by At

My code is as follows:

import asyncio
import aiohttp

urls = [
    'http://www.163.com/',
    'http://www.sina.com.cn/',
    'https://www.hupu.com/',
    'http://www.csdn.net/'
]

async def get_url_data(u):
    """
    read url data
    :param u:
    :return:
    """
    print('running ', u)
    resp = await aiohttp.ClientSession().get(url=u)
    headers = resp.headers
    print(u, headers)
    return headers


async def request_url(u):
    """
    main func
    :param u:
    :return:
    """
    res = await get_url_data(u)
    return res

loop = asyncio.get_event_loop()
task_lists = asyncio.wait([request_url(u) for u in urls])
loop.run_until_complete(task_lists)
loop.close()

When i running my code, it's display a warning message: Unclosed client session

Anybody can give me some solutions about that?

Thanks a lot

3

There are 3 answers

0
Mikhail Gerasimov On

You should use ClientSession using async context manager for proper blocking/freeing resources:

async def get_url_data(u):
    """
    read url data
    :param u:
    :return:
    """
    print('running ', u)
    async with aiohttp.ClientSession() as session:
        resp = await session.get(url=u)
        headers = resp.headers
        print(u, headers)
        return headers
2
Yuval Pruss On

You should close the connection in the end. You have 2 options:

You can close the connection manually:

import aiohttp
session = aiohttp.ClientSession()
# use the session here
session.close()

Or you can use it with a contex manager:

import aiohttp
import asyncio

async def fetch(client):
    async with client.get('http://python.org') as resp:
        assert resp.status == 200
        return await resp.text()

async def main(loop):
    async with aiohttp.ClientSession(loop=loop) as client:
        html = await fetch(client)
        print(html)

loop = asyncio.get_event_loop()
loop.run_until_complete(main(loop))

The client session supports the context manager protocol for self closing.

1
RayLuo On

If you are not using context manager, the proper way to close it would also need an await. Many answers on the internet miss that part, and few people actually notice it, presumably because most people use the more convenient context manager. But the manual await session.close() is essential when/if you are closing a class-wide session inside the tearDownClass() when doing unittesting.

import aiohttp
session = aiohttp.ClientSession()
# use the session here
await session.close()