Zhe Xiao
Zhe Xiao

Reputation: 494

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

My code is as follows:

import asyncio
import aiohttp

urls = [
    'http://www.163.com/',
    'http://www.sina.com.cn/',
]

async def get_url_data(u):
    resp = await aiohttp.ClientSession().get(url=u)
    headers = resp.headers
    return headers


async def request_url(u):
    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?

Upvotes: 26

Views: 78331

Answers (4)

Yuval Pruss
Yuval Pruss

Reputation: 9856

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
await session.close()

Or you can use it with a context 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.

Upvotes: 32

Vladyslav
Vladyslav

Reputation: 21

Read this pls: https://docs.aiogram.dev/en/latest/api/session/aiohttp.html

from aiogram import Bot
from aiogram.client.session.aiohttp import AiohttpSession

session = AiohttpSession()
bot = Bot('token', session=session)

That will solve your problem. And yes, the session does not need to be closed

Upvotes: 1

RayLuo
RayLuo

Reputation: 19300

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()

Upvotes: 14

Mikhail Gerasimov
Mikhail Gerasimov

Reputation: 39596

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

Upvotes: 7

Related Questions