Client-side GraphQL query generator based on Pydantic
Project description
pygraphic
Client-side GraphQL query generator based on pydantic.
Why?
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!
Workflow
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!
Release Checklist
Pygraphic is in development stage. Major features might either be missing or work incorrectly. The API may change at any time.
- Basic queries
- Queries with parameters
- Custom scalars (not needed, comes with pydantic)
- Mutations
- Subscriptions
- Tests
- Stable codebase
Example
Server schema
type User {
id: UUID!
name: String!
friends: [User!]!
}
get_all_users.py
from __future__ import annotations
from uuid import UUID
from pygraphic import GQLQuery, GQLType
class User(GQLType):
id: UUID
name: str
friends: list[UserFriend]
class UserFriend(GQLType):
id: UUID
name: str
class GetAllUsers(GQLQuery):
users: list[User]
main.py
import requests
from .get_all_users import GetAllUsers
# Generate query string
gql = GetAllUsers.get_query_string()
# Make the request
url = "http://127.0.0.1/graphql"
response = requests.post(url, json={"query": gql})
# Extract data from the response
json = response.json()
data = json.get("data")
if data is None:
raise Exception("Query failed", json.get("error"))
# Parse the data
result = GetAllUsers.parse_obj(data)
# Print validated data
for user in result.users:
print(user.name)
print(user.friends)
Generated query string
query GetAllUsers {
users {
id
name
friends {
id
name
}
}
}
Contribution
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.
License
Copyright © 2022, Dmitry Semenov. Released under the MIT license.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.