【问题标题】:Discord.py Rewrite Giphy Cog Error: Unclosed ConnectorDiscord.py 重写 Giphy Cog 错误:未闭合的连接器
【发布时间】:2021-03-11 04:57:45
【问题描述】:

我正在尝试为我的 discord.py 机器人构建一个 Giphy cog,它会抛出以下错误

Unclosed client session
client_session: <aiohttp.client.ClientSession object at 0x000001CA509CDA60>
Unclosed connector
connections: ['[(<aiohttp.client_proto.ResponseHandler object at 0x000001CA51897BE0>, 77055.671)]']
connector: <aiohttp.connector.TCPConnector object at 0x000001CA509CDA30>

有谁知道是什么原因造成的以及我将如何解决它?

这是我的代码:

import os
import aiohttp
import random
import discord
from discord.ext import commands
from dotenv import load_dotenv

load_dotenv()

prefix = os.getenv("CLIENT_PREFIX")
giphy_api = os.getenv("GIPHY_API_KEY")

command_attrs = {'hidden': False}


class FunCog(commands.Cog, name='Fun Commands', command_attrs=command_attrs):
    def __init__(self, client):
        self.client = client

    @commands.command(name='gif')
    async def _gif(self, ctx, *, search, json=None):
        embed = discord.Embed(colour=discord.Colour.blue())
        session = aiohttp.ClientSession()

        if search == '':
            response = await session.get('https://api.giphy.com/v1/gifs/random?api_key=' + giphy_api)
            data = json.loads(await response.text())
            embed.set_image(url=data['data']['images']['original']['url'])
        else:
            search.replace(' ', '+')
            response = await session.get(
                'http://api.giphy.com/v1/gifs/search?q=' + search + '&api_key=' + giphy_api + '&limit=10')
            data = json.loads(await response.text())
            gif_choice = random.randint(0, 9)
            embed.set_image(url=data['data'][gif_choice]['images']['original']['url'])
            await session.close()
            await ctx.send(embed=embed)


def setup(client):
    client.add_cog(FunCog(client))

出于安全原因,我省略了我的 Giphy API 密钥。 如果有帮助,我正在使用 discord.py rewritepython 3.8.6

基本上,我希望能够通过标签搜索带有它的 gif,它会以来自 giphy 的随机 gif 响应指定标签。

--编辑--

  1. 将错误记录移至我的Events.py 文件中
  2. 将 API 密钥移至我的 .env 文件中
  3. 删除了 tenor_api 环境,因为它不会被使用并且与这个问题无关
  4. 稍微更新了代码以解决一些缺失的参数。

---编辑---

感谢 Fixator10 的回复解决了我在这篇文章中遇到的问题。

如果有人想使用,这是我的工作代码:

import os
import aiohttp
import random
import discord
import json
from discord.ext import commands
from dotenv import load_dotenv

load_dotenv()

prefix = os.getenv("CLIENT_PREFIX")
giphy_api = os.getenv("GIPHY_API_KEY")

command_attrs = {'hidden': False}


class FunCog(commands.Cog, name='Fun Commands', command_attrs=command_attrs):
    def __init__(self, client):
        self.client = client
        self.session = aiohttp.ClientSession()

    def cog_unload(self):
        self.client.loop.create_task(self.session.close())

    @commands.command(name='gif')
    async def _gif(self, ctx, *, search):
        session = self.session
        embed = discord.Embed(colour=discord.Color.dark_gold())

        if search == '':
            response = await session.get('https://api.giphy.com/v1/gifs/random?api_key=' + giphy_api)
            data = json.loads(await response.text())
            embed.set_image(url=data['data']['images']['original']['url'])
        else:
            search.replace(' ', '+')
            response = await session.get(
                'http://api.giphy.com/v1/gifs/search?q=' + search + '&api_key=' + giphy_api + '&limit=10')
            data = json.loads(await response.text())
            gif_choice = random.randint(0, 9)
            embed.set_image(url=data['data'][gif_choice]['images']['original']['url'])
            await ctx.send(embed=embed)


def setup(client):
    client.add_cog(FunCog(client))

它可能不是最好的,因为它只使用一个标签,但我可能会在其他时间改进它 xD

【问题讨论】:

  • 顺便说一句,您可以使用on_command_error 只使用一个,而不是为每个命令执行它。
  • 这绝对是有用的。我必须为该提示设置该事件 =)

标签: discord.py discord.py-rewrite giphy-api


【解决方案1】:

这是由您的会话行为引起的。如果搜索为空,您不会关闭会话。简而言之:您应该在使用后关闭会话。

最简单的解决方案——使用上下文管理器:

    # https://docs.aiohttp.org/en/stable/#client-example
    async with aiohttp.ClientSession() as session:
        async with session.get('http://python.org') as response:

否则,您可以为 Cog 创建一个会话并在卸载时关闭它:

class MyCog(commands.Cog):
    def __init__(client):
        self.client = client
        self.session = aiohttp.ClientSession()

    # https://discordpy.readthedocs.io/en/stable/ext/commands/api.html#discord.ext.commands.Cog.cog_unload
    def cog_unload(self):
        # since close is coroutine, 
        # and we need to call it in sync func
        # lets create asyncio task
        self.client.loop.create_task(self.session.close()) 
        # or, we can use detach:
        # self.session.detach()

    @commands.command()
    async def mycmd(ctx):
        async with self.session.get("https://example.com") as response:
            await ctx.send(response.status)

【讨论】:

  • 我在上面编辑了我的帖子,这是做什么的......仍然无法正常工作......
  • 我再次编辑了帖子,我得到了某种工作,但没有达到预期。任何想法如何从我编辑的代码中完全修复它?
  • 我不确定你的问题是什么,但是对于代码,我可以建议对请求方法使用 params 参数,而不是手动构建它:docs.aiohttp.org/en/stable/…。它也会正确编码你的字符串,所以你不需要使用search.replace(' ', '+') part
  • 哟,别担心。 tbh 它确实有效,我猜这段代码根本不允许多个标签。但是我在这个特定问题中遇到的问题已经解决了。
猜你喜欢
  • 2019-08-09
  • 2020-02-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-22
  • 1970-01-01
相关资源
最近更新 更多