graphql-query
A complete Python DSL for building correct GraphQL query strings from typed classes.
Repository Health
Technical Analysis
graphql-query is a Python domain-specific language for constructing GraphQL queries programmatically. Instead of hand-writing and string-concatenating query text, you compose Python objects for operations, queries, fields, arguments, variables, fragments, and directives, then render them into a correctly formatted GraphQL string.
Built on Pydantic, it validates query structure at construction time and lets you share and reuse arguments, variables, and fragments across many queries. It can also generate graphql-query classes from an existing Pydantic data model, making it a good fit for codegen workflows and typed API clients.
What You Get
- A typed object model for every GraphQL construct: operations, queries, fields, arguments, variables, fragments, inline fragments, and directives
- A render() method that emits correctly formatted, indented GraphQL query strings
- Reusable Argument, Variable, and Fragment objects shared across multiple queries
- Pydantic-based validation of query structure at construction time
- Generation of graphql-query classes from Pydantic data models for codegen pipelines
Common Use Cases
- Programmatically building GraphQL queries in API clients and SDK layers
- Generating queries dynamically based on runtime field selection
- Sharing common arguments, variables, and fragments across a query library
- Producing GraphQL queries from Pydantic schemas in code-generation tools
Under The Hood
Architecture
The library is organized around a small set of Pydantic model classes in graphql_query/types.py (Variable, Argument, Directive, Field, Fragment, InlineFragment, Query, Operation), all descending from an abstract _GraphQL2PythonQuery base that provides shared line-shifting and rendering helpers. Each type owns a render() method that fills a corresponding Jinja2 template from graphql_query/templates/ (operation.jinja2, query.jinja2, field.jinja2, etc.), so string formatting is fully data-driven rather than hand-concatenated. A base_model.py customizes the Pydantic base configuration.
Tech Stack
Pure Python (3.8+) with Pydantic 2 for the typed model layer and Jinja2 for template rendering. Packaging uses Hatchling with the version sourced from graphql_query/__version__.py. typing_extensions supplies TypeGuard on Python 3.9 and earlier. Documentation is built with MkDocs.
Code Quality
The repo ships a substantial pytest suite under tests/ with dedicated modules per construct (test_query, test_field, test_argument, test_operation, test_fragment, test_directive, and a template-existence check), plus type hints throughout and a py.typed marker for downstream type checking. Code is modular and small, with rendering concerns isolated in templates.
API Design
The public API is compact and ergonomic: you instantiate a handful of clearly named classes and call render(). Field lists accept plain strings, Field objects, or fragments interchangeably, keeping simple cases terse while supporting full GraphQL expressiveness. The README and hosted docs give copy-paste examples for each construct, so onboarding is quick for anyone who already knows GraphQL.