Capable GraphQL client for Python.
Features:
- Sync/async compatible, pluggable HTTP clients.
- Auto-generate typed and documented python APIs
- ORM-like syntax to write GraphQL.
Note that this project is in an early alpha stage. Some features are not yet implemented (see the roadmap below), and it may be a little rough around the edges. If you encounter a problem or have a feature request, don't hesitate to open an issue in the issue tracker.
A quick 'n dirty request to GitHub's new V4 API:
>>> import quiz
>>> query = '''
... {
... repository(owner: "octocat", name: "Hello-World") {
... createdAt
... description
... }
... }
... '''
>>> quiz.execute(query, url='https://api.github.com/graphql',
... auth=('me', 'password'))
{"repository": ...}
Adaptability. Built on top of snug, quiz supports different HTTP clients
import requests result = quiz.execute(query, ..., client=requests.Session())
as well as async execution (optionally with aiohttp):
result = await quiz.execute_async(query, ...)
Typing. Convert a GraphQL schema into documented python classes:
>>> schema = quiz.Schema.from_url('https://api.github.com/graphql', ... auth=('me', 'password')) >>> help(schema.Repository) class Repository(Node, ProjectOwner, Subscribable, Starrable, UniformResourceLocatable, RepositoryInfo, quiz.types.Object) | A repository contains the content for a project. | | Method resolution order: | ... | | Data descriptors defined here: | | assignableUsers | : UserConnection | A list of users that can be assigned to issues in this repo | | codeOfConduct | : CodeOfConduct or None | Returns the code of conduct for this repository ...
GraphQL "ORM". Write queries as you would with an ORM:
>>> _ = quiz.SELECTOR >>> query = schema.query[ ... _ ... .repository(owner='octocat', name='Hello-World')[ ... _ ... .createdAt ... .description ... ] ... ] >>> str(query) query { repository(owner: "octocat", name: "Hello-World") { createdAt description } }
Offline query validation. Use the schema to catch errors quickly:
>>> schema.query[ ... _ ... .repository(owner='octocat', name='Hello-World')[ ... _ ... .createdAt ... .foo ... .description ... ] ... ] SelectionError: SelectionError on "Query" at path "repository": SelectionError: SelectionError on "Repository" at path "foo": NoSuchField: field does not exist
Deserialization into python objects. Responses are loaded into the schema's types. Use
.
to access fields:>>> r = quiz.execute(query, ...) >>> r.repository.description "My first repository on GitHub!" >>> isinstance(r.repository, schema.Repository) True
If you prefer the raw JSON response, you can always do:
>>> quiz.execute(str(query), ...) {"repository": ...}
quiz
and its dependencies are pure python. Installation is easy as:
pip install quiz
After you've cloned the repo locally, set up the development environment with:
make init
For quick test runs, run:
pytest
To run all tests and checks on various python versions, run:
make test
Generate the docs with:
make docs
Pull requests welcome!