How to Use GraphQL with Python

Let's take a look at how you can query GraphQL endpoints with Python and build a demo To Do List app in Flask.

ezzeddin abdullah
EzzEddin Abdullah
how to use graphql with python

In today's world, more data is consumed and coming up in a massive amount. Clients, on one side, need to load data as fast as they can. Developers, on the other side, need to make their apps performant. If your app is fast, your clients will have a better user experience and will be happy, and eventually, your business will make more money.

Modern apps should be faster than the old ones. Your app should get data fast from the server to the client. GraphQL is a sure solution for that.

Why use GraphQLAnchor

Back in 2012, Facebook engineers found that iOS and Android apps frequently crashed. They decided to look at how to improve how Facebook data was being sent to the client apps. Then they built GraphQL for their internal use. In September 2015, Facebook released GraphQL to the public.

Today when you think about APIs, the first thing that might come to your mind is the REST API. In 2000, REST was defined in a Ph.D. dissertation as a resource-oriented architecture with operations like GET, PUT, POST, and DELETE.

REST API architecture is much simpler than RPC and SOAP regarding the data model. REST APIs have been used by countless apps, but it has some shortcomings.

First off, GraphQL is not a REST killer. Like any other successful technology, GraphQL came to solve some problems faced by REST.

Three major issues REST has:

  1. Overfetching
  2. Underfetching
  3. Inflexibility

In the REST world, you get too much data in the response you don't need. This problem is called overfetching. In GraphQL, you're fetching only the fields you want. This makes GraphQL more declarative and faster.

In REST, if you developed an endpoint that returns specific data and there is a feature request to fetch more data from the response, you would need additional requests to get these new data. This is how you underfetched.

In GraphQL, you must add new key(s) to the nested query. This will request the data all in just one fetch.

Another pain of REST APIs is the inflexibility, especially if your app is getting bigger. In REST, when a client needs a change in your app, you will probably create a new endpoint. These endpoints keep adding up whenever there is a need. Thus, more collaboration between your backend and frontend teams. This will cost time and speed, as new endpoints mean more HTTP requests from the clients.

In GraphQL, a single endpoint is typically involved. This makes easy organization of data and more productivity among your teams.

Tutorial - Create a Simple GraphQL Wrapper using FlaskAnchor

In this post, you'll build a simple GraphQL wrapper at Hygraph. You'll be able to use Hygraph GraphQL Query API. You'll learn how to authenticate with the Hygraph API using Python, explore the Hygraph GraphQL playground, learn and how to fetch data from GraphQL API and wrap the result in a Flask app.

Create a Hygraph projectAnchor

In this tutorial, you will learn how to use Hygraph to create a pre-configured project like a Todo app. Sign up, and then you'll be redirected to the dashboard of projects. You can create a project from scratch and use a template. If you used the todo app, a new window will pop up like this:

create a hygraph project

Select the Region that you want to host your content on. If you hit "Create project", you'll have a project.

my todos app

Set up the project locallyAnchor

Open the terminal and set up a quick virtual environment like the following:

python3 -m venv venv;
. venv/bin/activate;
pip install --upgrade pip

Now, you're ready to install dependencies for your project with pip:

pip install flask requests

You've installed Flask, a microframework that you'll use for the simple web app to wrap data sent from GraphQL API.

You'll also need requests for authentication and to be able to fetch data from the Hygraph GraphQL API.

Set up the Flask appAnchor

To configure the flask app location, set up an environment variable with the name of your application (say, api.py file):

export FLASK_APP=api.py

In this api.py file, create the simple Flask setup like the following:

from flask import Flask
app = Flask(__name__)
@app.route("/get_todo")
def get_todo():
return {"todo text": "data from the API"}

Type flask run in the terminal and open the browser on localhost:5000/get_todo endpoint. A simple JSON with the "todo text" key is returned.

Hygraph authenticationAnchor

To authenticate your todo app on Hygraph, you need to know the endpoint that you want to access, the GraphQL query you want to send to the request, and the token generated by Hygraph.

To get the endpoint of your Hygraph application, navigate to the Project settings tab on the left and select Endpoints inside API Access page. Copy the endpoint under Content API and paste it somewhere.

If you scroll down on the same API Access page, you'll see a token generated by Hygraph called HYGRAPH_TOKEN. Under Value column, click on the token to copy it. Paste it somewhere, you'll need it.

What's left is the GraphQL query that you want to pass to the request. Navigate to the API playground on which you can experiment with GraphQL queries. Write this query on the playground:

query MyQuery {
todo(where: {id: "ckz8d4mlc0qjq0b13gcgbieni"}) {
description
completed
}
}

A quick write-up for the previous query is to select the todo dropdown and the id under the where clause and then the fields you want to query. In this case, it's description and completed.

graphql playground

If you want to get the id related to your project, navigate to the Content tab. You'll find each column representing a specific field in the schema and each row representing a specific entry in your application.

Now, you're ready to authenticate your app. Open the api.py and your project is now like the following:

import requests
import json
import os
from flask import Flask
query_todo = """query MyQuery {
todo(where: {id: "ckz8d4mlc0qjq0b13gcgbieni"}) {
description
completed
}
}
"""
url = "https://api-<region>.hygraph.com/v2/<some hash>/master" # paste your Content API endpoint
token = os.getenv("HYGRAPH_TOKEN")
headers = {"Authorization": f"Bearer {token}"}
app = Flask(__name__)
@app.route("/get_todo")
def get_todo():
payload = {"query": query_todo}
r = requests.post(url, json=payload, headers=headers)
json_data = r.json()
return {"todo text": json_data["data"]["todo"]["description"]}

Notes:

  • The url is the token
  • The payload is a dictionary that contains the query pointing to the query_todo which is the string of the query you wrote at the Hygraph API playground
  • The headers contain the Authorization key which contains the string "Bearer " + ""
  • The r object contains the response of the post request that you sent to the Hygraph API
  • The json_data is a JSON conversion from the r Python object

Finally, the response coming from the query (see the picture above about the playground):

{
"data": {
"todo": {
"description": "Hello",
"completed": null
}
}
}

So if you want to get the description of that JSON, you need to traverse through that JSON. The get_todo endpoint returns a "todo text" key with the value of the description as indicated.

Query the todo itemAnchor

Now, you're ready to move on and run the Flask app. Before that, you need to set up the environment variable of the Hygraph token with the following command:

export HYGRAPH_TOKEN=<your Hygraph token>

Run the Flask app with flask run and open the local host on get_todo endpoint. You'll see a response with the following:

{
"todo text": "Hello"
}

MutationAnchor

If you want to modify data or create new one, use the mutation root type in GraphQL. Explore that in the Hygraph API playground and write the following:

mutation editTodo {
updateTodo(
data: {
description: "write a blog post",
completed: true
},
where: {
id: "ckz8d4mlc0qjq0b13gcgbieni"
}) {
id
description
completed
}
}

This mutation updates the previous query you fetched with a new description and a completed boolean value instead of null. Then, it will return the id, description, and completed fields with the updated values.

graphql playground

When you hit Run, you'll find two values to choose from. Select the editTodo mutation name. Now, if you run the Flask app again, you'll find a response with the new description that you fetched:

{
"todo text": "write a blog post"
}

ConclusionAnchor

This tutorial shows you how to use GraphQL with Python to fetch data. You've explored a GraphQL API and how to use its playground to write queries and mutations. You now have the ability to authenticate your app using Python with requests. And you've linked a Flask app with GraphQL API and fetched information from it.