Python code generator that takes graphql schema, queries and mutations 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
- 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.
Ariadne Code Generator can be installed with pip:
$ pip install ariadne-codegen
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
Required settings:
queries_path
- path to file/directory with queries
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"}
target_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.../graphql_sdk_gen/generators/async_base_client.py
) - path to file wherebase_client_name
is 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 modelsinclude_comments
(defaults totrue
) - a flag that specifies whether to include comments in generated filesconvert_to_snake_case
(defaults totrue
) - a flag that specifies whether to convert fields and arguments names to snake caseasync_client
(defaults totrue
) - default generated client isasync
, change this to optionfalse
to generate synchronous client insteadfiles_to_include
(defaults to[]
) - list of files which will be copied into generated packageplugins
(defaults to[]
) - list of plugins to use during generation
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.
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
Client (with default base client), takes passed headers and attaches them to every sent request.
client = Client("https://example.com/graphql", {"Authorization": "Bearer token"})
For more complex scenarios, you can pass your own http client:
client = Client(http_client=CustomComplexHttpClient())
By default, not built-in scalars are represented as typing.Any
in generated client.
You can provide information about specific scalar by adding section to 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"
import = "module to import from"
All occurences of {graphql scalar name}
will be represented as type
. If provided, serialize
and parse
will be used for serialization and deserialization. In all files which use type
/serialize
/parse
there will be added extra import from {import} import {type}, {serialize}, {parse}
In this case scalar is mapped to built-in str
which doesn`t require custom serialize
and parse
methods.
[tool.ariadne-codegen.scalars.SCALARA]
type = "str"
In this scenario scalar is represented as datetime
, so it needs to be imported. Pydantic handles serialization and deserialization so custom parse
and serialize
is not necessary.
[tool.ariadne-codegen.scalars.DATETIME]
type = "datetime"
import = "datetime"
In this example scalar is represented as class TypeB
. Pydantic can`t handle serialization and deserialization so custom parse
and serialize
is necessary. To provide type
, parse
and serialize
implementation we can use files_to_include
to copy type_b.py
file.
[tool.ariadne-codegen]
...
files_to_include = [".../type_b.py"]
[tool.ariadne-codegen.scalars.SCALARB]
type = "TypeB"
parse = "parse_b"
serialize = "serialize_b"
import = ".type_b"
mixin
directive allows to extend class generated for query/mutation field with custom logic.
mixin
takes two required arguments:
from
- name of a module to import fromimport
- name of a parent class
Generated class will use import
as extra base class, and import will be added to the file.
from {from} import {import}
...
class OperationNameField(BaseModel, {import}):
...
This directive can be used along with files_to_include
option to extend funcionallity of generated classes.
Query with mixin
directive:
query listUsers {
users @mixin(from: ".mixins", import: "UsersMixin") {
id
}
}
Part of pyproject.toml
with files_to_include
(mixins.py
contains UsersMixin
implementation)
files_to_include = [".../mixins.py"]
Part of generated list_users.py
file:
...
from .mixins import UsersMixin
...
class ListUsersUsers(BaseModel, UsersMixin):
...
To generate multiple different clients you can store config for each in different file, then provide path to config file by --config
option, eg.
ariadne-codegen --config clientA.toml
ariadne-codegen --config clientB.toml
Generated code requires:
- pydantic
- httpx (can be avoided by providing another base client class with
base_client_file_path
andbase_client_name
parameters)
Example with simple schema and few queries and mutations is available here.
We welcome all contributions to Ariadne! If you've found a bug or issue, feel free to use GitHub issues. If you have any questions or feedback, don't hesitate to catch us on GitHub discussions.
Also make sure you follow @AriadneGraphQL on Twitter for latest updates, news and random musings!