How to use telethon with hypercorn?
How to convert the following line
app.run(loop=client.loop)
In procfile, how to pass the loop
hypercorn file:app -k asyncio
Or how to use hypercorn api?
import asyncio
from hypercorn.asyncio import serve
asyncio.run(serve(app, config)) # value for config
Answer
To integrate Telethon with Hypercorn, you need to properly configure the asynchronous event loop in a way that works with both Telethon (which runs on its own asyncio loop) and Hypercorn (which is a web server running on asyncio). Here's how you can adapt your code to run both simultaneously.
Solution
- Using
hypercorn
with theTelethon
client loop:
When using Hypercorn to serve an ASGI app, you can pass the existing Telethon client event loop to Hypercorn, so that both the HTTP server and the Telethon client run on the same asyncio event loop.
You cannot directly use app.run(loop=client.loop)
with Hypercorn, but we can adapt the existing setup. Here's how you can do it:
1. Install Dependencies:
Make sure you have both Hypercorn and Telethon installed in your environment:
pip install telethon hypercorn
2. Using hypercorn
API:
The Hypercorn API uses asyncio.run()
for running the server. You can use the Telethon client with Hypercorn by ensuring that both the Hypercorn server and Telethon client are running on the same event loop.
Here’s how you can structure your app.py
file:
app.py
:
import asyncio
from telethon import TelegramClient
from hypercorn.asyncio import serve
from hypercorn.config import Config
from fastapi import FastAPI
# Initialize the Telethon client
api_id = 'your_api_id' # Your Telegram API ID
api_hash = 'your_api_hash' # Your Telegram API hash
client = TelegramClient('session_name', api_id, api_hash)
# Define the FastAPI app
app = FastAPI()
@app.get("/")
async def root():
return {"message": "Hello, World!"}
# Create an async function to run the Telethon client and Hypercorn server
async def run():
# Start the Telethon client
await client.start()
print("Telethon client is running...")
# Create the Hypercorn configuration
config = Config()
config.bind = ["0.0.0.0:8000"] # Set your desired host and port
# Run Hypercorn server on the same event loop
await serve(app, config)
# Run the app with asyncio.run()
if __name__ == "__main__":
asyncio.run(run())
Key Points in the Code:
- Telethon Client: The Telethon client is initialized and started using
await client.start()
. This connects the client to Telegram and starts receiving updates, such as messages. - FastAPI Application: The FastAPI application is defined as usual. In this case, a simple
root
endpoint is used. - Hypercorn Config: You create a Hypercorn configuration (
Config
) to set up the binding for the app (e.g.,0.0.0.0:8000
). - Running both Telethon and Hypercorn: The
run()
function is an asynchronous function that starts both the Telethon client and the Hypercorn server. This ensures both services run on the same event loop.
3. Procfile:
If you're deploying to a platform like Heroku, you'll need a Procfile
to run the app using Hypercorn.
Your Procfile
might look like this:
web: hypercorn app:run -k asyncio
Here:
app:run
tells Hypercorn to execute therun
function fromapp.py
, which starts both the Telethon client and the Hypercorn server.
4. Running with Hypercorn (locally):
If you want to run the app locally with Hypercorn, simply execute this:
hypercorn app:run -k asyncio
This will start both the Telethon client and the Hypercorn HTTP server, running on the same asyncio event loop.
5. Alternative Setup (Using asyncio.create_task
):
If you want more control over managing the Telethon client and the HTTP server, you can use asyncio.create_task
to run both in parallel:
import asyncio
from telethon import TelegramClient
from hypercorn.asyncio import serve
from hypercorn.config import Config
from fastapi import FastAPI
api_id = 'your_api_id'
api_hash = 'your_api_hash'
client = TelegramClient('session_name', api_id, api_hash)
app = FastAPI()
@app.get("/")
async def root():
return {"message": "Hello, World!"}
async def run_telethon():
await client.start()
print("Telethon client started")
await client.run_until_disconnected()
async def run_hypercorn():
config = Config()
config.bind = ["0.0.0.0:8000"]
await serve(app, config)
async def run():
# Run Telethon and Hypercorn in parallel
task_telethon = asyncio.create_task(run_telethon())
task_hypercorn = asyncio.create_task(run_hypercorn())
# Wait for both tasks to complete
await asyncio.gather(task_telethon, task_hypercorn)
if __name__ == "__main__":
asyncio.run(run())
This method uses asyncio.create_task
to run both the Telethon client and Hypercorn server as asynchronous tasks in parallel.
Conclusion
- Telethon client and Hypercorn run on the same event loop by ensuring that both are part of the same asyncio task.
- The
run()
function combines the initialization of the Telethon client and the Hypercorn server, ensuring both are running asynchronously. - The
Procfile
is configured to start theHypercorn
server with-k asyncio
to use asyncio.
This setup ensures that Telethon (which is asyncio-based) and Hypercorn (also asyncio-based) run smoothly in the same application.