Search code examples
pythondiscord.pyquart

I am getting an error to await ipc.start() but the documentation doesn't say it


I am creating a web dashboard for my discord bot using quart. I have 2 files, bot.py and webserver.py. The bot.py file has the code for my bot and the webserver.py has the code for the web dashboard.
Here is the code of bot.py.

import os
import discord
from discord.ext import commands, ipc
from dotenv import load_dotenv

load_dotenv()

class BotClass(commands.Bot):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.ipc = ipc.Server(self, secret_key="Hercules")

    async def on_ready(self):
        """Called upon the bot is ready to use"""
        await self.ipc.start() # There were some issues with event loop, so I put the ipc.start() inside the on_ready function which fixed my issue
        print("Bot is ready")

    async def on_ipc_ready(self):
        """Called upon the ipc server is ready to use"""
        print("The ipc server is ready")

    async def on_ipc_error(self, endpoint, error):
        """Called upon the endpoint raises an error"""
        print(f"{error} was raised by {endpoint}")

bot = BotClass(command_prefix="!", intents=discord.Intents.all())

@bot.ipc.route()
async def get_guild_count(data):
    guild_count = len(bot.guilds)
    return guild_count

@bot.command()
async def test(ctx):
    await ctx.reply("Everything is working perfectly")

if __name__ == "__main__":
    bot.run(os.getenv("BOT_TOKEN"))

And here's the error I am getting from bot.py file.

Traceback (most recent call last):
  File "F:\HS International\XyRic Bot Dashboard\venv\lib\site-packages\discord\client.py", line 377, in _run_event
    await coro(*args, **kwargs)
  File "F:\HS International\XyRic Bot Dashboard\bot.py", line 15, in on_ready
    await self.ipc.start() # There were some issues with event loop, so I put the ipc.start() inside the on_ready function which fixed my issue
  File "F:\HS International\XyRic Bot Dashboard\venv\lib\site-packages\discord\ext\ipc\server.py", line 262, in start
    self.loop.run_until_complete(self.__start(self._multicast_server, self.multicast_port))
  File "E:\Python\lib\asyncio\base_events.py", line 617, in run_until_complete
    self._check_running()
  File "E:\Python\lib\asyncio\base_events.py", line 577, in _check_running
    raise RuntimeError('This event loop is already running')
RuntimeError: This event loop is already running
F:\HS International\XyRic Bot Dashboard\venv\lib\site-packages\discord\client.py:382: RuntimeWarning: coroutine 'Server.__start' was never awaited
  await self.on_error(event_name, *args, **kwargs)
RuntimeWarning: Enable tracemalloc to get the object allocation traceback
The ipc server is ready

I know it's telling me to await bot.ipc.start(), but the documentation doesn't tell me to do it. I am confused about this. If I have to await it then I have to put this in an async function, but I am not supposed to do it like this.

Here goes the code of my webserver.py.

from quart import Quart, redirect, url_for
from quart_discord import DiscordOAuth2Session, requires_authorization, Unauthorized
from discord.ext import ipc
import os
from dotenv import load_dotenv

load_dotenv()

app = Quart(__name__)
app.secret_key = "Hercules"
ipc_client = ipc.Client(secret_key="Hercules")

app.config["DISCORD_CLIENT_ID"] = os.getenv("CLIENT_ID")
app.config["DISCORD_CLIENT_SECRET"] = os.getenv("CLIENT_SECRET")
app.config["DISCORD_REDIRECT_URI"] = "http://127.0.0.1:5000/callback"
app.config["DISCORD_BOT_TOKEN"] = os.getenv("BOT_TOKEN")
discord = DiscordOAuth2Session(app)

@app.route("/")
async def index():
    guild_count = await ipc_client.request("get_guild_count")
    return str(guild_count) 

@app.route("/login/")
async def login():
    return await discord.create_session()

@app.route("/callback/")
async def callback():
    try: 
        await discord.callback()
    except:
        return redirect(url_for("login"))
    return redirect(url_for("select_server"))

@app.route("/select_server/")
async def select_server():
    user = await discord.fetch_user()
    return f"{user.name}"

if __name__ == "__main__":
    app.run()

And here goes the error that I am getting from webserver.py file.


