Bearle / django-private-chat

(Deprecated - Please check out https://github.com/Bearle/django_private_chat2) Django one-to-one Websocket-based Asyncio-handled chat, developed by Bearle team
ISC License
424 stars 132 forks source link

SynchronousOnlyOperation error with python 3.7 #54

Open kopy-kat opened 4 years ago

kopy-kat commented 4 years ago

Description

I first tried to implement django-private-chat into an existing project which did not work. To figure out what my problem was, I tried to run the example project and encountered the same problem.

What I Did

I ran both run_server and run_chat_server without errors. Upon trying to send a message I got the following error.

25.04.20 10:45:49:ERROR:Error in connection handler
Traceback (most recent call last):
  File "/opt/anaconda3/envs/testEnv/lib/python3.7/site-packages/websockets/server.py", line 191, in handler
    await self.ws_handler(self, path)
  File "/opt/anaconda3/envs/testEnv/lib/python3.7/site-packages/django_private_chat/handlers.py", line 259, in main_handler
    user_owner = get_user_from_session(session_id)
  File "/opt/anaconda3/envs/testEnv/lib/python3.7/site-packages/django_private_chat/utils.py", line 15, in get_user_from_session
    session = Session.objects.get(session_key=session_key)
  File "/opt/anaconda3/envs/testEnv/lib/python3.7/site-packages/django/db/models/manager.py", line 82, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "/opt/anaconda3/envs/testEnv/lib/python3.7/site-packages/django/db/models/query.py", line 411, in get
    num = len(clone)
  File "/opt/anaconda3/envs/testEnv/lib/python3.7/site-packages/django/db/models/query.py", line 258, in __len__
    self._fetch_all()
  File "/opt/anaconda3/envs/testEnv/lib/python3.7/site-packages/django/db/models/query.py", line 1261, in _fetch_all
    self._result_cache = list(self._iterable_class(self))
  File "/opt/anaconda3/envs/testEnv/lib/python3.7/site-packages/django/db/models/query.py", line 57, in __iter__
    results = compiler.execute_sql(chunked_fetch=self.chunked_fetch, chunk_size=self.chunk_size)
  File "/opt/anaconda3/envs/testEnv/lib/python3.7/site-packages/django/db/models/sql/compiler.py", line 1142, in execute_sql
    cursor = self.connection.cursor()
  File "/opt/anaconda3/envs/testEnv/lib/python3.7/site-packages/django/utils/asyncio.py", line 24, in inner
    raise SynchronousOnlyOperation(message)
django.core.exceptions.SynchronousOnlyOperation: You cannot call this from an async context - use a thread or sync_to_async.
25.04.20 10:45:49:DEBUG:server ! failing OPEN WebSocket connection with code 1011
25.04.20 10:45:49:DEBUG:server - state = CLOSING
25.04.20 10:45:49:DEBUG:server > Frame(fin=True, opcode=8, data=b'\x03\xf3', rsv1=False, rsv2=False, rsv3=False)
25.04.20 10:45:49:DEBUG:server x half-closing TCP connection
25.04.20 10:45:49:DEBUG:server - event = connection_lost(None)
25.04.20 10:45:49:DEBUG:server - state = CLOSED
25.04.20 10:45:49:DEBUG:server x code = 1006, reason = [no reason]
Gilbishkosma commented 4 years ago

i got the same error ,can anyone look at it.

delneg commented 4 years ago

Check updated package - 0.3.0 I've to tried to get it working with django 3.0.5 but had not luck atm I've played sync_to_async wrapper for an hour but didn't manage to get it going Feel free to submit the PR if you have more luck The package is only compatible with Django < 3.0 atm

Gilbishkosma commented 4 years ago

Thanks, i will try the django version < 3.0

Bensebabillal commented 4 years ago

I don't know if it's bug in Django, but in version 3.0.1 Django add with a new setting to skip the async_unsafe check. so juste add : os.environ["DJANGO_ALLOW_ASYNC_UNSAFE"] = "true" in your Django settings . I hope that's will help you . Once the ORM gets async support probably have to rewrite the project to support it

jgslunde commented 4 years ago

Does anyone know if this is simply Django 3 being more aggressive than Django 2 in checking for async-unsafe operations, or if it is actually less safe than it was in Django 2? Is setting os.environ["DJANGO_ALLOW_ASYNC_UNSAFE"] = "true" a very bad solution to this problem, or should it then run exactly as it does in Django 2?