Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
alifanov opened this issue Oct 14, 2020 · 4 comments

Comments

@alifanov
Copy link

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
Copy link
Author

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

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

In [14]: client.connect()

@bzdvdn
Copy link

bzdvdn commented Jan 31, 2021

at django 2.2.7 still work, django 3+ - dont

@Darth-source1
Copy link

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

@bondbenz
Copy link

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)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants