sinarezaei / django-telethon-session

MIT License
12 stars 3 forks source link

SynchronousOnlyOperation: You cannot call this from an async context - use a thread or sync_to_async. #4

Open alifanov opened 4 years ago

alifanov commented 4 years ago

I get an exception when I try to use DjangoSession django version is 3.1

Im [14]: sessions = DjangoSession()
In [15]: client = TelegramClient(
    ...:             session,
    ...:             api_id,
    ...:             api_hash
    ...:         )

In [16]: client.connect()
---------------------------------------------------------------------------
SynchronousOnlyOperation                  Traceback (most recent call last)
<ipython-input-16-be08c18772f3> in <module>
----> 1 client.connect()

/usr/local/lib/python3.7/site-packages/telethon/sync.py in syncified(*args, **kwargs)
     37             return coro
     38         else:
---> 39             return loop.run_until_complete(coro)
     40
     41     # Save an accessible reference to the original method

/usr/local/lib/python3.7/asyncio/base_events.py in run_until_complete(self, future)
    585             raise RuntimeError('Event loop stopped before Future completed.')
    586
--> 587         return future.result()
    588
    589     def stop(self):

/usr/local/lib/python3.7/site-packages/telethon/client/telegrambaseclient.py in connect(self)
    489             return
    490
--> 491         self.session.auth_key = self._sender.auth_key
    492         self.session.save()
    493

/usr/local/lib/python3.7/site-packages/django_telethon_session/sessions.py in auth_key(self, value)
    212         # print('django session auth_key value ' + str(value.key))
    213         self._auth_key = value
--> 214         self._update_session_table()
    215
    216     @MemorySession.takeout_id.setter

/usr/local/lib/python3.7/site-packages/django_telethon_session/sessions.py in _update_session_table(self)
    230         # multiple DCs. Probably done differently.
    231         # c.execute('delete from sessions')
--> 232         TelethonSession.objects.filter(client_session_name=self.client_session_name).delete()
    233         # c.execute('insert or replace into sessions values (?,?,?,?,?)', (
    234         #     self._dc_id,

/usr/local/lib/python3.7/site-packages/django/db/models/query.py in delete(self)
    745         collector = Collector(using=del_query.db)
    746         collector.collect(del_query)
--> 747         deleted, _rows_count = collector.delete()
    748
    749         # Clear the result cache, in case this QuerySet gets reused.

/usr/local/lib/python3.7/site-packages/django/db/models/deletion.py in delete(self)
    398                 return count, {model._meta.label: count}
    399
--> 400         with transaction.atomic(using=self.using, savepoint=False):
    401             # send pre_delete signals
    402             for model, obj in self.instances_with_model():

/usr/local/lib/python3.7/site-packages/django/db/transaction.py in __enter__(self)
    173             connection.commit_on_exit = True
    174             connection.needs_rollback = False
--> 175             if not connection.get_autocommit():
    176                 # Pretend we're already in an atomic block to bypass the code
    177                 # that disables autocommit to enter a transaction, and make a

/usr/local/lib/python3.7/site-packages/django/db/backends/base/base.py in get_autocommit(self)
    387     def get_autocommit(self):
    388         """Get the autocommit state."""
--> 389         self.ensure_connection()
    390         return self.autocommit
    391

/usr/local/lib/python3.7/site-packages/django/utils/asyncio.py in inner(*args, **kwargs)
     22                 else:
     23                     if event_loop.is_running():
---> 24                         raise SynchronousOnlyOperation(message)
     25             # Pass onwards.
     26             return func(*args, **kwargs)

SynchronousOnlyOperation: You cannot call this from an async context - use a thread or sync_to_async.
alifanov commented 4 years ago

When I use default session engine (sqlite) it's ok

In [13]: client = TelegramClient(
    ...:             'test',
    ...:             api_id,
    ...:             api_hash
    ...:         )

In [14]: client.connect()
bzdvdn commented 3 years ago

at django 2.2.7 still work, django 3+ - dont

Darth-source1 commented 3 years ago

Any updates to Django 3+? Someone found a workaround or can share a repository where Django and Telethon have been integrated sucessfully?

bondbenz commented 3 years ago

Any updates to Django 3+? Someone found a workaround or can share a repository where Django and Telethon have been integrated sucessfully?

Hello , I have made it work on django 3+, what you need to do is to use asyncio and run telethon as async function

Snippet:

async def search_telegram(query,date = None):
    async with TelegramClient('SESSION NAME', api_id, api_hash) as client:
        #dialogs = await client.get_dialogs()
        result = await client(functions.messages.SearchGlobalRequest(
            q=query,
            filter=types.InputMessagesFilterEmpty(),
            min_date=date,
            max_date=None,
            offset_rate=0,
            offset_peer='media',
            offset_id=0,
            limit=100000000,
            folder_id=0
        ))
        return result

For Django View

from asyncio import run
def view_name(request):
    telegram_hits = run(search_telegram(iptv_dns))
    print(telegram_hits)