Build GraphQL APIs in Flask using Graphene

Sharmila S
featurepreneur
Published in
5 min readJun 1, 2021

In this article, you will be learning to implement GraphQL in Flask using the Graphene module.

GraphQL helps us to design APIs efficiently, by allowing us to request exactly what we want and receive a response with only the data that you requested.

Dependencies to install

  • Flask
  • graphene

Install the dependencies using pip

$ pip install Flask
$ pip install graphene

Let’s create a simple flask app called app.py with a root route

from flask import Flask
app = Flask(__name__)
@app.route('/')
def root_route():
return 'Hello World'
if __name__ == '__main__':
app.run()

And run the app, using

$ python app.py

Go to http://localhost:5000/ to view the response.

http://localhost:5000

Now, let’s create a simple graphql query to get data and return it as the response

GraphQL Code

Let’s import the graphene module to our app

import graphene

Steps

  • Create a new Query
  • Create a new Schema with the created query
  • Execute custom queries using the created Schema

Let’s see how we can create a simple query to return a string.

Every data dealing with graphql should be of of graphene’s type, not a python builtin type.
i.e. A string variable should be of graphene.String type instead of python’s str type.

Query to return a string

1. Create a query

class Query(graphene.ObjectType):    hello = graphene.String( 
name = graphene.Argument(graphene.String, default_value = "World")
)

# resolve function
def resolve_hello(self, info, name):
return 'Hello ' + name

Code Explanation

Our Query class extends graphene’s ObjectType.

We are defining a Field called hello within the query.

For the fields, we should mention the return type. Here, the return type is String. hello = graphene.String()

To mention that our hello field takes arguments, we can specify the name and type of the arguments, within graphene.String() (its datatype). Our field ‘hello’ takes an argument called ‘name’ which is of String data type.

  • Let’s understand the following part of the code.
name = graphene.Argument(graphene.String, default_value = "World")

Argument() says that it is an argument. The type of the argument (here, name argument is a String) is given to Argument() along with a default value. The default value is considered when no argument is passed.

Resolve function — this function defines the steps to be executed to return the desired data when a specific field is requested. This function must be named as ‘resolve_<Field Name>’.
Here, our field is hello, so the resolve function is resolve_hello()

This function receives the argument passed along with the arguments, self and info . Here, we are returning ‘Hello ’ + the name passed.

2. Create a schema using the query we defined.

Let’s create a schema using the query Query we just defined.

schema = graphene.Schema(query = Query)

3. Execute custom queries using Schema

Now we have our Schema ready, we can pass our queries to Schema and get the data. We create our query as a docstring(enclosed by triple quotes).

To request hello, we enclose it in curly braces and pass the argument name along with it hello (name: "Percy")

# get 'hello', pass "Percy" as the argument
my_query = """
{
hello ( name : "Percy" )
}
"""

Now, let’s execute the above query statement using the schema and return it when the ‘/’ route is requested.

# execute 
result = schema.execute(my_query)
# return the result as response, when api is called
@app.route('/')
def root_route():
return {
"data": result.data
}

Now, run the app again, and view the result in the browser.

Query to Return an object

We learned how to return a String which is a built-in type, now let’s try to return an Object which is defined by us.

  • Define a class with the attributes for the object
class Book(graphene.ObjectType):
id = graphene.NonNull(graphene.Int)
title = graphene.String
author = graphene.String

This Book class is the type of data that we are going to return. It has three attributes, id, title, and author which are of type Int, String, String respectively. Further, we are mentioning that the ‘id’ attribute can’t be Null(Empty) by enclosing the Int type within NonNull().

Let’s modify our query to return a Book object.

class Query (graphene.ObjectType):    book = graphene.Field(Book)

def resolve_book(self, info):
return Book( id = 1, title = "Six of Crows", author = "Leigh Bardugo")
my_query = """
{
book {
id, title
}
}
"""

In the above code snippet, we define a field for our query called ‘book’ which is going to return a Book object. We should enclose the Book type within graphene.Field()

In the resolve function, we are returning a Book object with all attributes initialized.

Note that, we only requested id and title and not author , since we know that in graphql, we can request and get, only the properties that we want.

Query to return a list of objects

We can use graphene’s List type to return a list of elements

Let’s define a list called book_array which holds a list of objects.

book_array = [
Book(id = 1, title = "Angels and Demons", author = "Dan Brown"),
Book(id = 2, title = "And Then There Were None", author = "Agatha Christie"),
Book(id = 3, title = "The Lightning Thief", author = "Rick Riordon")
]

Let’s modify the query to return the list book_array
graphene.List(Book) — A list of objects of Book type.

class BooksQuery (graphene.ObjectType):    # This is called from query as bookList (Camelcase)
book_list = graphene.List(Book)
def resolve_book_list(self, info):
return book_array
books_query = """
{
bookList {
title, author
}
}
"""

Let’s run our app, and call the API (http://localhost:5000/)

Hope this article helped you to get started with Graphql for Flask!

Github repo — https://github.com/SharmilaS22/medium-graphql-flask/

Happy Learning!

--

--

Sharmila S
featurepreneur

Software Engineer | Writes about Full Stack Web Development | 1 X AWS | CKA http://sharmilas.bio.link/