Install & Compatibility
Where this runs
tested against v0.19.0 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
muslpy 3.10–3.910 runs
installs and imports cleanly · install 0.0s · import 0.367s · 37.6MB
glibcpy 3.10–3.910 runs
installs and imports cleanly · install 5.2s · import 0.322s · 37MB
38MB installed
● package 38MB
Code
Verified usage
Verified import paths — ran on the pinned version, not inferred.
Plugin
✓ from ariadne_codegen import Plugin
✗ from graphql_client.client import Client
plugins
✓ from ariadne_codegen import plugins
✗ from graphql_client.client import Client
This quickstart demonstrates how to use `ariadne-codegen` to generate a Python client and then interact with a GraphQL API. It involves defining a GraphQL schema and queries, configuring `ariadne-codegen` via `pyproject.toml`, running the code generator, and finally importing and using the generated client. The example simulates a generated client for demonstration purposes without requiring a live GraphQL server or the actual `ariadne-codegen` command execution during runtime.
import asyncio
import os
from pathlib import Path
# --- Setup: Create dummy schema and queries files ---
# In a real scenario, these files would exist in your project.
schema_content = '''
schema { query: Query mutation: Mutation subscription: Subscription }
type Query {
users(country: String): [User!]!
hello: String!
}
type Mutation {
createUser(name: String!, email: String!): User!
}
type Subscription {
randomNumber: Int!
}
type User {
id: ID!
name: String!
email: String!
country: String
}
'''
queries_content = '''
query ListAllUsers {
users {
id
name
email
country
}
}
mutation CreateNewUser($name: String!, $email: String!) {
createUser(name: $name, email: $email) {
id
name
email
}
}
'''
# Create a temporary directory for the quickstart
quickstart_dir = Path("./ariadne_codegen_quickstart")
quickstart_dir.mkdir(exist_ok=True)
schema_path = quickstart_dir / "schema.graphql"
queries_path = quickstart_dir / "queries.graphql"
schema_path.write_text(schema_content)
queries_path.write_text(queries_content)
# --- Step 1: Configure ariadne-codegen in pyproject.toml ---
pyproject_toml_content = f'''
[tool.ariadne-codegen]
schema_path = "{schema_path}"
queries_path = "{queries_path}"
target_package_name = "my_graphql_client"
target_package_path = "."
'''
pyproject_toml_path = quickstart_dir / "pyproject.toml"
pyproject_toml_path.write_text(pyproject_toml_content)
# --- Step 2: Run ariadne-codegen to generate the client ---
print("Generating GraphQL client...")
# This command needs to be run in the shell where `ariadne-codegen` is installed.
# For demonstration, we simulate its effect by assuming successful generation.
# In a real setup, you would run: `cd ariadne_codegen_quickstart && ariadne-codegen`
# For this runnable example, we will proceed as if 'my_graphql_client' was generated.
# A placeholder for actual generation:
# os.system(f"cd {quickstart_dir} && ariadne-codegen")
# To make this code runnable without `ariadne-codegen` actually being installed and run,
# we simulate the generated client structure. In a real scenario, these files would be created.
(quickstart_dir / "my_graphql_client").mkdir(exist_ok=True)
(quickstart_dir / "my_graphql_client" / "__init__.py").touch()
(quickstart_dir / "my_graphql_client" / "client.py").write_text(
"""from typing import Any, Dict, List, Optional
class User:
id: str
name: str
email: str
country: Optional[str]
class ListAllUsers:
users: List[User]
class CreateNewUser:
createUser: User
class AsyncBaseClient:
def __init__(self, url: str, headers: Optional[Dict[str, str]] = None):
self.url = url
self.headers = headers if headers is not None else {}
async def _execute(self, query: str, variables: Optional[Dict[str, Any]] = None) -> Dict[str, Any]:
# In a real client, this would make an actual HTTP request.
# For this example, we return mock data.
print(f"Executing query to {self.url} with headers: {self.headers}")
print(f"Query: {query}")
print(f"Variables: {variables}")
if "ListAllUsers" in query:
return {"data": {"users": [{"id": "1", "name": "Alice", "email": "alice@example.com", "country": "Wonderland"}]}}
if "CreateNewUser" in query:
return {"data": {"createUser": {"id": "2", "name": variables['name'], "email": variables['email']}}}
return {"data": {}}
class Client(AsyncBaseClient):
async def list_all_users(self) -> ListAllUsers:
query = """
query ListAllUsers {
users {
id
name
email
country
}
}
"""
data = await self._execute(query)
return ListAllUsers(users=[User(**user_data) for user_data in data['data']['users']])
async def create_new_user(self, name: str, email: str) -> CreateNewUser:
query = """
mutation CreateNewUser($name: String!, $email: String!) {
createUser(name: $name, email: $email) {
id
name
email
}
}
"""
variables = {"name": name, "email": email}
data = await self._execute(query, variables)
return CreateNewUser(createUser=User(**data['data']['createUser']))
""")
# Add placeholder pydantic BaseModels (actual generated models would be more complex)
(quickstart_dir / "my_graphql_client" / "base_model.py").write_text(
"""from pydantic import BaseModel
class BaseGraphQLModel(BaseModel):
class Config:
arbitrary_types_allowed = True
""")
# Ensure `my_graphql_client` is importable from the quickstart_dir
import sys
sys.path.insert(0, str(quickstart_dir))
from my_graphql_client.client import Client
from my_graphql_client.client import ListAllUsers, CreateNewUser
async def main():
# Replace with your actual GraphQL endpoint
graphql_url = os.environ.get('GRAPHQL_ENDPOINT', 'https://api.example.com/graphql')
# Replace with your actual authentication token if needed
auth_token = os.environ.get('GRAPHQL_AUTH_TOKEN', '')
headers = {}
if auth_token:
headers['Authorization'] = f'Bearer {auth_token}'
client = Client(url=graphql_url, headers=headers)
print("\n--- Listing all users ---")
all_users_result: ListAllUsers = await client.list_all_users()
for user in all_users_result.users:
print(f"User ID: {user.id}, Name: {user.name}, Email: {user.email}, Country: {user.country}")
print("\n--- Creating a new user ---")
new_user_result: CreateNewUser = await client.create_new_user(name="Charlie", email="charlie@example.com")
created_user = new_user_result.createUser
print(f"Created User ID: {created_user.id}, Name: {created_user.name}, Email: {created_user.email}")
# Clean up temporary files
import shutil
shutil.rmtree(quickstart_dir)
print(f"\nCleaned up temporary directory: {quickstart_dir}")
if __name__ == "__main__":
asyncio.run(main())
ariadne-codegen --version
Debug
Known issues
breakingAriadne Codegen's minor version increments for breaking changes until 1.0.0. Always check the changelog for new releases, as imports, class names, or behavior might change.fixReview the official changelog (e.g., on the Ariadne blog or GitHub releases) for each new minor version. Update generated client code and configurations accordingly.
affects: All versions before 1.0.0 (e.g., 0.x to 0.y where y > x).
breakingPydantic v2 support (>=2.0.0,<3.0.0) was introduced in version 0.8. This changed method names on generated models (e.g., `parse_obj` to `model_validate`, `dict` to `model_dump`) and removed `model_rebuild` calls.fixIf migrating from ariadne-codegen <0.8 and using Pydantic v2, update method calls on generated models from `parse_obj` to `model_validate` and `dict` to `model_dump`. Ensure your project's Pydantic version aligns with the `ariadne-codegen` version requirements.
affects: Versions 0.8 and later (when upgrading from <0.8).
gotchaThe default generated package name is `graphql_client`. If you don't specify `target_package_name` in `pyproject.toml`, your imports will need to reflect this default.fixAlways explicitly define `target_package_name` in your `pyproject.toml` (e.g., `target_package_name = "my_api_client"`) for clarity and consistency, or remember to import from `graphql_client.client` if using the default.
affects: All versions.
gotchaCustom scalars are by default represented as `typing.Any`. To get proper type hints and (de)serialization, you need to configure them in `pyproject.toml`.fixAdd a `[tool.ariadne-codegen.scalars.YOUR_SCALAR_NAME]` section to your `pyproject.toml` and specify `type`, `serialize`, and `parse` methods. For example, for a `DateTime` scalar: `[tool.ariadne-codegen.scalars.DateTime] type = "datetime.datetime" serialize = "str" parse = "isoformat"`.
affects: All versions.
breakingIn version 0.11, `GraphQlClientInvalidResponseError` was renamed to `GraphQLClientInvalidResponseError` (capital 'L'). Additionally, `GraphQLClientGraphQLMultiError` is now raised for payloads with an `errors` key but no `data`.fixUpdate exception handling in your code to catch the new error names: `GraphQLClientInvalidResponseError` and `GraphQLClientGraphQLMultiError`.
affects: Versions 0.11 and later (when upgrading from <0.11).
gotchaGenerated model field names might clash with Python reserved keywords or Pydantic `BaseModel` methods. `ariadne-codegen` appends an underscore to resolve some of these, but it's important to be aware.fixIf encountering issues with field names, inspect the generated client code. Consider using GraphQL aliases in your queries to rename problematic fields or implement a custom plugin to adjust name generation if necessary.
affects: All versions.
Upgrade
Version history
0.19.0latest on PyPI · released Aug 28, 2026
Audit
Dependencies
pydanticrequiredGenerated client models are based on Pydantic for type safety and data validation. Version >=2.0.0,<3.0.0 is supported since 0.8.
websocketsoptionalRequired by the default base client for GraphQL subscriptions.