You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何为GraphQL API生成带类型提示的Python SDK?

如何为GraphQL API生成带类型提示的Python SDK?

我之前也遇到过完全一样的问题——想要给跨团队维护的GraphQL API做一个顺手的Python客户端,既要类型提示和IDE自动补全拉满,又不想每次后端改schema就手动折腾半天。结合我的踩坑经验,给你几个靠谱的方向:

1. 用成熟的代码生成工具(最省心的方案)

优先推荐ariadne-codegen或者sgqlc,这俩都是专门解决「GraphQL到Python类型化代码生成」的工具,完美适配你的需求,维护成本极低。

以ariadne-codegen为例:

  • 先安装工具:pip install ariadne-codegen
  • 创建一个配置文件(比如codegen.yml),指定你的GraphQL endpoint或者本地SDL文件,以及生成代码的输出目录
  • 运行生成命令:ariadne-codegen

生成后的代码会自动包含:

  • 对应GraphQL查询/突变的Python方法,参数全带类型提示
  • 基于Pydantic(或dataclass)的模型类,完全对应GraphQL的类型,返回结果会自动解析成这些模型
  • IDE能直接识别所有代码,自动补全字段、参数都不在话下

举个使用例子:

from generated_client import Client, MeQuery

async def get_current_user():
    async with Client("https://your-graphql-endpoint.com") as client:
        result = await client.execute(MeQuery())
        # IDE会自动提示result.me.id、result.me.name这些字段
        print(result.me.id)

后续后端schema更新时,你只要重新跑一遍生成命令就行,全程自动化。

sgqlc的思路类似:

它会把SDL转换成Python类,你可以用这些类构建查询,还能自动处理序列化和反序列化,同样能得到完整的类型提示,适合偏好轻量方案的场景。

2. 针对gql库的自定义代码生成(如果你非要用gql)

gql的DSLSchema是动态构建的,所以IDE没法做静态分析。但你可以写个简单的脚本,把GraphQL SDL转换成静态的Python类,包装DSLSchema的功能,就能让IDE识别了。

大致步骤:

  1. graphql-core读取SDL文件,解析出所有类型、字段
  2. 生成对应的Python类——把Query类型的每个字段定义成DSLQuery的属性,把Object类型定义成DSLType的子类
  3. 把生成的类和动态构建的DSLSchema关联起来

比如生成的代码大概长这样:

# 自动生成的gql_types.py
from gql.dsl import DSLSchema, DSLQuery, DSLType
from graphql import build_schema

# 先构建动态schema
with open("schema.gql") as f:
    raw_schema = build_schema(f.read())
ds = DSLSchema(raw_schema)

# 静态生成的类型包装
class User(DSLType):
    id = ds.User.id
    name = ds.User.name
    # 其他字段...

class Query(DSLQuery):
    me = ds.Query.me.of_type(User)
    # 其他查询字段...

然后业务代码里就能这么用:

from gql.dsl import dsl_gql
from gql_types import Query, User

query = dsl_gql(
    Query.me.select(User.id, User.name)
)

这样IDE就能自动提示Query.meUser.id这些内容了。你可以用graphql-core的SDL解析功能遍历类型和字段,自动生成对应的Python代码。

3. 留个“逃生通道”应对SDK过期

不管用哪种方案,都建议在生成的SDK里保留一个直接执行原始GQL字符串的方法,比如:

async def execute_raw_query(self, query: str, variables: dict = None):
    # 直接调用底层库的执行方法
    return await self.client.execute(query, variables)

这样如果后端schema更新了但你还没来得及重新生成SDK,就能临时用这个方法救急,不用卡着等发布。

内容来源于stack exchange

火山引擎 最新活动