ariadne-codegen
Generate fully typed GraphQL client from schema, queries and mutations!
Description
Ariadne Code Generator
Python code generator that takes graphql schema, queries, mutations and subscriptions and generates Python package with fully typed and asynchronous GraphQL client.
It's available as ariadne-codegen command and reads configuration from the pyproject.toml file:
$ ariadne-codegen
It can also be run as python -m ariadne_codegen.
Features
- Generate pydantic models from schema types, inputs and enums.
- Generate pydantic models for GraphQL results.
- Generate client package with each GraphQL operation available as async method.
Installation
Ariadne Code Generator can be installed with pip:
$ pip install ariadne-codegen
To support subscriptions, default base client requires websockets package:
$ pip install ariadne-codegen[subscriptions]
Configuration
ariadne-codegen reads configuration from [tool.ariadne-codegen] section in your pyproject.toml. You can use other configuration file with --config option, eg. ariadne-codegen --config custom_file.toml
Minimal configuration for client generation:
[tool.ariadne-codegen]
schema_path = "schema.graphql"
queries_path = "queries.graphql"
Required settings:
queries_path- path to file/directory with queries (Can be optional ifenable_custom_operationsis used)
One of the following 2 parameters is required, in case of providing both of them schema_path is prioritized:
schema_path- path to file/directory with graphql schemaremote_schema_url- url to graphql server, where introspection query can be perfomed
Optional settings:
remote_schema_headers- extra headers that are passed along with introspection query, eg.{"Authorization" = "Bearer token"}. To include an environment variable in a header value, prefix the variable with$, eg.{"Authorization" = "$AUTH_TOKEN"}remote_schema_verify_ssl(defaults totrue) - a flag that specifies wheter to verify ssl while introspecting remote schemaremote_schema_timeout(defaults to5) - timeout in seconds while introspecting remote schematarget_package_name(defaults to"graphql_client") - name of generated packagetarget_package_path(defaults to cwd) - path where to generate packageclient_name(defaults to"Client") - name of generated client classclient_file_name(defaults to"client") - name of file with generated client classbase_client_name(defaults to"AsyncBaseClient") - name of base client classbase_client_file_path(defaults to.../ariadne_codegen/client_generators/dependencies/async_base_client.py) - path to file wherebase_client_nameis definedenums_module_name(defaults to"enums") - name of file with generated enums modelsinput_types_module_name(defaults to"input_types") - name of file with generated input types modelsfragments_module_name(defaults to"fragments") - name of file with generated fragments modelsinclude_comments(defaults to"stable") - option which sets content of comments included at the top of every generated file. Valid choices are:"none"(no comments),"timestamp"(comment with generation timestamp),"stable"(comment contains a message that this is a generated file)convert_to_snake_case(defaults totrue) - a flag that specifies whether to convert fields and arguments names to snake caseinclude_all_inputs(defaults totrue) - a flag specifying whether to include all inputs defined in the schema, or only those used in supplied operationsinclude_all_enums(defaults totrue) - a flag specifying whether to include all enums defined in the schema, or only those used in supplied operationsasync_client(defaults totrue) - default generated client isasync, change this to optionfalseto generate synchronous client insteadopentelemetry_client(defaults tofalse) - default base clients don't support any performance tracing. Change this option totrueto use the base client with Open Telemetry support.files_to_include(defaults to[]) - list of files which will be copied into generated packageplugins(defaults to[]) - list of plugins to use during generationenable_custom_operations(defaults tofalse) - enables building custom operations. Generates additional files that contains all the classes and methods for generation.
Custom operation builder
The custom operation builder allows you to create complex GraphQL queries in a structured and intuitive way.
Example Code
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())
Explanation
- Building the Product Query:
- The Query.product(id="...", channel="channel-uk") initiates a query for a product with the specified ID and channel.
- .fields(ProductFields.id, ProductFields.name) specifies the fields to retrieve for the product: id and name.
- Building the Translation Query:
- The Query.translations(kind=TranslatableKinds.PRODUCT, first=10) initiates a query for product translations.
- .fields(...) specifies the fields to retrieve for the translations.
- .alias("aliased_edges") renames the edges field to aliased_edges.
- .on("ProductTranslatableContent", ...) specifies the fields to retrieve if the node is of type ProductTranslatableContent: id, product_id, and name.
- Executing the Queries:
- The client.query(...) method is called with the built queries and an operation name "get_products".
- This method sends the queries to the server and retrieves the response.
Example pyproject.toml configuration.
Note: queries_path is optional when enable_custom_operations is set to true
[tool.ariadne-codegen]
schema_path = "schema.graphql"
include_comments = "none"
target_package_name = "example_client"
enable_custom_operations = true
Plugins
Ariadne Codegen implements a plugin system that enables further customization and fine-tuning of generated Python code. It’s documentation is available separately in the PLUGINS.md file.
Standard plugins
Ariadne Codegen ships with optional plugins importable from the ariadne_codegen.contrib package:
-
ariadne_codegen.contrib.shorter_results.ShorterResultsPlugin- This plugin processes generated client methods for operations where only single top field is requested, so they return this field's value directly instead of operation's result type. For example get_user method generated for queryGetUser() { user(...) { ... }}will return value of user field directly instead ofGetUserResult. -
ariadne_codegen.contrib.extract_operations.ExtractOperationsPlugin- This extracts query strings from generated client's methods into separateoperations.pymodule. It also modifies the generated client to import these definitions. Generated module name can be customized by addingoperations_module_name="custom_name"to the[tool.ariadne-codegen.operations]section in config. Eg.:[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- This plugin changes generated client module moving all Pydantic models imports under theTYPE_CHECKINGcondition, making them forward references. This greatly improves the import performance of theclientmodule. -
ariadne_codegen.contrib.no_reimports.NoReimportsPlugin- This plugin removes content of generated__init__.py. This is useful in scenarios where generated plugins contain so many Pydantic models that client's eager initialization of entire package on first import is very slow.
Using generated client
Generated client can be imported from package:
from {target_package_name}.{client_file_name} import {client_name}
Example with default settings:
from graphql_client.client import Client
