How to resolve RuntimeError: await wasn't used with future using aiohttp and asyncio in python?
How to resolve RuntimeError: await wasn't used with future using aiohttp and asyncio in python?
我制作了一些非常简单的脚本,可以从 clicky.com api 中提取数据,但由于某些原因,它有时无法正常工作。
有时会得到结果,但有时我会收到以下无法调试的错误。我对 asyncio 和 aiohttp
还很陌生
Traceback (most recent call last):
File "/Users/almeco/Downloads/python/_projekty/projekt_baza_review/1_stable/asy/usable/baza_goals.py", line 118, in <module>
goals_results_last_week = asyncio.run(goals_clicky_results_last_week())
File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/asyncio/runners.py", line 44, in run
return loop.run_until_complete(main)
File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/asyncio/base_events.py", line 641, in run_until_complete
return future.result()
File "/Users/almeco/Downloads/python/_projekty/projekt_baza_review/1_stable/asy/usable/baza_goals.py", line 82, in goals_clicky_results_last_week
responses_clicky_goals = await asyncio.gather(*tasks_goals)
File "/Users/almeco/Downloads/python/_projekty/projekt_baza_review/venv/lib/python3.10/site-packages/aiohttp/client.py", line 1122, in send
return self._coro.send(arg)
File "/Users/almeco/Downloads/python/_projekty/projekt_baza_review/venv/lib/python3.10/site-packages/aiohttp/client.py", line 535, in _request
conn = await self._connector.connect(
File "/Users/almeco/Downloads/python/_projekty/projekt_baza_review/venv/lib/python3.10/site-packages/aiohttp/connector.py", line 542, in connect
proto = await self._create_connection(req, traces, timeout)
File "/Users/almeco/Downloads/python/_projekty/projekt_baza_review/venv/lib/python3.10/site-packages/aiohttp/connector.py", line 907, in _create_connection
_, proto = await self._create_direct_connection(req, traces, timeout)
File "/Users/almeco/Downloads/python/_projekty/projekt_baza_review/venv/lib/python3.10/site-packages/aiohttp/connector.py", line 1175, in _create_direct_connection
transp, proto = await self._wrap_create_connection(
File "/Users/almeco/Downloads/python/_projekty/projekt_baza_review/venv/lib/python3.10/site-packages/aiohttp/connector.py", line 986, in _wrap_create_connection
return await self._loop.create_connection(*args, **kwargs) # type: ignore[return-value] # noqa
File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/asyncio/base_events.py", line 1040, in create_connection
sock = await self._connect_sock(
File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/asyncio/base_events.py", line 954, in _connect_sock
await self.sock_connect(sock, address)
File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/asyncio/selector_events.py", line 502, in sock_connect
return await fut
RuntimeError: await wasn't used with future
如何调试?这里有什么问题?
编辑:
这是我的代码供您测试:
import asyncio
import datetime
import aiohttp
import requests
start_operacji = datetime.datetime.now()
print('start', start_operacji)
date_filename = datetime.datetime.now().strftime('%d-%m_%H-%M')
def goals_clicky_tasks_last_week(session):
tasks_clicky_goals = []
# todo to mozna by jeszcze dać do asyncio
clicky_auth = requests.get(
'https://api.clicky.com/api/account/sites?username=meeffe&password=hAs!23cy&output=json')
auth_jsonised = clicky_auth.json()
list_site_id_sitekey_dict = []
for k in auth_jsonised:
site_id_sitekey_dict = {'site_id': k['site_id'], 'sitekey': k['sitekey']}
list_site_id_sitekey_dict.append(site_id_sitekey_dict)
for auth_item in list_site_id_sitekey_dict:
goal_url = f"https://api.clicky.com/api/stats/4?site_id={auth_item['site_id']}&sitekey={auth_item['sitekey']}&type=goals&date=today&limit=1000&output=json"
tasks_clicky_goals.append(asyncio.ensure_future(session.get(goal_url, ssl=False)))
return tasks_clicky_goals
async def goals_clicky_results_last_week():
list_final_goals = []
async with aiohttp.ClientSession() as session:
tasks_goals = goals_clicky_tasks_last_week(session)
responses_clicky_goals = await asyncio.gather(*tasks_goals)
for response_clicky_goal in responses_clicky_goals:
clicky_data = await response_clicky_goal.json(content_type=None)
goals_list = []
for url_item_goal in clicky_data[0]['dates'][0]['items']:
if url_item_goal['conversion'] != '':
if url_item_goal['title'].startswith(
'http'): # nie bierze pod uwagę goalsów które zawierają U - https:// etc
goals_dict = {'url': url_item_goal['title'].replace('http://', 'https://'),
'goals': url_item_goal['value'],
'ad_ctr': url_item_goal['conversion']
}
goals_list.append(goals_dict)
else:
continue
else:
continue
list_final_goals.append(goals_list)
flattened_list_final_goals = [val for sublist in list_final_goals for val in sublist]
return flattened_list_final_goals
print(asyncio.run(goals_clicky_results_last_week()), 'goals_clicky_results_last_week')
goals_results_last_week = asyncio.run(goals_clicky_results_last_week())
######################################################################
end = datetime.datetime.now() - start_operacji
print('Ready:)!')
print('It took: ', end)
其实我自己找到了解决办法
- 我使用了 httpx
而不是 aiohttp
- 我对每个请求都使用了超时
- 我删除了不必要的 await
以下原始代码的更改。现在脚本 运行 100% 稳定。坦率地说,我不确定这些更改中的哪一个影响最大,但它按预期工作。
timeout = httpx.Timeout(60.0, connect=60.0)
async with httpx.AsyncClient(verify=False, timeout=timeout) as session:
tasks_goals = goals_clicky_tasks_last_week(session)
responses_clicky_goals = await asyncio.gather(*tasks_goals)
for response_clicky_goal in responses_clicky_goals:
clicky_data = response_clicky_goal.json()
...
我制作了一些非常简单的脚本,可以从 clicky.com api 中提取数据,但由于某些原因,它有时无法正常工作。
有时会得到结果,但有时我会收到以下无法调试的错误。我对 asyncio 和 aiohttp
还很陌生Traceback (most recent call last):
File "/Users/almeco/Downloads/python/_projekty/projekt_baza_review/1_stable/asy/usable/baza_goals.py", line 118, in <module>
goals_results_last_week = asyncio.run(goals_clicky_results_last_week())
File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/asyncio/runners.py", line 44, in run
return loop.run_until_complete(main)
File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/asyncio/base_events.py", line 641, in run_until_complete
return future.result()
File "/Users/almeco/Downloads/python/_projekty/projekt_baza_review/1_stable/asy/usable/baza_goals.py", line 82, in goals_clicky_results_last_week
responses_clicky_goals = await asyncio.gather(*tasks_goals)
File "/Users/almeco/Downloads/python/_projekty/projekt_baza_review/venv/lib/python3.10/site-packages/aiohttp/client.py", line 1122, in send
return self._coro.send(arg)
File "/Users/almeco/Downloads/python/_projekty/projekt_baza_review/venv/lib/python3.10/site-packages/aiohttp/client.py", line 535, in _request
conn = await self._connector.connect(
File "/Users/almeco/Downloads/python/_projekty/projekt_baza_review/venv/lib/python3.10/site-packages/aiohttp/connector.py", line 542, in connect
proto = await self._create_connection(req, traces, timeout)
File "/Users/almeco/Downloads/python/_projekty/projekt_baza_review/venv/lib/python3.10/site-packages/aiohttp/connector.py", line 907, in _create_connection
_, proto = await self._create_direct_connection(req, traces, timeout)
File "/Users/almeco/Downloads/python/_projekty/projekt_baza_review/venv/lib/python3.10/site-packages/aiohttp/connector.py", line 1175, in _create_direct_connection
transp, proto = await self._wrap_create_connection(
File "/Users/almeco/Downloads/python/_projekty/projekt_baza_review/venv/lib/python3.10/site-packages/aiohttp/connector.py", line 986, in _wrap_create_connection
return await self._loop.create_connection(*args, **kwargs) # type: ignore[return-value] # noqa
File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/asyncio/base_events.py", line 1040, in create_connection
sock = await self._connect_sock(
File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/asyncio/base_events.py", line 954, in _connect_sock
await self.sock_connect(sock, address)
File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/asyncio/selector_events.py", line 502, in sock_connect
return await fut
RuntimeError: await wasn't used with future
如何调试?这里有什么问题?
编辑: 这是我的代码供您测试:
import asyncio
import datetime
import aiohttp
import requests
start_operacji = datetime.datetime.now()
print('start', start_operacji)
date_filename = datetime.datetime.now().strftime('%d-%m_%H-%M')
def goals_clicky_tasks_last_week(session):
tasks_clicky_goals = []
# todo to mozna by jeszcze dać do asyncio
clicky_auth = requests.get(
'https://api.clicky.com/api/account/sites?username=meeffe&password=hAs!23cy&output=json')
auth_jsonised = clicky_auth.json()
list_site_id_sitekey_dict = []
for k in auth_jsonised:
site_id_sitekey_dict = {'site_id': k['site_id'], 'sitekey': k['sitekey']}
list_site_id_sitekey_dict.append(site_id_sitekey_dict)
for auth_item in list_site_id_sitekey_dict:
goal_url = f"https://api.clicky.com/api/stats/4?site_id={auth_item['site_id']}&sitekey={auth_item['sitekey']}&type=goals&date=today&limit=1000&output=json"
tasks_clicky_goals.append(asyncio.ensure_future(session.get(goal_url, ssl=False)))
return tasks_clicky_goals
async def goals_clicky_results_last_week():
list_final_goals = []
async with aiohttp.ClientSession() as session:
tasks_goals = goals_clicky_tasks_last_week(session)
responses_clicky_goals = await asyncio.gather(*tasks_goals)
for response_clicky_goal in responses_clicky_goals:
clicky_data = await response_clicky_goal.json(content_type=None)
goals_list = []
for url_item_goal in clicky_data[0]['dates'][0]['items']:
if url_item_goal['conversion'] != '':
if url_item_goal['title'].startswith(
'http'): # nie bierze pod uwagę goalsów które zawierają U - https:// etc
goals_dict = {'url': url_item_goal['title'].replace('http://', 'https://'),
'goals': url_item_goal['value'],
'ad_ctr': url_item_goal['conversion']
}
goals_list.append(goals_dict)
else:
continue
else:
continue
list_final_goals.append(goals_list)
flattened_list_final_goals = [val for sublist in list_final_goals for val in sublist]
return flattened_list_final_goals
print(asyncio.run(goals_clicky_results_last_week()), 'goals_clicky_results_last_week')
goals_results_last_week = asyncio.run(goals_clicky_results_last_week())
######################################################################
end = datetime.datetime.now() - start_operacji
print('Ready:)!')
print('It took: ', end)
其实我自己找到了解决办法
- 我使用了 httpx 而不是 aiohttp
- 我对每个请求都使用了超时
- 我删除了不必要的 await
以下原始代码的更改。现在脚本 运行 100% 稳定。坦率地说,我不确定这些更改中的哪一个影响最大,但它按预期工作。
timeout = httpx.Timeout(60.0, connect=60.0)
async with httpx.AsyncClient(verify=False, timeout=timeout) as session:
tasks_goals = goals_clicky_tasks_last_week(session)
responses_clicky_goals = await asyncio.gather(*tasks_goals)
for response_clicky_goal in responses_clicky_goals:
clicky_data = response_clicky_goal.json()
...