Skip to content

Instantly share code, notes, and snippets.

@nicolas17
Created May 14, 2020 07:16
Show Gist options
  • Save nicolas17/c8330da13512c9743a3da4b7c7688a3b to your computer and use it in GitHub Desktop.
Save nicolas17/c8330da13512c9743a3da4b7c7688a3b to your computer and use it in GitHub Desktop.
class AsyncTdlib:
def __init__(self, loop=None):
self.pending_futures = {}
self.update_handler = lambda r: None
self.receiver_thread = None
if loop is None:
self.loop = asyncio.get_event_loop()
else:
self.loop = loop
self.last_req_id = 0
self.running = False
self.client = td_json_client_create()
def set_update_handler(self, func):
"""
Set a function to handle "updates", which are responses not matched
with any request.
"""
self.update_handler = func
def _receiver_loop(self):
# only part that runs in a separate thread
while self.running:
result = td_json_client_receive(self.client, 1.0)
if result is not None:
# the result isn't guaranteed to stay valid once we call receive() again,
# so we make a copy to send to the main thread.
self.loop.call_soon_threadsafe(self._got_response, bytes(result))
def _got_response(self, result_json):
# this runs in main thread
result = json.loads(result_json.decode('utf-8'))
if result.get('@extra') in self.pending_futures:
self.pending_futures[result['@extra']].set_result(result)
else:
self.update_handler(result)
def start(self):
self.running = True
self.receiver_thread = threading.Thread(target=self._receiver_loop)
print("tg: Starting thread")
self.receiver_thread.start()
def stop(self):
self.running = False
print("tg: Waiting for thread to quit")
self.receiver_thread.join()
def send_request(self, req):
req = req.copy()
self.last_req_id += 1
req['@extra'] = self.last_req_id
future = self.loop.create_future()
self.pending_futures[self.last_req_id] = future
td_json_client_send(self.client, json.dumps(req).encode('utf-8'))
return future
async def main():
tdlib = AsyncTdlib()
tdlib.set_update_handler(print)
tdlib.start()
print("Sleeping 5s")
await asyncio.sleep(5)
print("Sending a textentities request")
result = await tdlib.send_request({"@type": "getTextEntities", "text": "@telegram /test_command https://telegram.org telegram.me"})
print("request response: {}".format(result))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment