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

如何让Graphene所有解析器在上下文管理器中执行?

如何让Graphene所有解析器在Aiohttp Client Session上下文管理器中执行?

当然有可行的方案!结合aiohttp推荐的单应用复用一个Client Session的原则,以及Graphene对异步执行器的支持,我们可以通过上下文注入的方式,让所有解析器都共享同一个Client Session的上下文环境。下面是具体的实现思路和代码示例:

核心思路

Graphene的异步解析器可以访问GraphQL的执行上下文(info.context),我们可以在请求的入口处(比如aiohttp-graphql的路由配置里),把预先初始化好的全局Client Session注入到这个上下文中,这样所有解析器都能从上下文里获取到同一个Session,自然就运行在它的上下文管理器作用域内了。

具体实现步骤

1. 全局初始化Client Session

按照aiohttp的最佳实践,我们在应用启动时创建一个全局的Client Session,整个应用生命周期内复用它,避免频繁创建销毁连接:

from aiohttp import web
from aiohttp_graphql import GraphQLView
import graphene

# 先定义你的Graphene Query类型
class Query(graphene.ObjectType):
    async def resolve_fetch_external_data(self, info):
        # 从上下文里拿到复用的Session
        session = info.context["client_session"]
        # 直接用这个Session发起请求,不用每次都创建新的上下文管理器
        async with session.get("https://example.com/api/data") as resp:
            return await resp.json()

# 构建Schema
schema = graphene.Schema(query=Query)

async def create_app():
    app = web.Application()
    
    # 全局初始化Client Session,整个应用复用
    app["client_session"] = web.ClientSession()
    
    # 定义上下文工厂:把全局Session注入到GraphQL执行上下文
    async def context_factory(request):
        return {"client_session": request.app["client_session"]}
    
    # 添加GraphQL路由,启用异步执行器
    app.add_routes([
        web.post("/graphql", GraphQLView.as_view(
            schema=schema,
            context_factory=context_factory,
            enable_async=True  # 必须开启异步执行,才能运行async解析器
        ))
    ])
    
    # 应用关闭时,记得关闭全局Session,避免资源泄漏
    async def on_app_shutdown(app):
        await app["client_session"].close()
    
    app.on_shutdown.append(on_app_shutdown)
    
    return app

if __name__ == "__main__":
    web.run_app(create_app())

2. 在解析器中使用上下文里的Session

所有异步解析器都可以通过info.context["client_session"]获取到同一个全局Session,所有基于这个Session的HTTP请求,都运行在它的上下文管理器作用域内,完美符合aiohttp的复用建议。

关键注意事项

  • 必须启用异步执行:确保Graphene的GraphQLView开启了enable_async=True,同时解析器要用async def定义,否则无法处理异步操作。
  • 资源清理不能忘:一定要在应用关闭钩子中关闭全局Session,否则会有连接泄漏的风险。
  • Session复用策略:如果你的应用有特殊需求(比如每个请求需要独立Session),也可以在context_factory里为每个请求创建新的Session,但这不符合aiohttp的最佳实践,仅在特殊场景下使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 10:16:02