Client-side GraphQL query generator based on pydantic.
Working with GraphQL in Python seems simple... If you're fine with dictionaries, lack of autocompletion and unexpected errors.
Some tools allow you to generate Python code from GraphQL schemas. One of them, turms, even generates pydantic models from GQL documents. This approach can be problematic: queries are written in GraphQL, not Python, so the codebase you're actually working with is out of your control; and the main advantage of pydantic — data validation — is missing!
Pygraphic is the opposite of turms:
-
For each individual query, you define pydantic models that you want to request, optionally with validators and other configuration;
-
Pygraphic converts those definitions to raw GraphQL documents (basically strings);
-
Using a GraphQL or an HTTP client, you make requests with those documents and get back JSON responses;
-
Pydantic converts those responses to instances of the defined models and validates them;
-
You use the validated data, while enjoying autocompletion and type safety!
Pygraphic is in development stage. Some major features are missing or might work incorrectly. The API may change at any time.
See ROADMAP.md for the list of implemented/missing features.
Examples are kept in the
/examples folder.
Queries that they're expected to produce are stored in the
/golden_files
folder.
Most examples are based on GitHub's GraphQL API.
If you want to run them, you need to
generate a personal access token and assign it to
the environment variable called GITHUB_TOKEN
(with VSCode, the best way to do this is
to create a .env
file in the project's root directory).
Here's the gist:
import os
import requests
from pygraphic import GQLQuery, GQLType
# Define data models
class License(GQLType):
id: str
name: str
description: str
# Define query model
class GetAllLicenses(GQLQuery):
licenses: list[License]
# Generate the GraphQL query string
query_str = GetAllLicenses.get_query_string()
# Make the request
TOKEN = os.environ["GITHUB_TOKEN"]
response = requests.post(
url="https://api.github.com/graphql",
json={
"query": query_str,
},
headers={
"Authorization": f"bearer {TOKEN}",
},
)
# Parse the response
response_data = response.json().get('data')
if response_data is None:
print('Query failed')
result = GetAllLicenses.parse_obj(response_data)
# Print the results
for license in result.licenses:
print(license.name)
query GetAllLicenses {
licenses {
id
name
description
}
}
This project is developed on GitHub.
If you have any general questions or need help — you're welcome in the Discussions section.
If you encounter any bugs or missing features — file new Issues, but make sure to check the existing ones first.
If you want to solve an issue, go ahead and create a Pull Request! It will be reviewed and hopefully merged. Help is always appreciated.
Copyright © 2022, Dmitry Semenov. Released under the MIT license.