Example
December 6, 2025 ยท View on GitHub
Schema file
schema {
query: Query
mutation: Mutation
subscription: Subscription
}
type Query {
users(country: String): [User!]!
}
type Mutation {
userCreate(userData: UserCreateInput!): User
userPreferences(data: UserPreferencesInput): Boolean!
fileUpload(file: Upload!): Boolean!
}
type Subscription {
usersCounter: Int!
}
scalar Upload
input UserCreateInput {
firstName: String
lastName: String
email: String!
favouriteColor: Color
location: LocationInput
}
input LocationInput {
city: String
country: String
}
type User {
id: ID!
firstName: String
lastName: String
email: String!
favouriteColor: Color
location: Location
}
type Location {
city: String
country: String
}
enum Color {
BLACK
WHITE
RED
GREEN
BLUE
YELLOW
}
input UserPreferencesInput {
luckyNumber: Int = 7
favouriteWord: String = "word"
colorOpacity: Float = 1.0
excludedTags: [String!] = ["offtop", "tag123"]
notificationsPreferences: NotificationsPreferencesInput! = {
receiveMails: true
receivePushNotifications: true
receiveSms: false
title: "Mr"
}
}
input NotificationsPreferencesInput {
receiveMails: Boolean!
receivePushNotifications: Boolean!
receiveSms: Boolean!
title: String!
}
Queries/mutations/subscriptions file
mutation CreateUser($userData: UserCreateInput!) {
userCreate(userData: $userData) {
id
}
}
query ListAllUsers {
users {
id
firstName
lastName
email
location {
country
}
}
}
query ListUsersByCountry($country: String) {
users(country: $country) {
...BasicUser
...UserPersonalData
favouriteColor
}
}
fragment BasicUser on User {
id
email
}
fragment UserPersonalData on User {
firstName
lastName
}
subscription GetUsersCounter {
usersCounter
}
mutation uploadFile($file: Upload!) {
fileUpload(file: $file)
}
Running
Add [tool.ariadne-codegen] section to pyproject.toml with paths to files with schema and queries/mutations.
[tool.ariadne-codegen]
schema_path = "schema.graphql"
queries_path = "queries.graphql"
Run command to generate code:
$ ariadne-codegen
Result
Generated files
Structure of generated package:
grapql_client/
__init__.py
async_base_client.py
base_model.py
client.py
create_user.py
enums.py
exceptions.py
fragments.py
get_users_counter.py
input_types.py
list_all_users.py
list_users_by_country.py
scalars.py
upload_file.py
Client class
Generated client class inherits from AsyncBaseClient and has async method for every provided query/mutation.
# graphql_client/client.py
from collections.abc import AsyncIterator
from typing import Any, Optional, Union
from .async_base_client import AsyncBaseClient
from .base_model import UNSET, UnsetType, Upload
from .create_user import CreateUser
from .get_users_counter import GetUsersCounter
from .input_types import UserCreateInput
from .list_all_users import ListAllUsers
from .list_users_by_country import ListUsersByCountry
from .upload_file import UploadFile
def gql(q: str) -> str:
return q
class Client(AsyncBaseClient):
async def create_user(
self, user_data: UserCreateInput, **kwargs: Any
) -> CreateUser:
query = gql(
"""
mutation CreateUser($userData: UserCreateInput!) {
userCreate(userData: $userData) {
id
}
}
"""
)
variables: dict[str, object] = {"userData": user_data}
response = await self.execute(
query=query, operation_name="CreateUser", variables=variables, **kwargs
)
data = self.get_data(response)
return CreateUser.model_validate(data)
async def list_all_users(self, **kwargs: Any) -> ListAllUsers:
query = gql(
"""
query ListAllUsers {
users {
id
firstName
lastName
email
location {
country
}
}
}
"""
)
variables: dict[str, object] = {}
response = await self.execute(
query=query, operation_name="ListAllUsers", variables=variables, **kwargs
)
data = self.get_data(response)
return ListAllUsers.model_validate(data)
async def list_users_by_country(
self, country: Union[Optional[str], UnsetType] = UNSET, **kwargs: Any
) -> ListUsersByCountry:
query = gql(
"""
query ListUsersByCountry($country: String) {
users(country: $country) {
...BasicUser
...UserPersonalData
favouriteColor
}
}
fragment BasicUser on User {
id
email
}
fragment UserPersonalData on User {
firstName
lastName
}
"""
)
variables: dict[str, object] = {"country": country}
response = await self.execute(
query=query,
operation_name="ListUsersByCountry",
variables=variables,
**kwargs
)
data = self.get_data(response)
return ListUsersByCountry.model_validate(data)
async def get_users_counter(self, **kwargs: Any) -> AsyncIterator[GetUsersCounter]:
query = gql(
"""
subscription GetUsersCounter {
usersCounter
}
"""
)
variables: dict[str, object] = {}
async for data in self.execute_ws(
query=query, operation_name="GetUsersCounter", variables=variables, **kwargs
):
yield GetUsersCounter.model_validate(data)
async def upload_file(self, file: Upload, **kwargs: Any) -> UploadFile:
query = gql(
"""
mutation uploadFile($file: Upload!) {
fileUpload(file: $file)
}
"""
)
variables: dict[str, object] = {"file": file}
response = await self.execute(
query=query, operation_name="uploadFile", variables=variables, **kwargs
)
data = self.get_data(response)
return UploadFile.model_validate(data)
Base client
Base client is copied from path provided in base_client_file_path and has to contain definition of class with name provided in base_client_name.
Base model
base_model.py is a file that contains preconfigured class, which extends pydantic's BaseModel class and is used by other generated classes.
Input types
Models are generated from inputs from provided schema. They are used as arguments types in client`s methods.
# graphql_client/input_types.py
from typing import Optional
from pydantic import Field
from .base_model import BaseModel
from .enums import Color
class UserCreateInput(BaseModel):
first_name: Optional[str] = Field(alias="firstName", default=None)
last_name: Optional[str] = Field(alias="lastName", default=None)
email: str
favourite_color: Optional[Color] = Field(alias="favouriteColor", default=None)
location: Optional["LocationInput"] = None
class LocationInput(BaseModel):
city: Optional[str] = None
country: Optional[str] = None
class UserPreferencesInput(BaseModel):
lucky_number: Optional[int] = Field(alias="luckyNumber", default=7)
favourite_word: Optional[str] = Field(alias="favouriteWord", default="word")
color_opacity: Optional[float] = Field(alias="colorOpacity", default=1.0)
excluded_tags: Optional[list[str]] = Field(
alias="excludedTags", default_factory=lambda: ["offtop", "tag123"]
)
notifications_preferences: "NotificationsPreferencesInput" = Field(
alias="notificationsPreferences",
default_factory=lambda: globals()[
"NotificationsPreferencesInput"
].model_validate(
{
"receiveMails": True,
"receivePushNotifications": True,
"receiveSms": False,
"title": "Mr",
}
),
)
class NotificationsPreferencesInput(BaseModel):
receive_mails: bool = Field(alias="receiveMails")
receive_push_notifications: bool = Field(alias="receivePushNotifications")
receive_sms: bool = Field(alias="receiveSms")
title: str
Enums
Enums are generated from enums from provided schema. They are used in other generated classes as field types, but also as arguments types in client`s methods.
# graphql_client/enums.py
from enum import Enum
class Color(str, Enum):
BLACK = "BLACK"
WHITE = "WHITE"
RED = "RED"
GREEN = "GREEN"
BLUE = "BLUE"
YELLOW = "YELLOW"
Query/mutation/subscription types
For every provided query/mutation/subscription there is a generated file that contains models which correspond to return type of operation. File name is generated by converting operation name to snake case. Root models has the same name as query/mutation/subscription, and depend classes use it as prefix in their names.
# graphql_client/create_user.py
from typing import Optional
from pydantic import Field
from .base_model import BaseModel
class CreateUser(BaseModel):
user_create: Optional["CreateUserUserCreate"] = Field(alias="userCreate")
class CreateUserUserCreate(BaseModel):
id: str
# graphql_client/list_all_users.py
from typing import Optional
from pydantic import Field
from .base_model import BaseModel
class ListAllUsers(BaseModel):
users: list["ListAllUsersUsers"]
class ListAllUsersUsers(BaseModel):
id: str
first_name: Optional[str] = Field(alias="firstName")
last_name: Optional[str] = Field(alias="lastName")
email: str
location: Optional["ListAllUsersUsersLocation"]
class ListAllUsersUsersLocation(BaseModel):
country: Optional[str]
# graphql_client/list_users_by_country.py
from typing import Optional
from pydantic import Field
from .base_model import BaseModel
from .enums import Color
from .fragments import BasicUser, UserPersonalData
class ListUsersByCountry(BaseModel):
users: list["ListUsersByCountryUsers"]
class ListUsersByCountryUsers(BasicUser, UserPersonalData):
favourite_color: Optional[Color] = Field(alias="favouriteColor")
# graphql_client/get_users_counter.py
from pydantic import Field
from .base_model import BaseModel
class GetUsersCounter(BaseModel):
users_counter: int = Field(alias="usersCounter")
# graphql_client/upload_file.py
from pydantic import Field
from .base_model import BaseModel
class UploadFile(BaseModel):
file_upload: bool = Field(alias="fileUpload")
Fragments file
This file contains classes generated from all fragments used in any provided operation.
# graphql_client/fragments.py
from typing import Optional
from pydantic import Field
from .base_model import BaseModel
class BasicUser(BaseModel):
id: str
email: str
class UserPersonalData(BaseModel):
first_name: Optional[str] = Field(alias="firstName")
last_name: Optional[str] = Field(alias="lastName")
BasicUser.model_rebuild()
UserPersonalData.model_rebuild()
Init file
Generated init file contains reimports and list of all generated classes.
# graphql_client/__init__.py
from .async_base_client import AsyncBaseClient
from .base_model import BaseModel, Upload
from .client import Client
from .create_user import CreateUser, CreateUserUserCreate
from .enums import Color
from .exceptions import (
GraphQLClientError,
GraphQLClientGraphQLError,
GraphQLClientGraphQLMultiError,
GraphQLClientHttpError,
GraphQLClientInvalidResponseError,
)
from .fragments import BasicUser, UserPersonalData
from .get_users_counter import GetUsersCounter
from .input_types import (
LocationInput,
NotificationsPreferencesInput,
UserCreateInput,
UserPreferencesInput,
)
from .list_all_users import ListAllUsers, ListAllUsersUsers, ListAllUsersUsersLocation
from .list_users_by_country import ListUsersByCountry, ListUsersByCountryUsers
from .upload_file import UploadFile
__all__ = [
"AsyncBaseClient",
"BaseModel",
"BasicUser",
"Client",
"Color",
"CreateUser",
"CreateUserUserCreate",
"GetUsersCounter",
"GraphQLClientError",
"GraphQLClientGraphQLError",
"GraphQLClientGraphQLMultiError",
"GraphQLClientHttpError",
"GraphQLClientInvalidResponseError",
"ListAllUsers",
"ListAllUsersUsers",
"ListAllUsersUsersLocation",
"ListUsersByCountry",
"ListUsersByCountryUsers",
"LocationInput",
"NotificationsPreferencesInput",
"Upload",
"UploadFile",
"UserCreateInput",
"UserPersonalData",
"UserPreferencesInput",
]