I'm trying to run Quart+Telethon with multiple clients. This example shows one global client. I have this working.
Now I need my app to handle multiple users simultaneously logging in and doing stuff. This post suggests using asyncio.gather.
How do I need to change my code such that I can have multiple people logging in?
Here I placed the bulk of Quart functionality into the work() function (wherever client is referenced). In the def main() I start the app and then invoke asyncio.gather.
When running the app with two work() functions (two clients) in asyncio.gather I get error "AssertionError: Handler is overwriting existing for endpoint phone_form".
And if I run only with one work() function I get a different error: "ConnectionError('Cannot send requests while disconnected')"
What am I missing? Thx
import os
import asyncio
from dotenv import load_dotenv
from quart import Quart, render_template_string, request, render_template
from telethon import TelegramClient
load_dotenv('.env')
API_ID = int(os.getenv('API_ID'))
API_HASH = str(os.getenv('API_HASH'))
app = Quart(__name__)
async def work(client):
async with client:
@app.route("/")
async def phone_form():
return await render_template('phone_form.html')
@app.route("/validation_form", methods=['POST'])
async def validation_form():
""" Ask the user for the confirmation code they just got. """
global phone
# Check form parameters (phone/code)
form = await request.form
if 'phone' in form:
phone = form['phone']
await client.send_code_request(phone)
return await render_template('validation_form.html', phone_nr=phone)
async def main():
import hypercorn.asyncio
# create task so that starting hypercorn server is no blocking functions that come after it
server = asyncio.create_task(hypercorn.asyncio.serve(app, hypercorn.Config()))
# have many clients here, using the app asynchronously
await asyncio.gather(
work(TelegramClient('user1', API_ID_, API_HASH)),
work(TelegramClient('user2', API_ID, API_HASH)),
)
# this is to start blocking - means after this subsequent functions will need to wait until hypercorn is finished (hypercorn runs forever!)
# this await also lets server run indefinitely
await server
if __name__ == '__main__':
asyncio.run(main())