Ошибка You cannot call this from an async context - use a thread or sync_to_async. Django
У меня есть скрипт который слушает вебсокет, парсит приходящие данные и должен добавлять в базу данных обьект. Скрипт я запускаю вместе с сервером. Пишет что нужно использовать sync_to_asyc, что я и делаю. Код скрипта:
from django.core.management.base import BaseCommand, CommandError
from django_q.tasks import async_task
from asgiref.sync import sync_to_async
from django.core.exceptions import SynchronousOnlyOperation
import asyncio
import json
import django
import websockets
import os
import sys
from client.models import Call, ClientEvents
from users.models import User
async def main():
async with websockets.connect('wss://ws.binotel.com:9002') as client:
await client.send(message)
data = json.loads(await client.recv())
print(data)
await client.send(message)
data = json.loads(await client.recv())
print(data)
while True:
msg = await client.recv()
print(msg)
try:
parse_call(msg)
except SynchronousOnlyOperation:
for user in await get_all_users():
print(user)
@sync_to_async
def get_all_users():
return User.objects.all()
def parse_call(msg):
k=json.loads(msg)
if type(k) is dict:
try:
if int(k['callType']) == 0:
type_call = "IN"
else:
type_call = "OUT"
except KeyError:
pass
try:
if 'Телефонный звонок' not in k['customerName']:
print(1)
fisrt_name = k['customerName'].split(' ')[1]
last_name = k['customerName'].split(' ')[0]
user = sync_to_async(User.objects.filter(first_name =fisrt_name, last_name=last_name).first())
print(2)
call = Call(type = type_call, phone_number = k['externalNumber'])
print(3)
call.save()
print(4)
call.contact.add(user)
except KeyError:
pass
try:
call ={
'type':1,
'phone':k['externalNumber']
}
except KeyError:
pass
class Command(BaseCommand):
help = 'Listen Binotel websokets'
def handle(self, *args, **options):
sys.path.append("D:\work\snapt\snapt-crm")
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'snapt_crm.settings')
django.setup()
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
asyncio.get_event_loop().run_until_complete(main())
Ошибка:
Exception in thread django-main-thread:
Traceback (most recent call last):
File "C:\Users\User\.virtualenvs\snapt-crm-T_dZIZfo\lib\site-packages\asgiref\sync.py", line 451, in thread_handler
raise exc_info[1]
File "D:\work\snapt\snapt-crm\binotel_calls\management\commands\listen.py", line 34, in main
parse_call(msg)
File "D:\work\snapt\snapt-crm\binotel_calls\management\commands\listen.py", line 60, in parse_call
user = sync_to_async(User.objects.filter(first_name =fisrt_name, last_name=last_name).first())
File "C:\Users\User\.virtualenvs\snapt-crm-T_dZIZfo\lib\site-packages\django\db\models\query.py", line 682, in first
for obj in (self if self.ordered else self.order_by('pk'))[:1]:
File "C:\Users\User\.virtualenvs\snapt-crm-T_dZIZfo\lib\site-packages\django\db\models\query.py", line 280, in __iter__
self._fetch_all()
File "C:\Users\User\.virtualenvs\snapt-crm-T_dZIZfo\lib\site-packages\django\db\models\query.py", line 1354, in _fetch_all
self._result_cache = list(self._iterable_class(self))
File "C:\Users\User\.virtualenvs\snapt-crm-T_dZIZfo\lib\site-packages\django\db\models\query.py", line 51, in __iter__
results = compiler.execute_sql(chunked_fetch=self.chunked_fetch, chunk_size=self.chunk_size)
File "C:\Users\User\.virtualenvs\snapt-crm-T_dZIZfo\lib\site-packages\django\db\models\sql\compiler.py", line 1200, in execute_sql
cursor = self.connection.cursor()
File "C:\Users\User\.virtualenvs\snapt-crm-T_dZIZfo\lib\site-packages\django\utils\asyncio.py", line 23, in inner
raise SynchronousOnlyOperation(message)
django.core.exceptions.SynchronousOnlyOperation: You cannot call this from an async context - use a thread or sync_to_async.
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "c:\python\lib\threading.py", line 954, in _bootstrap_inner
self.run()
File "c:\python\lib\threading.py", line 892, in run
self._target(*self._args, **self._kwargs)
File "C:\Users\User\.virtualenvs\snapt-crm-T_dZIZfo\lib\site-packages\django\utils\autoreload.py", line 64, in wrapper
fn(*args, **kwargs)
File "C:\Users\User\.virtualenvs\snapt-crm-T_dZIZfo\lib\site-packages\channels\management\commands\runserver.py", line 75, in inner_run
self.check(display_num_errors=True)
File "C:\Users\User\.virtualenvs\snapt-crm-T_dZIZfo\lib\site-packages\django\core\management\base.py", line 438, in check
all_issues = checks.run_checks(
File "C:\Users\User\.virtualenvs\snapt-crm-T_dZIZfo\lib\site-packages\django\core\checks\registry.py", line 77, in run_checks
new_errors = check(app_configs=app_configs, databases=databases)
File "C:\Users\User\.virtualenvs\snapt-crm-T_dZIZfo\lib\site-packages\django\core\checks\urls.py", line 13, in check_url_config
return check_resolver(resolver)
File "C:\Users\User\.virtualenvs\snapt-crm-T_dZIZfo\lib\site-packages\django\core\checks\urls.py", line 23, in check_resolver
return check_method()
File "C:\Users\User\.virtualenvs\snapt-crm-T_dZIZfo\lib\site-packages\django\urls\resolvers.py", line 448, in check
for pattern in self.url_patterns:
File "C:\Users\User\.virtualenvs\snapt-crm-T_dZIZfo\lib\site-packages\django\utils\functional.py", line 48, in __get__
res = instance.__dict__[self.name] = self.func(instance)
File "C:\Users\User\.virtualenvs\snapt-crm-T_dZIZfo\lib\site-packages\django\urls\resolvers.py", line 634, in url_patterns
patterns = getattr(self.urlconf_module, "urlpatterns", self.urlconf_module)
File "C:\Users\User\.virtualenvs\snapt-crm-T_dZIZfo\lib\site-packages\django\utils\functional.py", line 48, in __get__
res = instance.__dict__[self.name] = self.func(instance)
File "C:\Users\User\.virtualenvs\snapt-crm-T_dZIZfo\lib\site-packages\django\urls\resolvers.py", line 627, in urlconf_module
return import_module(self.urlconf_name)
File "c:\python\lib\importlib\__init__.py", line 127, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "<frozen importlib._bootstrap>", line 1030, in _gcd_import
File "<frozen importlib._bootstrap>", line 1007, in _find_and_load
File "<frozen importlib._bootstrap>", line 986, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 680, in _load_unlocked
File "<frozen importlib._bootstrap_external>", line 790, in exec_module
File "<frozen importlib._bootstrap>", line 228, in _call_with_frames_removed
File "D:\work\snapt\snapt-crm\snapt_crm\urls.py", line 33, in <module>
path('binotel/', include('binotel_calls.urls')),
File "C:\Users\User\.virtualenvs\snapt-crm-T_dZIZfo\lib\site-packages\django\urls\conf.py", line 34, in include
urlconf_module = import_module(urlconf_module)
File "c:\python\lib\importlib\__init__.py", line 127, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "<frozen importlib._bootstrap>", line 1030, in _gcd_import
File "<frozen importlib._bootstrap>", line 1007, in _find_and_load
File "<frozen importlib._bootstrap>", line 986, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 680, in _load_unlocked
File "<frozen importlib._bootstrap_external>", line 790, in exec_module
File "<frozen importlib._bootstrap>", line 228, in _call_with_frames_removed
File "D:\work\snapt\snapt-crm\binotel_calls\urls.py", line 16, in <module>
call_command('listen')
File "C:\Users\User\.virtualenvs\snapt-crm-T_dZIZfo\lib\site-packages\django\core\management\__init__.py", line 187, in call_command
return command.execute(*args, **defaults)
File "C:\Users\User\.virtualenvs\snapt-crm-T_dZIZfo\lib\site-packages\django\core\management\base.py", line 417, in execute
output = self.handle(*args, **options)
File "D:\work\snapt\snapt-crm\binotel_calls\management\commands\listen.py", line 89, in handle
asyncio.get_event_loop().run_until_complete(main())
File "c:\python\lib\asyncio\base_events.py", line 642, in run_until_complete
return future.result()
File "D:\work\snapt\snapt-crm\binotel_calls\management\commands\listen.py", line 36, in main
for user in await get_all_users():
File "C:\Users\User\.virtualenvs\snapt-crm-T_dZIZfo\lib\site-packages\django\db\models\query.py", line 280, in __iter__
self._fetch_all()
File "C:\Users\User\.virtualenvs\snapt-crm-T_dZIZfo\lib\site-packages\django\db\models\query.py", line 1354, in _fetch_all
self._result_cache = list(self._iterable_class(self))
File "C:\Users\User\.virtualenvs\snapt-crm-T_dZIZfo\lib\site-packages\django\db\models\query.py", line 51, in __iter__
results = compiler.execute_sql(chunked_fetch=self.chunked_fetch, chunk_size=self.chunk_size)
File "C:\Users\User\.virtualenvs\snapt-crm-T_dZIZfo\lib\site-packages\django\db\models\sql\compiler.py", line 1200, in execute_sql
cursor = self.connection.cursor()
File "C:\Users\User\.virtualenvs\snapt-crm-T_dZIZfo\lib\site-packages\django\utils\asyncio.py", line 23, in inner
raise SynchronousOnlyOperation(message)
django.core.exceptions.SynchronousOnlyOperation: You cannot call this from an async context - use a thread or sync_to_async.