Traceback (most recent call last):
  File "F:\HS International\XyRic Bot Dashboard\venv\lib\site-packages\aiohttp\connector.py", line 980, in _wrap_create_connection
    return await self._loop.create_connection(*args, **kwargs)  # type: ignore[return-value]  # noqa
  File "E:\Python\lib\asyncio\base_events.py", line 1055, in create_connection
    raise exceptions[0]
  File "E:\Python\lib\asyncio\base_events.py", line 1040, in create_connection
    sock = await self._connect_sock(
  File "E:\Python\lib\asyncio\base_events.py", line 954, in _connect_sock
    await self.sock_connect(sock, address)
  File "E:\Python\lib\asyncio\proactor_events.py", line 704, in sock_connect
    return await self._proactor.connect(sock, address)
  File "E:\Python\lib\asyncio\windows_events.py", line 812, in _poll
    value = callback(transferred, key, ov)
  File "E:\Python\lib\asyncio\windows_events.py", line 599, in finish_connect
    ov.getresult()
ConnectionRefusedError: [WinError 1225] The remote computer refused the network connection

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "F:\HS International\XyRic Bot Dashboard\venv\lib\site-packages\quart\app.py", line 1629, in handle_request
    return await self.full_dispatch_request(request_context)
  File "F:\HS International\XyRic Bot Dashboard\venv\lib\site-packages\quart\app.py", line 1654, in full_dispatch_request
    result = await self.handle_user_exception(error)
  File "F:\HS International\XyRic Bot Dashboard\venv\lib\site-packages\quart\app.py", line 1099, in handle_user_exception
    raise error
  File "F:\HS International\XyRic Bot Dashboard\venv\lib\site-packages\quart\app.py", line 1652, in full_dispatch_request
    result = await self.dispatch_request(request_context)
  File "F:\HS International\XyRic Bot Dashboard\venv\lib\site-packages\quart\app.py", line 1697, in dispatch_request
    return await self.ensure_async(handler)(**request_.view_args)
  File "F:\HS International\XyRic Bot Dashboard\webserver.py", line 21, in index
    guild_count = await ipc_client.request("get_guild_count")
  File "F:\HS International\XyRic Bot Dashboard\venv\lib\site-packages\discord\ext\ipc\client.py", line 97, in request
    await self.init_sock()
  File "F:\HS International\XyRic Bot Dashboard\venv\lib\site-packages\discord\ext\ipc\client.py", line 61, in init_sock
    self.multicast = await self.session.ws_connect(self.url, autoping=False)
  File "F:\HS International\XyRic Bot Dashboard\venv\lib\site-packages\aiohttp\client.py", line 779, in _ws_connect
    resp = await self.request(
  File "F:\HS International\XyRic Bot Dashboard\venv\lib\site-packages\aiohttp\client.py", line 536, in _request
    conn = await self._connector.connect(
  File "F:\HS International\XyRic Bot Dashboard\venv\lib\site-packages\aiohttp\connector.py", line 540, in connect
    proto = await self._create_connection(req, traces, timeout)
  File "F:\HS International\XyRic Bot Dashboard\venv\lib\site-packages\aiohttp\connector.py", line 901, in _create_connection
    _, proto = await self._create_direct_connection(req, traces, timeout)
  File "F:\HS International\XyRic Bot Dashboard\venv\lib\site-packages\aiohttp\connector.py", line 1206, in _create_direct_connection
    raise last_exc
  File "F:\HS International\XyRic Bot Dashboard\venv\lib\site-packages\aiohttp\connector.py", line 1175, in _create_direct_connection
    transp, proto = await self._wrap_create_connection(
  File "F:\HS International\XyRic Bot Dashboard\venv\lib\site-packages\aiohttp\connector.py", line 988, in _wrap_create_connection
    raise client_error(req.connection_key, exc) from exc
aiohttp.client_exceptions.ClientConnectorError: Cannot connect to host localhost:20000 ssl:default [The remote computer refused the network connection]
[2022-10-07 21:11:08 +0600] [7028] [INFO] 127.0.0.1:50415 GET /login 1.1 308 243 998

The other routes of the file is working correctly, I only get the error with the index route. Thank you.


Solution

  • I have fixed my issue, let me explain how did I solve my problem. Actually discord-ext-ipc has stopped maintenance, I am not sure if it was the issue of my problem. But all I did was uninstalled discord.py and discord-ext-ipc. Then I installed nextcord and nextcord-ext-ipc (basically I switched to nextcord). But I was still having the same issue. So later what I did was, just changed the name of my ipc server variable. My code looks like this now,

    import os
    import discord
    from nextcord.ext import commands, ipc
    from dotenv import load_dotenv
    
    load_dotenv()
    
    class BotClass(commands.Bot):
        def __init__(self, *args, **kwargs):
            super().__init__(*args, **kwargs)
            self.ipc_server = ipc.Server(self, secret_key="Hercules")
    
        async def on_ready(self):
            """Called upon the bot is ready to use"""
            print("Bot is ready")
    
        async def on_ipc_ready(self):
            """Called upon the ipc server is ready to use"""
            print("The ipc server is ready")
    
        async def on_ipc_error(self, endpoint, error):
            """Called upon the endpoint raises an error"""
            print(f"{error} was raised by {endpoint}")
    
    bot = BotClass(command_prefix="!", intents=discord.Intents.all())
    
    @bot.ipc_server.route()
    async def get_guild_count(data):
        guild_count = len(bot.guilds)
        return guild_count
    
    @bot.ipc_server.route()
    async def get_guild_ids(data):
        guild_ids = [int(guild.id) for guild in bot.guilds]
        return guild_ids
    
    @bot.command()
    async def test(ctx):
        await ctx.reply("Everything is working perfectly")
    
    if __name__ == "__main__":
        bot.ipc_server.start()
        bot.run(os.getenv("BOT_TOKEN"))```
    Thank you.