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
asked Sep 8, 2017 at 9:14
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.
answered Sep 8, 2017 at 16:18
Yuval PrussYuval Pruss
8,11813 gold badges42 silver badges66 bronze badges
1
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 unittest
ing.
import aiohttp
session = aiohttp.ClientSession()
# use the session here
await session.close()
answered Feb 21, 2020 at 5:50
RayLuoRayLuo
16.3k5 gold badges84 silver badges71 bronze badges
1
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
answered Sep 8, 2017 at 10:20
Mikhail GerasimovMikhail Gerasimov
35.1k16 gold badges111 silver badges155 bronze badges
Issue
I’m trying to make command to discord bot ,that takes list from this script and send one random from them.I started program in Python about month ago soo it’s actually pretty hard for me.
Problem is that when i run this script appears error : Unclosed client session
client_session: <aiohttp.client.ClientSession object at 0x000002EE51BE5B80>
import asyncpraw
import asyncio
from aiohttp import ClientSession
async def get_meme(posses=100):
posts = []
async with ClientSession() as session:
async for subreddit in subreddits:
sub = await reddit.subreddit(subreddit).top(limit=posses, time_filter="week")
for post in sub:
await posts.append(post.url)
await session.close()
return posts
async def main():
task = asyncio.create_task(get_meme())
reddit_memes = await task
print(reddit_memes)
Solution
I can see that you are trying to make a meme command. I would recommend asyncpraw the reddit API. Here is a simple example :-
import asyncpraw #Register at https://www.reddit.com/prefs/apps
reddit = asyncpraw.Reddit(client_id = 'client_id',
client_secret = 'client_secret',
username = 'username',
password = 'password',
user_agent = 'user_agent')
@client.command()
async def meme(ctx):
subreddit = await reddit.subreddit("memes")
all_subs = []
top = subreddit.top(limit = 100)
async for submission in top:
all_subs.append(submission)
random_sub = random.choice(all_subs)
name = random_sub.title
url = random_sub.url
link = random_sub.permalink
embed = discord.Embed(title=name color=ctx.author.color)
embed.set_image(url=url)
await ctx.send(embed=embed)
Answered By — ChaoticNebula
У меня есть test.py
файл и AsyncioCurl.py
файл.
Я уже использую session
вместо просто aiohttp.request
Но это также дает мне эту ошибку:
Unclosed client session
client_session: <aiohttp.client.ClientSession object at 0x000001FAEFEA7DA0>
Unclosed connector
connections: ['[(<aiohttp.client_proto.ResponseHandler object at 0x000001FAF10AC648>, 119890.906)]']
connector: <aiohttp.connector.TCPConnector object at 0x000001FAF0F702B0>
test.py
import asyncio
from AsyncioCurl import AsyncioCurl
async def a():
payload = {}
url = "https://awebsiteisthere.com"
data = await AsyncioCurl().get(url,payload)
print(data)
task = [
a()
]
loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait(task))
< Сильный > AsyncioCurl.py
import asyncio
import aiohttp
from Log import Log
from Base import sign
from config import config
class AsyncioCurl:
def __init__(self):
self.session = aiohttp.ClientSession(timeout=aiohttp.ClientTimeout(total=4))
async def get(self,url,param):
Log.debug("GET: "+url)
payload = {
"cookie":config["Token"]["COOKIE"]
}
payload = dict(param,**payload)
payload = sign(payload)
async with self.session.get(url,params=payload) as r:
Log.debug(r.status)
return await r.json()
async def post(self,url,param):
async with sem:
Log.debug("POST: "+url)
payload = {
"cookie":config["Token"]["COOKIE"]
}
payload = dict(param,**payload)
payload = sign(payload)
async with self.session.post(url,data=payload) as r:
return await r.json()
async def nspost(self,url,param):
Log.debug("POST: "+url)
headers = {
"Accept":"application/json, text/plain, */*",
"User-Agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36",
"Accept-Language":"zh-CN,zh;q=0.9",
"accept-encoding":"gzip, deflate",
"cookie":config["Token"]["COOKIE"]
}
async with self.session.post(url,data=param,headers=headers) as r:
return await r.json()
async def nsdpost(self,url):
Log.debug("POST: "+url)
headers = {
"Accept":"application/json, text/plain, */*",
"User-Agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36",
"Accept-Language":"zh-CN,zh;q=0.9",
"accept-encoding":"gzip, deflate",
"cookie":config["Token"]["COOKIE"]
}
async with self.session.post(url,headers=headers) as r:
return await r.json()
2 ответа
Лучший ответ
Это не ошибка, просто предупреждение. И вы можете справиться с этим, закрыв сессию. Попробуй это:
async def a():
payload = {}
url = "https://awebsiteisthere.com"
curl = AsyncioCurl()
data = await curl.get(url,payload)
print(data)
await curl.session.close() # this
2
sanyassh
21 Фев 2019 в 15:29
Я только что добавил close()
в конец вашего test.py
скрипта
import asyncio
from AsyncioCurl import AsyncioCurl
async def a():
payload = {}
url = "https://awebsiteisthere.com"
data = await AsyncioCurl().get(url,payload)
print(data)
await AsyncioCurl.close() #added this line
task = [
a()
]
loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait(task))
0
Ced
11 Фев 2020 в 12:57
662 исправляет это для run_async=False
(по умолчанию используется False, поэтому вы используете режим False, если вы явно не указываете этот параметр), поскольку режим синхронизации больше не зависит от библиотеки aiohttp.
@seratch Я использовал его в асинхронном режиме (забыл указать). Это что-то меняет?
@jourdanrodrigues Спасибо за ответ. В этом случае это может все еще существовать в зависимости от вопросов, связанных с aiohttp. Позвольте мне снова открыть это и удалить веху v2.6.0.
Имея ту же проблему, try-except поймал asyncio.TimeoutError
и в конце он показал «Незакрытый сеанс клиента»,
try:
await slack_client.chat_postMessage(...)
except Exception:
logger.exception(f'failed to post message')
После некоторого расследования кажется, что исключение может быть вызвано внутри инструкции async with, https://github.com/slackapi/python-slackclient/blob/v2.3.1/slack/web/base_client.py#L259
Итак, можем ли мы использовать оператор try-finally, чтобы убедиться, что сеанс клиента aiohttp правильно закрыт? Я провел несколько тестов локально, похоже, в моем случае это работает,
try:
async with session.request(http_verb, api_url, **req_args) as res:
data = {}
try:
data = await res.json()
except aiohttp.ContentTypeError:
self._logger.debug(
f"No response data returned from the following API call: {api_url}."
)
response = {"data": data, "headers": res.headers, "status_code": res.status}
finally:
if not use_running_session:
await session.close()
@NoAnyLove Спасибо, что поделились этим! Мне тоже нравится ваше предложение. Чтобы продвинуться вперед, я хочу иметь модульный тест, который всегда сначала воспроизводит ситуацию, а затем хотел бы применить его исправление в качестве допустимого решения. Если вам интересно работать над обоими, я буду рад рассмотреть и объединить их. Если вы заняты, я, вероятно, поработаю над этим на следующей неделе.
Спасибо за быстрый ответ. Постараюсь поработать на выходных.
Была ли эта страница полезной?
0 / 5 — 0 рейтинги
feature/asyncio: Unclosed client session
Describe the bug
I simply instantiate AsyncClient like demonstrated in readme, and its usage is always followed with an «Unclosed client session» error.
To Reproduce
import asyncio
from binance import AsyncClient
async def main():
client = await AsyncClient.create()
print(await client.get_server_time())
if __name__ == '__main__':
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
Output:
Unclosed client session
client_session: <aiohttp.client.ClientSession object at 0x0000029492976A58>
Unclosed connector
connections: ['[(<aiohttp.client_proto.ResponseHandler object at 0x000002949290DE88>, 3463537.656)]']
connector: <aiohttp.connector.TCPConnector object at 0x0000029492976AC8>
{'serverTime': 1566977521778}
Expected behavior
Expected not to have errors. Should I somehow gracefully close/destroy AsyncClient?
Environment (please complete the following information):
- Python version: 3.7
- OS: Windows 10
- python-binance: 0.7.3-asyncio, cloned from the repository: 00dc9a9
Yep same here. There’s no AsyncClient and also the DepthCacheManager and BinanceSocketManager are elsewhere.
from binance.depthcache import DepthCacheManager
from binance.websockets import BinanceSocketManager
…perhaps?
@sapph1re did you find a fix / workaround for this?
@sapph1re did you find a fix / workaround for this?
sorry, my previous (deleted) answer was misleading.
I made a stop()
method in the exchange wrapper class, which explicitly calls await self._client.session.close()
where self._client
is the AsyncClient instance.
I’m still getting this error. I guess it has not been fixed.