🎱 Quiz#

https://img.shields.io/pypi/v/quiz.svg?style=flat-square https://img.shields.io/pypi/l/quiz.svg?style=flat-square https://img.shields.io/pypi/pyversions/quiz.svg?style=flat-square https://img.shields.io/readthedocs/quiz.svg?style=flat-square https://img.shields.io/codecov/c/github/ariebovenberg/quiz.svg?style=flat-square&logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAaCAMAAACaYWzBAAABX1BMVEUAAAD///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////8P/Ub/AAAAdHRSTlMAAQIDBAUGBw0PERIVFhcZGhsgISQmKSorLS8zODk6PUFDR0lLTE1YXF5fYGRlaHB1dnd4eXt/g4eKjJKVlpeYmZqcnqOkpaanqqusrq+xsrW3ubu8vb7Hzc7Q1dfZ3N3e3+Dh4ujp6uzt7/Hz9fb3+Pv9/mHMvTIAAAFPSURBVHgBbdDXcxJRGIbx55zvnI1ijJI1YuxiEkWNsRjsKPYiFuxFsRdREH3//5Hd2YvMLL/bZ76L9yMTYe74o95g+L57qgaRQiC9qbF+X2N35zBHxmj80bC9mFYqs/sv/NLfZXxWAiekq5soTLekJgaRw9IyxOCd8yHCIekoEbaMdITEKFhCQ/9qwB1dIWGNhIu6D9s0qDJlnoIPU8z0tZ1VXSITDMACmfNq8liL0/X6jnXgIcCGXUsLmxf0jA96q7Fv7RQz5m/kI9/pI1+lTw/vvZC0F1YkPb/V6Uk/0Ot6ANJrn2c4KbVmAbfvlTgNmDmosidf6s2AVYpnmoenOlssjUBw5Iyt+lnByLkAhchB3SZQEjmmM8RJYUXnJoXAkp5glHg2/laNZNLJZXUh8a588l3XHWWB3SO9aVTXW7nMv5TUwblS4cCDLzsx4D/omEB2BXPuawAAAABJRU5ErkJggg== https://img.shields.io/badge/code%20style-black-000000.svg?style=flat-square

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.

Quickstart#

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": ...}

Features#

  1. 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, ...)
    
  2. 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
     ...
    
  3. 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
      }
    }
    
  4. 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
    
  5. 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": ...}
    

Installation#

quiz and its dependencies are pure python. Installation is easy as:

pip install quiz

Contributing#

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!

Contents#

Release history#

development#

0.3.2 (2023-03-02)#

  • Relax version constraint on importlib-metadata backport

0.3.1 (2022-11-17)#

  • Relax importlib backport dependency

0.3.0 (2022-11-16)#

  • Official Python 3.10 and 3.11 support, drop 3.6

  • Update docs theme

0.2.3 (2021-05-14)#

  • Move to use poetry, github actions

0.2.2 (2020-12-05)#

  • Official Python 3.9 support

0.2.1 (2020-09-11)#

  • Drop Python 3.5 support

0.2.0 (2019-10-28)#

  • Drop Python 2 support

  • Add Python 3.8 support

0.1.6 (2019-04-07)#

  • Drop python 3.4 suport

0.1.5 (2019-03-16)#

  • Include request/response metadata in responses (#95)

0.1.4 (2019-03-05)#

  • Fixed issue with single-type unions (#100)

0.1.3 (2019-02-16)#

  • Add request context to HTTPError (#82)

0.1.2 (2019-01-11)#

  • Handle error responses without data correctly

0.1.1 (2018-10-30)#

  • Fixed deserialization of Enum values

0.1.0 (2018-10-30)#

  • Fixed handling of HTTP error status codes (#10)

  • Fix in validation exceptions (#11)

  • Implement custom scalars

  • Improvements to documentation

0.0.4 (2018-10-17)#

  • Remove some unneeded fields from introspection query

  • Improvements to documentation

  • Small fixes to API, tests

0.0.3 (2018-09-23)#

  • Established initial public API

  • Improved documentation, user guide

  • Field aliases

  • Deserialization

0.0.2 (2018-08-21)#

  • Execution of basic GraphQL queries

  • Convert GraphQL schema to python types (undocumented)

  • Write GraphQL in python syntax (undocumented)

0.0.1#

  • initial version

Indices and tables#