Skip to main content

A pythonic way to build GraphQL queries

Project description

grafq

grafq is a library designed to help constructing GraphQL queries with idiomatic Python. It provides a concise and simple API to build such queries incrementally, with strong emphasis on correctness and type safety. Partial queries can be shared, composed and modified trivially, and fully formed queries can be converted to strings and reused infinitely with zero cost.

Example

from grafq import Field, Var, Query
from grafq.client import Client

client = Client("https://api.github.com/graphql", token=TOKEN)

simple = Query().select("viewer.login", "viewer.name").build()
data = client.get(simple)

schema = client.schema(strict=True)
using_schema = (
    client.new_query()
    .select(schema.repository(owner="asmello", name="grafq").url)
    .build_and_run()
)

composition = (
    client.new_query()
    .var("size", "Int")
    .select(
        Field("viewer").select(
            "login", "name", Field("avatarUrl", size=Var("size"))
        ),
        schema.repository(owner="asmello", name="grafq").url,
    )
    .build_and_run(variables={"size": 200})
)

FAQ

Can't I just type out the query directly?

Yes, but usage of string literals with embedded code have a number of practical disadvantages:

  1. Poor IDE support - most IDEs aren't smart enough to detect that your string contains some GraphQL code and won't interpret the embedded code specially. This means loss of important productivity features like syntax highlighting, type hinting, reference validation and autocomplete. This can be sometimes worked around by placing queries in separate files, but that creates a number of overheads and error conditions that are best avoided.
  2. Error proneness - given lack of tooling support, it's much easier to make mistakes that won't be flagged until the code is executed in an integration test or in production.
  3. Poor integration - when represented as a string, embedded code has to be manipulated as such. This creates surface area for bugs and vulnerabilities, and makes dynamic queries just a royal pain to implement.
  4. Poor reusability - it's far too easy to end up just creating static ad-hoc queries everywhere, when often times there are reusable components that could be shared around. Fragments help avoiding that, but are hard to use correctly in practice due to (3).

All of these (and other reasons) have led to the development of this library, which makes it possible to construct and manipulate GraphQL queries in a first class manner, using plain old Python objects.

Did you mention type safety?

Type safety is opt-in. If you use the Field API, you can create typeless queries that work just as well as typed ones. Then you delegate error-catching to the server, which may or may not provide useful context.

If you choose to use the sugar-sweet TypedField API (accesible from a Schema object), however, every field and variable is validated as early as possible, client-side, as you build the query. Validation will still occur at runtime, but before the query is fully built and executes. Bear in mind that currently this has a noticeable overhead, as introspection queries are relatively expensive (but in the future better caching will minimise this).

Further, there are plans to support generating schema classes staticallly, which can then be used for offline type-checking using Python's native type hinting system. This has the downside that the generated classes need to be kept in sync with the remote API, but it has the upside that IDE features (like type checking and auto-complete) can be leveraged to their full potential at virtually no runtime cost.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

grafq-0.0.3.tar.gz (10.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

grafq-0.0.3-py3-none-any.whl (9.7 kB view details)

Uploaded Python 3

File details

Details for the file grafq-0.0.3.tar.gz.

File metadata

  • Download URL: grafq-0.0.3.tar.gz
  • Upload date:
  • Size: 10.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.4.2 importlib_metadata/4.8.1 pkginfo/1.7.1 requests/2.26.0 requests-toolbelt/0.9.1 tqdm/4.62.3 CPython/3.9.7

File hashes

Hashes for grafq-0.0.3.tar.gz
Algorithm Hash digest
SHA256 81e4eca8c2c88d9852d3eacf7014a0f92256002c43af8a7a766d9b5dd8878938
MD5 9ed068a1eb832c24b0a486ac442d38bd
BLAKE2b-256 79954cff39af63c2396f2fdd94244d8f70ca1b6eb63c561a79c1c380a24d2d47

See more details on using hashes here.

File details

Details for the file grafq-0.0.3-py3-none-any.whl.

File metadata

  • Download URL: grafq-0.0.3-py3-none-any.whl
  • Upload date:
  • Size: 9.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.4.2 importlib_metadata/4.8.1 pkginfo/1.7.1 requests/2.26.0 requests-toolbelt/0.9.1 tqdm/4.62.3 CPython/3.9.7

File hashes

Hashes for grafq-0.0.3-py3-none-any.whl
Algorithm Hash digest
SHA256 ec944fc59104fabffd54a261769b2a27869332e7d55443e561dea6eaba42b6de
MD5 79f68dd4e687ee3ce399c2c3c6ddf863
BLAKE2b-256 3d41e5ccd032b20187bf891cd4a868c7ef0e3e6c3ccb4b8474bd33ce33fe079d

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page