mirror of
				https://github.com/LonamiWebs/Telethon.git
				synced 2025-10-31 07:57:38 +03:00 
			
		
		
		
	Improve Quart example (#1229)
This commit is contained in:
		
							parent
							
								
									2b277dd558
								
							
						
					
					
						commit
						e1355ae5d8
					
				|  | @ -1,7 +1,8 @@ | ||||||
| import base64 | import base64 | ||||||
| import os | import os | ||||||
| 
 | 
 | ||||||
| from quart import Quart, request | import hypercorn.asyncio | ||||||
|  | from quart import Quart, render_template_string, request | ||||||
| 
 | 
 | ||||||
| from telethon import TelegramClient, utils | from telethon import TelegramClient, utils | ||||||
| 
 | 
 | ||||||
|  | @ -12,24 +13,44 @@ def get_env(name, message): | ||||||
|     return input(message) |     return input(message) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | BASE_TEMPLATE = ''' | ||||||
|  | <!DOCTYPE html> | ||||||
|  | <html> | ||||||
|  |     <head> | ||||||
|  |         <meta charset='UTF-8'> | ||||||
|  |         <title>Telethon + Quart</title> | ||||||
|  |     </head> | ||||||
|  |     <body>{{ content | safe }}</body> | ||||||
|  | </html> | ||||||
|  | ''' | ||||||
|  | 
 | ||||||
|  | PHONE_FORM = ''' | ||||||
|  | <form action='/' method='post'> | ||||||
|  |     Phone (international format): <input name='phone' type='text' placeholder='+34600000000'> | ||||||
|  |     <input type='submit'> | ||||||
|  | </form> | ||||||
|  | ''' | ||||||
|  | 
 | ||||||
|  | CODE_FORM = ''' | ||||||
|  | <form action='/' method='post'> | ||||||
|  |     Telegram code: <input name='code' type='text' placeholder='70707'> | ||||||
|  |     <input type='submit'> | ||||||
|  | </form> | ||||||
|  | ''' | ||||||
|  | 
 | ||||||
| # Session name, API ID and hash to use; loaded from environmental variables | # Session name, API ID and hash to use; loaded from environmental variables | ||||||
| SESSION = os.environ.get('TG_SESSION', 'quart') | SESSION = os.environ.get('TG_SESSION', 'quart') | ||||||
| API_ID = int(get_env('TG_API_ID', 'Enter your API ID: ')) | API_ID = int(get_env('TG_API_ID', 'Enter your API ID: ')) | ||||||
| API_HASH = get_env('TG_API_HASH', 'Enter your API hash: ') | API_HASH = get_env('TG_API_HASH', 'Enter your API hash: ') | ||||||
| 
 | 
 | ||||||
|  | # Telethon client | ||||||
|  | client = TelegramClient(SESSION, API_ID, API_HASH) | ||||||
|  | client.parse_mode = 'html'  # <- Render things nicely | ||||||
|  | phone = None | ||||||
| 
 | 
 | ||||||
| # Helper method to add the HTML head/body | # Quart app | ||||||
| def html(inner): | app = Quart(__name__) | ||||||
|     return ''' | app.secret_key = 'CHANGE THIS TO SOMETHING SECRET' | ||||||
| <!DOCTYPE html> |  | ||||||
| <html> |  | ||||||
|     <head> |  | ||||||
|         <meta charset="UTF-8"> |  | ||||||
|         <title>Telethon + Quart</title> |  | ||||||
|     </head> |  | ||||||
|     <body>{}</body> |  | ||||||
| </html> |  | ||||||
| '''.format(inner) |  | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| # Helper method to format messages nicely | # Helper method to format messages nicely | ||||||
|  | @ -50,18 +71,20 @@ async def format_message(message): | ||||||
|     ) |     ) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| # Define the global phone and Quart app variables | # Connect the client before we start serving with Quart | ||||||
| phone = None | @app.before_serving | ||||||
| app = Quart(__name__) | async def startup(): | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| # Quart handlers |  | ||||||
| @app.route('/', methods=['GET', 'POST']) |  | ||||||
| async def root(): |  | ||||||
|     # Connect if we aren't yet |  | ||||||
|     if not client.is_connected(): |  | ||||||
|     await client.connect() |     await client.connect() | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|  | # After we're done serving (near shutdown), clean up the client | ||||||
|  | @app.after_serving | ||||||
|  | async def cleanup(): | ||||||
|  |     await client.disconnect() | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @app.route('/', methods=['GET', 'POST']) | ||||||
|  | async def root(): | ||||||
|     # We want to update the global phone variable to remember it |     # We want to update the global phone variable to remember it | ||||||
|     global phone |     global phone | ||||||
| 
 | 
 | ||||||
|  | @ -82,22 +105,18 @@ async def root(): | ||||||
|         async for m in client.iter_messages(dialog, 10): |         async for m in client.iter_messages(dialog, 10): | ||||||
|             result += await(format_message(m)) |             result += await(format_message(m)) | ||||||
| 
 | 
 | ||||||
|         return html(result) |         return await render_template_string(BASE_TEMPLATE, content=result) | ||||||
| 
 | 
 | ||||||
|     # Ask for the phone if we don't know it yet |     # Ask for the phone if we don't know it yet | ||||||
|     if phone is None: |     if phone is None: | ||||||
|         return html(''' |         return await render_template_string(BASE_TEMPLATE, content=PHONE_FORM) | ||||||
| <form action="/" method="post"> |  | ||||||
|     Phone (international format): <input name="phone" type="text" placeholder="+34600000000"> |  | ||||||
|     <input type="submit"> |  | ||||||
| </form>''') |  | ||||||
| 
 | 
 | ||||||
|     # We have the phone, but we're not logged in, so ask for the code |     # We have the phone, but we're not logged in, so ask for the code | ||||||
|     return html(''' |     return await render_template_string(BASE_TEMPLATE, content=CODE_FORM) | ||||||
| <form action="/" method="post"> | 
 | ||||||
|     Telegram code: <input name="code" type="text" placeholder="70707"> | 
 | ||||||
|     <input type="submit"> | async def main(): | ||||||
| </form>''') |     await hypercorn.asyncio.serve(app, hypercorn.Config()) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| # By default, `Quart.run` uses `asyncio.run()`, which creates a new asyncio | # By default, `Quart.run` uses `asyncio.run()`, which creates a new asyncio | ||||||
|  | @ -108,13 +127,12 @@ async def root(): | ||||||
| # So, we have to manually pass the same `loop` to both applications to | # So, we have to manually pass the same `loop` to both applications to | ||||||
| # make 100% sure it works and to avoid headaches. | # make 100% sure it works and to avoid headaches. | ||||||
| # | # | ||||||
| # Quart doesn't seem to offer a way to run inside `async def` | # To run Quart inside `async def`, we must use `hypercorn.asyncio.serve()` | ||||||
| # (see https://gitlab.com/pgjones/quart/issues/146) so we must | # directly. | ||||||
| # run and block on it last. |  | ||||||
| # | # | ||||||
| # This example creates a global client outside of Quart handlers. | # This example creates a global client outside of Quart handlers. | ||||||
| # If you create the client inside the handlers (common case), you | # If you create the client inside the handlers (common case), you | ||||||
| # won't have to worry about any of this. | # won't have to worry about any of this, but it's still good to be | ||||||
| client = TelegramClient(SESSION, API_ID, API_HASH) | # explicit about the event loop. | ||||||
| client.parse_mode = 'html'  # <- render things nicely | if __name__ == '__main__': | ||||||
| app.run(loop=client.loop)  # <- same event loop as telethon |     client.loop.run_until_complete(main()) | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user