You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

FastAPI+Uvicorn+pycord运行报错:Future所属事件循环不一致

FastAPI + py-cord 在Uvicorn生产模式下的事件循环冲突问题

问题现象

  • 结合py-cord的FastAPI应用整体可运行,但Discord机器人响应缓慢
  • 生产模式启动时抛出错误:
ValueError: The future belongs to a different loop than the one specified as the loop argument
  • 开发模式(带reload=True)启动无报错,机器人响应正常;生产模式启动触发错误

当前启动py-cord的代码:

@asynccontextmanager
async def lifespan(app: FastAPI):
    asyncio.create_task(client.start(DISCORD_TOKEN))
    yield
    client.close()

app = FastAPI(lifespan=lifespan)

核心原因

开发模式下Uvicorn会重新加载模块并初始化单一事件循环,而生产模式直接传入app对象时,py-cord客户端可能提前绑定了默认的asyncio事件循环,和FastAPI运行时的循环不一致,导致future归属冲突。

修复方案

方案1:强制绑定FastAPI的事件循环给py-cord

修改lifespan函数,确保py-cord客户端使用当前运行的事件循环:

import asyncio
from contextlib import asynccontextmanager
from fastapi import FastAPI
import discord

client = discord.Client(intents=discord.Intents.all())
DISCORD_TOKEN = "your-discord-token"

@asynccontextmanager
async def lifespan(app: FastAPI):
    # 获取FastAPI当前使用的事件循环
    current_loop = asyncio.get_running_loop()
    # 将py-cord客户端的loop绑定到当前循环
    client.loop = current_loop
    # 启动机器人任务
    asyncio.create_task(client.start(DISCORD_TOKEN))
    yield
    # 优雅关闭客户端(改用await确保清理完成)
    await client.close()

app = FastAPI(lifespan=lifespan)

方案2:统一生产模式启动方式

生产模式下不要直接传入app对象给uvicorn.run,保持和开发模式一致的模块引用方式:

if __name__ == "__main__":
    import uvicorn
    # 用字符串引用app,而非直接传对象
    uvicorn.run("main:app", host="0.0.0.0", port=5000, log_level="info")

这种方式下Uvicorn会重新初始化事件循环,确保py-cord和FastAPI使用同一个循环。

方案3:切换到discord.py(已验证有效)

若上述方案仍无法解决,直接替换py-cord为discord.py是最稳妥的选择——discord.py在事件循环兼容性上的处理更成熟,和FastAPI协作时不会出现此类循环冲突问题。

内容的提问来源于stack exchange,提问作者Alan Janczuk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 19:13:22