Skip to main content

Ariadne Codegen 0.10

· 5 min read

Ariadne Codegen 0.10 has been released!

This release improves the snake case conversion of operation names, adds opt-in support for Open Telemetry tracing, introduces the ExtractOperationsPlugin plugin, adds Python 3.12 to the supported versions, and brings other features and fixes.

Converting capitalized names and digits to snake case (breaking change)

Codegen converts given operation name to snake case. Result will later be used as name of a file containing generated models for operation, optionally (if convert_to_snake_case is set to true) also as client's method name. This release introduces changes to how numbers and capitalised names are handled in the conversion process, e.g:

operation nameold snake casenew snake case
namenamename
operationNameoperation_nameoperation_name
operationNAMEoperation_n_a_m_eoperation_name
OPERATIONNameo_p_e_r_a_t_i_o_n_nameoperation_name
operationName123operation_name123operation_name_123
operationNAME123operation_n_a_m_e123operation_name_123

This is potentially a breaking change and may require changes in code using generated client.

Open Telemetry tracing

0.10 ships with two additional base clients that support the Open Telemetry tracing. When the opentelemetry_client configuration option is set to true, the default included base client is replaced with one that implements the opt-in Open Telemetry support - BaseClientOpenTelemetry/AsyncBaseClientOpenTelemetry. By default this support does nothing, but if the opentelemetry-api package is installed and the tracer argument is provided, then the client will create spans with data about requests made.

Tracing arguments accepted by BaseClientOpenTelemetry:

  • tracer: Optional[Union[str, Tracer]] = None - tracer object or name to pass to the get_tracer method
  • root_context: Optional[Context] = None - optional context added to the root span
  • root_span_name: str = "GraphQL Operation" - name of the root span

AsyncBaseClientOpenTelemetry supports the same arguments as BaseClientOpenTelemetry, but also accepts additional arguments regarding websockets:

  • ws_root_context: Optional[Context] = None - optional context added to root span for websocket connection
  • ws_root_span_name: str = "GraphQL Subscription" - name of root span for websocket connection

Included comments

In 0.10 we changed the include_comments option to allow selection of the style of comments to be included at the top of each generated file. Available options:

  • "timestamp" - comment with generation timestamp
  • "stable" - comment with message that this is a generated file (new default)
  • "none" - no comments

Previous boolean support is deprecated and will be dropped in future releases, but for now false is mapped to "none" and true to "timestamp".

ExtractOperationsPlugin

Version 0.10 adds ExtractOperationsPlugin to the ariadne_codegen.contrib package. It moves query strings from the generated client's methods into a separate operations.py module and changes the generated client to import these definitions instead. The generated module name can be customized by adding operations_module_name="custom_name" to the [tool.ariadne-codegen.operations] section in config. E.g:

# queries.graphql
query getName {
name
}

pyproject.toml:

[tool.ariadne-codegen]
...
queries_path = "..../queries.graphql"
plugins = ["ariadne_codegen.contrib.extract_operations.ExtractOperationsPlugin"]

[tool.ariadne-codegen.extract_operations]
operations_module_name = "custom_operations"

Using the above configuration will result in the custom_operations.py being generated with following contents:

__all__ = ["GET_NAME"]

GET_NAME = """
query getName {
name
}
"""

The generated client imports GET_NAME and uses it instead of defining it's own operation string:

from .custom_operations import GET_NAME
from .get_name import GetName


def gql(q: str) -> str:
return q


class Client(AsyncBaseClient):
async def get_name(self, **kwargs: Any) -> GetName:
variables: Dict[str, object] = {}
response = await self.execute(query=GET_NAME, variables=variables, **kwargs)
data = self.get_data(response)
return GetName.model_validate(data)

Overloading arguments per call

Each generated client's method now accepts **kwargs and passes them to the http_client.post/ws_connect call made in the base client.

Escaping enum values which are Python keywords

GraphQL enum values that are Python reserved keywords will now be suffixed with _ in generated code, just like this is the case with generated field names for models, e.g:

enum CustomEnum {
valid
import
}
# enums.py
from enum import Enum


class CustomEnum(str, Enum):
valid = "valid"
import_ = "import"

Adding __typename to all models generated from unions and interfaces

In previous versions, models created from single-member unions or from interfaces that were queried without inline fragments didn't have a __typename field added. Now 0.10 includes this special field in all models generated from abstract types.

Nullable fields with nullable directives

0.10 fixes behaviour when the default None was not added to a nullable field with a @skip/@include directive.

Ignored enums_module_name

Codegen now correctly reads enums_module_name and uses its value instead of always generating enums.py.

Changelog

  • Fixed generating results for nullable fields with nullable directives.
  • Changed include_comments option to accept enum value, changed default to "stable", deprecated boolean support. Added get_file_comment plugin hook.
  • Changed str_to_snake_case utility to correctly handle capitalized words.
  • Digits in Python names are now preceded by an underscore (breaking change).
  • Fixed parsing of unions and interfaces to always add __typename to generated result models.
  • Added escaping of enum values which are Python keywords by appending _ to them.
  • Fixed enums_module_name option not being passed to generators.
  • Added additional base clients supporting the Open Telemetry tracing. Added opentelemetry_client config option.
  • Changed generated client's methods to pass **kwargs to base client's execute and execute_ws methods (breaking change for custom base clients).
  • Added operation_definition argument to generate_client_method plugin hook.
  • Added ExtractOperationsPlugin that extracts operation strings from client methods to separate module.
  • Added Python 3.12 to tested versions.