web-dev-qa-db-fra.com

Python package - aiohttp a un message d'avertissement "Session client non fermée"

Mon code est le suivant:

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

Lorsque j'exécute mon code, il affiche un message d'avertissement: session client non fermée

Quelqu'un peut-il me donner des solutions à ce sujet?

Merci beaucoup

7
Zhe Xiao

Vous devez fermer la connexion à la fin. Vous avez 2 options:

Vous pouvez fermer la connexion manuellement:

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

Ou vous pouvez l'utiliser avec un gestionnaire de contexte:

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

La session client prend en charge le protocole du gestionnaire de contexte pour la fermeture automatique.

12
Yuval Pruss

Vous devez utiliser ClientSession en utilisant le gestionnaire de contexte asynchrone pour les ressources de blocage/libération appropriées:

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
Mikhail Gerasimov

Si vous n'utilisez pas le gestionnaire de contexte, la bonne façon de le fermer aurait également besoin d'un await. Beaucoup de réponses sur Internet manquent cette partie, et peu de gens le remarquent, probablement parce que la plupart des gens utilisent le gestionnaire de contexte plus pratique. Mais le manuel await session.close() est essentiel lorsque/si vous fermez une session à l'échelle de la classe à l'intérieur de tearDownClass() lorsque vous faites unittesting.

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