Не могу победить ошибку RuntimeWarning: coroutine 'save_res' was never awaited
Имеется неторая струкутура файлов:
some_project
│
├───some_files
│ ├───save_res.py
│ ├───some_class_1.py
│ └───some_class_.py
└───
some_class_1.py
import asyncio
import aiohttp
class SomeClass1:
def __init__(self, key=''):
self.key = key
print(f'SomeClass1 got {self.key}')
# описание класса
async def foo_1(self, url):
async with aiohttp.ClientSession() as s:
async with s.get(url) as r:
res = await r.text()
return res
async def foo_2(self, res):
if res:
await asyncio.sleep(1)
print('SomeClass1.foo_2 got the results')
# некоторые действия
some_result = [1, 1, 1]
return some_result
async def launch(self):
res = await self.foo_1('https://www.ya.ru')
next_res = await self.foo_2(res)
print('SomeClass1 is complete')
return next_res
some_class_2.py
import asyncio
import aiohttp
class SomeClass2:
def __init__(self, key=''):
self.key = key
print(f'SomeClass2 got {self.key}')
# описание класса
async def foo_1(self, url):
async with aiohttp.ClientSession() as s:
async with s.get(url) as r:
res = await r.text()
return res
async def foo_2(self, res):
if res:
await asyncio.sleep(1)
print('SomeClass2.foo_2 got the results')
# некоторые действия
some_result = [2, 2, 2]
return some_result
async def launch(self):
res = await self.foo_1('https://www.ya.ru')
next_res = await self.foo_2(res)
print('SomeClass2 is complete')
return next_res
save_res.py
import asyncio
from .some_class_1 import SomeClass1
from .some_class_2 import SomeClass2
async def save_res(arg):
tasks = [
SomeClass1(arg).launch(),
SomeClass2(arg).launch()
]
result = []
res = await asyncio.gather(*tasks)
for r in res:
if r:
result.extend(r)
print(result)
# сохранение результата в базу данных
return
some_sync_func.py
from some_files.save_res import save_res
def some_sync_func(data):
arg = data['key']
save_res(arg)
# некоторые действия
return print('All is ok, baddy!')
if __name__ == '__main__':
some_sync_func({'key':'value'})
Вызов функции some_sync_func() вызывает ошибку:
C:\some_project\some_sync_func.py:5: RuntimeWarning: coroutine 'save_res' was never awaited
save_res(arg)
RuntimeWarning: Enable tracemalloc to get the object allocation traceback
All is ok, baddy!
Я понимаю, что запускаю асинхронную функцию из синхронной, но не понимаю как это исправить. Так же интересует как эффективно при помощи какого-нибудь flag остановить выполнение tasks в любой момент. Проблема в том, что сама функция смены flag находится в some_sync_func.py. Можно, к примеру, добавить её в tasks, а в функции launch() классов SomeClass1 и SomeClass2 сделать проверку flag.
Ответы (1 шт):
Если это код работает с django, то https://docs.djangoproject.com/en/4.0/topics/async/#async-to-sync
from asgiref.sync import async_to_sync
async_to_sync(save_res(arg))
У джанги нет событийного цикла если она запущенна на runserver или wsgi. есть пул тредов и каджый запрос обрабатывается в своем треде. Для совместимости с asyncio сделали модуль asgiref.sync