从模式、查询和突变生成完全类型的GraphQL客户端!
项目描述
Ariadne代码生成器
Python代码生成器,从GraphQL模式、查询、突变和订阅中提取,生成具有完全类型和异步GraphQL客户端的Python包。
它作为ariadne-codegen
命令提供,并从pyproject.toml
文件读取配置。
$ ariadne-codegen
它也可以作为python -m ariadne_codegen
运行。
特性
- 从模式类型、输入和枚举生成pydantic模型。
- 为GraphQL结果生成pydantic模型。
- 生成客户端包,每个GraphQL操作都作为异步方法可用。
安装
Ariadne代码生成器可以使用pip安装。
$ pip install ariadne-codegen
要支持订阅,默认基础客户端需要websockets
包。
$ pip install ariadne-codegen[subscriptions]
配置
ariadne-codegen
从您的 pyproject.toml
文件中的 [tool.ariadne-codegen]
节读取配置。您可以使用其他配置文件,通过 --config
选项,例如 ariadne-codegen --config custom_file.toml
客户端生成的最小配置
[tool.ariadne-codegen]
schema_path = "schema.graphql"
queries_path = "queries.graphql"
必填设置
queries_path
- 包含查询的文件/目录路径(如果使用enable_custom_operations
,则可以是可选的)
以下两个参数中必须提供其中一个,如果两个都提供,则 schema_path
优先
schema_path
- 包含 GraphQL 模式的文件/目录路径remote_schema_url
- 可执行 introspection 查询的 GraphQL 服务器的 URL
可选设置
remote_schema_headers
- 附加头信息,随 introspection 查询一起传递,例如{"Authorization" = "Bearer: token"}
。要在头信息值中包含环境变量,请在该变量前加上$
,例如{"Authorization" = "$AUTH_TOKEN"}
remote_schema_verify_ssl
(默认为true
)- 一个标志,指定是否在检查远程模式时验证 SSLtarget_package_name
(默认为"graphql_client"
)- 生成包的名称target_package_path
(默认为当前工作目录)- 生成包的路径client_name
(默认为"Client"
)- 生成客户端类的名称client_file_name
(默认为"client"
)- 包含生成客户端类的文件名称base_client_name
(默认为"AsyncBaseClient"
)- 基础客户端类的名称base_client_file_path
(默认为.../ariadne_codegen/client_generators/dependencies/async_base_client.py
)- 定义base_client_name
的文件路径enums_module_name
(默认为"enums"
)- 包含生成枚举模型的文件名称input_types_module_name
(默认为"input_types"
)- 包含生成输入类型模型的文件名称fragments_module_name
(默认为"fragments"
)- 包含生成片段模型的文件名称include_comments
(默认为"stable"
)- 设置每个生成文件顶部包含的注释内容。有效选项有:"none"
(无注释)、"timestamp"
(包含生成时间戳的注释)、"stable"
(注释中包含这是一个生成文件的消息)convert_to_snake_case
(默认为true
)- 一个标志,指定是否将字段和参数名称转换为 snake_caseinclude_all_inputs
(默认为true
)- 一个标志,指定是否包含模式中定义的所有输入,或仅包含在提供的操作中使用的输入include_all_enums
(默认为true
)- 一个标志,指定是否包含模式中定义的所有枚举,或仅包含在提供的操作中使用的枚举async_client
(默认为true
)- 默认生成的客户端是async
,将其更改为false
以生成同步客户端opentelemetry_client
(默认为false
)- 默认基础客户端不支持任何性能跟踪。将此选项更改为true
以使用具有 Open Telemetry 支持的基础客户端。files_to_include
(默认为[]
)- 将复制到生成包中的文件列表plugins
(默认为[]
)- 在生成过程中使用的插件列表enable_custom_operations
(默认为false
)- 启用自定义操作构建。生成包含所有类和方法的附加文件。
自定义操作构建器
自定义操作构建器允许您以结构化和直观的方式创建复杂的 GraphQL 查询。
示例代码
import asyncio
from graphql_client import Client
from graphql_client.custom_fields import (
ProductFields,
ProductTranslatableContentFields,
ProductTranslationFields,
TranslatableItemConnectionFields,
TranslatableItemEdgeFields,
)
from graphql_client.custom_queries import Query
from graphql_client.enums import LanguageCodeEnum, TranslatableKinds
async def get_products():
# Create a client instance with the specified URL and headers
client = Client(
url="https://saleor.cloud/graphql/",
headers={"authorization": "bearer ..."},
)
# Build the queries
product_query = Query.product(id="...", channel="channel-uk").fields(
ProductFields.id,
ProductFields.name,
)
translation_query = Query.translations(kind=TranslatableKinds.PRODUCT, first=10).fields(
TranslatableItemConnectionFields.edges().alias("aliased_edges").fields(
TranslatableItemEdgeFields.node.on(
"ProductTranslatableContent",
ProductTranslatableContentFields.id,
ProductTranslatableContentFields.product_id,
ProductTranslatableContentFields.name,
)
)
)
# Execute the queries with an operation name
response = await client.query(
product_query,
translation_query,
operation_name="get_products",
)
print(response)
# Run the async function
asyncio.run(get_products())
说明
- 构建产品查询
- Query.product(id="...", channel="channel-uk") 启动了对具有指定 ID 和通道的产品进行查询。
- .fields(ProductFields.id, ProductFields.name) 指定要检索的产品字段:id 和 name。
- 构建翻译查询
- Query.translations(kind=TranslatableKinds.PRODUCT, first=10) 初始化对产品翻译的查询。
- .fields(...) 指定要检索的翻译字段。
- .alias("aliased_edges") 将 edges 字段重命名为 aliased_edges。
- .on("ProductTranslatableContent", ...) 指定如果节点类型为 ProductTranslatableContent 时要检索的字段:id、product_id 和 name。
- 执行查询
- 调用 client.query(...) 方法,传入构建的查询和操作名称 "get_products"。
- 此方法将查询发送到服务器并检索响应。
示例 pyproject.toml 配置。
注意:当 enable_custom_operations 设置为 true 时,queries_path 是可选的。
[tool.ariadne-codegen]
schema_path = "schema.graphql"
include_comments = "none"
target_package_name = "example_client"
enable_custom_operations = true
插件
Ariadne Codegen 实现了一个插件系统,该系统允许进一步自定义和微调生成的 Python 代码。它的文档可以在 PLUGINS.md 文件中单独查看。
标准插件
Ariadne Codegen 随附了可以从 ariadne_codegen.contrib
包导入的可选插件。
-
ariadne_codegen.contrib.shorter_results.ShorterResultsPlugin
- 此插件处理生成客户端方法,对于只请求单个顶层字段的操作,它们直接返回此字段的值而不是操作的结果类型。例如,为查询GetUser() { user(...) { ... }}
生成的 get_user 方法将直接返回 user 字段的值而不是GetUserResult
。 -
ariadne_codegen.contrib.extract_operations.ExtractOperationsPlugin
- 此插件将生成客户端方法的查询字符串提取到单独的operations.py
模块中。它还修改了生成的客户端以导入这些定义。生成的模块名称可以通过在配置中的[tool.ariadne-codegen.operations]
部分添加operations_module_name="custom_name"
进行自定义。例如。[tool.ariadne-codegen] ... plugins = ["ariadne_codegen.contrib.extract_operations.ExtractOperationsPlugin"] [tool.ariadne-codegen.extract_operations] operations_module_name = "custom_operations_module_name"
-
ariadne_codegen.contrib.client_forward_refs.ClientForwardRefsPlugin
- 此插件更改生成的客户端模块,将所有 Pydantic 模型的导入移至TYPE_CHECKING
条件下,使它们成为前向引用。这大大提高了client
模块的导入性能。 -
ariadne_codegen.contrib.no_reimports.NoReimportsPlugin
- 此插件移除生成的__init__.py
的内容。这在生成的插件包含大量 Pydantic 模型且客户端在首次导入时整个包的 eager 初始化非常慢的场景中非常有用。
使用生成的客户端
可以从包中导入生成的客户端。
from {target_package_name}.{client_file_name} import {client_name}
默认设置示例
from graphql_client.client import Client
将标题传递给客户端
客户端(使用默认基本客户端),接收传递的标题并将它们附加到每个发送的请求。
client = Client("https://example.com/graphql", {"Authorization": "Bearer token"})
对于更复杂的场景,您可以传递自己的 http 客户端
client = Client(http_client=CustomComplexHttpClient())
CustomComplexHttpClient
需要是一个 httpx.AsyncClient
的实例(用于异步客户端),或 httpx.Client
的实例(用于同步)。
Websockets
为了处理订阅,默认的 AsyncBaseClient
使用 websockets 并实现 graphql-transport-ws 子协议。将 ws_origin
和 ws_headers
参数添加为握手请求的标题,并使用 ws_connection_init_payload
作为 ConnectionInit 消息的有效负载。
文件上传
默认基本客户端(AsyncBaseClient
或 BaseClient
)检查 variables
字典的任何部分是否是 Upload
的实例。如果找到至少一个实例,则客户端根据 GraphQL 多部分请求规范 发送多部分请求。
类 Upload
包含在生成的客户端中,可以从其中导入。
from {target_package_name} import Upload
默认情况下,我们使用此类来表示 graphql 标量 Upload
。对于具有不同名称的此标量的模式,您仍然可以使用 Upload
和默认客户端进行文件上传。
[tool.ariadne-codegen.scalars.OTHERSCALAR]
type = "Upload"
OpenTelemetry
当配置选项 opentelemetry_client
设置为 true
时,默认的基础客户端会被替换为支持可选 OpenTelemetry 的客户端。默认情况下,这种支持不会做任何事情,但当 opentelemetry-api
包已安装且提供了 tracer
参数时,客户端将创建关于执行请求的数据的跨度。
由 BaseClientOpenTelemetry
处理的跟踪参数
tracer
:Optional[Union[str, Tracer]] = None
- 将传递给get_tracer
方法的跟踪对象或名称root_context
:Optional[Context] = None
- 可选的上下文,添加到根跨度root_span_name
:str = "GraphQL Operation"
- 根跨度名称
AsyncBaseClientOpenTelemetry
支持与 BaseClientOpenTelemetry
相同的所有参数,同时还公开了关于 WebSocket 的额外参数
ws_root_context
:Optional[Context] = None
- 可选的上下文,添加到 WebSocket 连接的根跨度ws_root_span_name
:str = "GraphQL Subscription"
- WebSocket 连接的根跨度名称
自定义标量
默认情况下,非内置标量在生成的客户端中表示为 typing.Any
。您可以通过向 pyproject.toml
中添加部分来提供有关特定标量的信息
[tool.ariadne-codegen.scalars.{graphql scalar name}]
type = "(required) python type name"
serialize = "function used to serialize scalar"
parse = "function used to create scalar instance from serialized form"
对于每个自定义标量,客户端将在所有 {graphql scalar name}
的出现中使用给定的 type
。如果提供了 serialize
和 parse
,则将用于序列化和反序列化。结果模型中的 type
将使用 BeforeValidator
注解,例如 Annotated[type, BeforeValidator(parse)]
。在输入注释中,将使用 PlainSerializer
,例如 Annotated[type, PlainSerializer(serialize)]
。如果 type
/serialize
/parse
至少包含一个 .
,则字符串将根据其最后一个出现点分割。第一部分将用作导入的模块,第二部分将用作类型/方法名称。例如,type = "custom_scalars.a.ScalarA"
将生成 from custom_scalars.a import ScalarA
。
将标量映射到内置类型的示例
在这种情况下,标量映射到内置 str
,不需要自定义的 serialize
和 parse
方法。
[tool.ariadne-codegen.scalars.SCALARA]
type = "str"
pydantic 支持的类型的示例
在这种情况下,标量表示为 datetime
,因此需要导入。Pydantic 处理序列化和反序列化,因此不需要自定义的 parse
和 serialize
。
[tool.ariadne-codegen.scalars.DATETIME]
type = "datetime.datetime"
完全自定义类型的示例
在此示例中,标量表示为类 TypeB
。Pydantic 无法处理序列化和反序列化,因此需要自定义 parse
和 serialize
。要提供 type
、parse
和 serialize
实现,我们可以使用 files_to_include
来复制 type_b.py
文件。
[tool.ariadne-codegen]
...
files_to_include = [".../type_b.py"]
[tool.ariadne-codegen.scalars.SCALARB]
type = ".type_b.TypeB"
parse = ".type_b.parse_b"
serialize = ".type_b.serialize_b"
# inputs.py
class TestInput(BaseModel):
value_b: Annotated[TypeB, PlainSerializer(serialize_b)]
# get_b.py
class GetB(BaseModel):
query_b: Annotated[TypeB, BeforeValidator(parse_b)]
# client.py
class Client(AsyncBaseClient):
async def test_mutation(self, value: TypeB) -> TestMutation:
...
variables: Dict[str, object] = {
"value": serialize_b(value),
}
...
扩展生成的类型
使用自定义混合扩展模型
mixin
指令允许通过自定义逻辑扩展为查询/突变字段生成的类。 mixin
需要两个必需参数
from
- 要从中导入的模块名称import
- 父类的名称
生成的类将使用 import
作为额外基类,并将导入添加到文件中。
from {from} import {import}
...
class OperationNameField(BaseModel, {import}):
...
此指令可以与 files_to_include
选项一起使用来扩展生成类的功能。
mixin
和 files_to_include
的使用示例
带有 mixin
指令的查询
query listUsers {
users @mixin(from: ".mixins", import: "UsersMixin") {
id
}
}
包含 files_to_include
的 pyproject.toml
部分(mixins.py
包含 UsersMixin
实现)
files_to_include = [".../mixins.py"]
生成的 list_users.py
文件的一部分
...
from .mixins import UsersMixin
...
class ListUsersUsers(BaseModel, UsersMixin):
...
多个客户端
要生成多个不同的客户端,您可以将每个配置存储在不同的文件中,然后通过 --config
选项提供配置文件的路径,例如。
ariadne-codegen --config clientA.toml
ariadne-codegen --config clientB.toml
生成的代码依赖关系
生成的代码需要
- pydantic
- httpx
- websockets(仅适用于默认异步基础客户端)
可以通过提供另一个带有 base_client_file_path
和 base_client_name
选项的基本客户端类来避免使用 httpx
和 websockets
依赖。
示例
关于简单模式和少量查询及变异的示例,请参阅此处。
生成 GraphSQL 模式的副本
您不仅可以生成客户端,还可以生成包含 GraphQL 模式副本的文件。为此,请使用带有 graphqlschema
参数调用 ariadne-codegen
。
ariadne-codegen graphqlschema
graphqlschema
模式从与 client
相同的位置读取配置,但仅使用 schema_path
、remote_schema_url
、remote_schema_headers
、remote_schema_verify_ssl
选项来检索模式,并使用 plugins
选项来加载插件。
除了上述内容外,graphqlschema
模式还接受特定于该模式的附加设置
target_file_path
一个包含生成文件目标路径的字符串。必须是 Python(.py
)或 GraphQL(.graphql
或 .gql
)文件。
默认为 schema.py
。
生成的 Python 文件将包含
- 必要的导入
- 类型映射声明
{type_map_variable_name}: TypeMap = {...}
- 模式声明
{schema_variable_name}: GraphQLSchema = GraphQLSchema(...)
生成的 GraphQL 文件将包含来自 graphql-core
包的 print_schema
函数的格式化输出。
schema_variable_name
一个用于模式变量的字符串名称,必须是有效的 Python 标识符。
默认为 "schema"
。仅在目标是 Python 文件时使用。
type_map_variable_name
一个用于类型映射变量的字符串名称,必须是有效的 Python 标识符。
默认为 "type_map"
。仅在目标是 Python 文件时使用。
贡献
我们欢迎所有人对 Ariadne 的贡献!如果您发现了错误或问题,请随时使用 GitHub 问题。如果您有任何问题或反馈,不要犹豫,在 GitHub 讨论中找到我们。
有关指导和说明,请参阅 CONTRIBUTING.md。
同时,请确保您关注 @AriadneGraphQL 以获取最新的更新、新闻和随想!
由 Mirumee Software 用 ❤️ 制作 hello@mirumee.com
项目详情
ariadne_codegen-0.14.0.tar.gz的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | d5b15470195c3858b88a2bae855b5c04602ffae40228077b6cfb26a57d3f14f6 |
|
MD5 | c9123cca9cb232c76bc7a21d211c7b67 |
|
BLAKE2b-256 | f4964f389335fd40db4ee685f594835181fec2692f8b362c51a6606e42bc904d |
ariadne_codegen-0.14.0-py2.py3-none-any.whl的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | e0553960bd298ddc49aeeb748a0be3a37acbdfdee7d7c26fce7154715fa826e0 |
|
MD5 | 13d9a9386729826587f49938f49085b1 |
|
BLAKE2b-256 | a9b02643c64d50df13ea2cc43ae4133292cad62ea6f95b7c377288592b385c4c |