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

Flask异步路由处理程序能否适配gql的AIOHTTPTransport异步调用?

报错核心原因

默认Flask的WSGI运行模式(即app.run()启动的方式)对异步路由的处理机制会导致该问题:默认模式下,每个异步路由请求会被分配到独立的线程,每个线程会创建单独的asyncio事件循环,你在main函数外层提前创建的gql session绑定的是外层启动时的主事件循环,和请求处理时的事件循环不属于同一个,才会触发跨循环的Future报错。

解决方案1:使用ASGI服务器运行Flask(官方推荐)

将Flask应用作为ASGI应用启动,保证整个应用的所有异步逻辑都运行在同一个全局事件循环中,即可正常复用提前创建的gql session,同时还能复用底层HTTP连接池,性能最优。

  1. 安装依赖:
pip install uvicorn
  1. 调整后代码:
from flask import Flask
from gql import Client, gql
from gql.transport.aiohttp import AIOHTTPTransport
import uvicorn

token = 'bearer ...'  # GitHub API token

# 全局初始化gql客户端,只执行一次schema拉取
transport = AIOHTTPTransport(
    url='https://api.github.com/graphql',
    headers={'Authorization': token}
)
client = Client(transport=transport, fetch_schema_from_transport=True)

app = Flask(__name__)

@app.route('/')
async def home():
    query = gql('''
    query example ($username: String!) {
        user(login: $username){
            bio,
        }
    }
    ''')
    params = {
        'username': 'octocat'
    }
    # 直接复用全局客户端执行请求,无需重建
    result = await client.execute(query, variable_values=params)
    return result

if __name__ == '__main__':
    # 用uvicorn启动ASGI应用,全局共用同一个事件循环
    uvicorn.run(app, host="127.0.0.1", port=5000)

解决方案2:预缓存Schema,兼容原有WSGI模式

如果必须保留默认app.run()的WSGI运行模式,可以提前预拉取Schema缓存,后续新建客户端时直接使用本地缓存的Schema,不会触发重复拉取,性能损耗可忽略:

import asyncio
from flask import Flask
from gql import Client, gql
from gql.transport.aiohttp import AIOHTTPTransport

token = 'bearer ...'  # GitHub API token

transport = AIOHTTPTransport(
    url='https://api.github.com/graphql',
    headers={'Authorization': token}
)
# 启动时预拉取一次Schema,全局缓存
cached_schema = asyncio.run(
    Client(transport=transport, fetch_schema_from_transport=True).load_schema()
)

app = Flask(__name__)

@app.route('/')
async def home():
    query = gql('''
    query example ($username: String!) {
        user(login: $username){
            bio,
        }
    }
    ''')
    params = {
        'username': 'octocat'
    }
    # 新建客户端直接传入缓存的Schema,不会重复拉取
    client = Client(transport=transport, schema=cached_schema)
    async with client as session:
        result = await session.execute(query, variable_values=params)
        return result

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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 18:27:04