Building a GraphQL Server With Flask, Graphene and SQLAlchemy

Alejandra Jamilis
Flux IT Thoughts
Published in
6 min readApr 17, 2020

--

A while ago, I took part in a project to research the use of GraphQL in order to expose data to client applications. Thus, I thought about sharing with you an alternative to start a GraphQL application using Python with Flask, Graphene and SQLAlchemy, a database on MySQL and Docker.

Before we start, let me give you some context…

What Is GraphQL?

GraphQL is a query language for APIs developed by Facebook in 2012 and released to the public in 2015 as an alternative to REST.

GraphQL allows us to gather data in a predictable way: it provides a full description of the data in the API and gives clients the possibility of asking for the exact information they need, thus optimizing data queries. This means that it serves to specify the data we need in a query, including only that in the result.

For more details on GraphQL, check their official website.

And What’s Flask?

Flask is a microframework designed to build applications in an easy and agile way, with the possibility of scaling to more complex applications. It’s based on Werkzeug and Jinja, and it’s one of the most popular web frameworks for Python.

What About Graphene?

Graphene-Python is library that allows us to build GraphQL APIs in Python easily, while also being simple and extendable.

All right, then, let’s get to it!

Prerequisites

For this project I used:

  • Python 3.7
  • Pip 3
  • Virtualenv
  • Docker

The Application’s Setup

First, we create a virtual environment.

$ virtualenv venv
$ source venv/bin/activate

Then, we start installing the required packages as they become necessary:

$ pip3 install flask flask_script
$ mkdir -p app/__init__.py

Within app/__init__.py, we create the function create_app(), where we’ll start the application according to the Application Factory pattern:

Next, we include the following code in /manage.py:

Once we’ve run the setup, we can start the application from the chosen IDE or from the command line running:

$ python3 ./manage.py runserver .

And if everything went to plan, this is a great moment to freeze the libraries you used in a text file:

$ pip3 freeze >> requirements.txt

It’s advisable to do this after installing a new library, since it allows you to reinstall all the required dependencies in other environments.

Docker Setup

We do it by creating the Dockerfile file in the project’s root. This one contains the Docker instructions to build the project’s image.

Since later on we’ll use a MySQL database, now we’ll define the Docker-Compose YAML in the root of the project. For the time being, it will only contain the information of the application’s image:

With this setup, and executing the following command:

$ docker-compose up

the application will be displayed and available through http://localhost:5000.

Connecting MySQL to Flask

To connect MySQL we have to perform 3 actions: install the dependencies, configure the connection data and run a MySQL docker image.

Through Pip we install the dependencies (and freeze them in requirements.txt):

$ pip3 install flask-alchemy pymysql$ pip3 freeze >> requirements.txt

In docker-compose.yml we add the MySQL image to which the application accesses:

Then, we set the Flask application to connect to MySQL, integrating the configuration in config.py and modifying the app/__init__.py file.

We’ll include two different configurations: one for the development environment and another one for the testing environment.

Finally, we modify the application to perform the database setup and teardown:

Hence, when executing docker-compose up — build, the application will run connected to the MySQL service.

GraphQL Setup

How do we integrate and use GraphQL in all this process? And how do we test it? Quite simply, there’s an answer to each question:

  • We integrate GraphQL through Flask-GraphQL.
  • We build the API using Graphene-Python.
  • We test the API using GraphiQL, an interactive IDE for browsers which is included in Flask-GraphQL.

We install the libraries we’ll use:

$ pip3 install graphene Flask-GraphQL graphene_sqlalchemy

We add the /graphql route to access the GraphQL API, including it in the app/__init__.py file.

The next step is to create app/schema.py, where our GraphQL schema will be. This schema is very important because it is an essential part of any GraphQL server implementation and it describes the available features to the clients. To do a quick test, we’ll include a quite simple schema and then we’ll test the application:

With these changes, when we run the application and access http://localhost:5000/graphql, we should be able to see the GraphQL IDE, which is similar to this one.

As we said before, always remember to run a pip3 freeze to pin down the dependencies!

Building our API

We’ll implement a simple model, which will have the User entity that contains a Profile with a list of Skills.

model

Through SQLAlchemy we’ll add the model to the app/model.py file.

Once the model is done, we build the schema. Why do we need a schema? Because that’s the way to describe the types of objects that we’ll show in the graph that GraphQL introduces. We’ll also define queries and mutations. Queries are the way in which the client searches for information and mutations are the way in which the client creates or changes data. Those concepts are detailed here.

Now we create the app/graphql/object.py file where we’ll include the types of objects:

In object.py there are some important things:

  • Classes extend from SQLAlchemyObjectType, a class provided by graphene-sqlalchemy for the integration between SQLAlchemy and GraphQL.
  • Within Profile, skills is defined as a Graphene list which also receives the score and name parameters; next, we have resolve_skills, which also receives these parameters as optional and performs a query filtered by the parameters. This is useful to filter by multiple nodes in the queries, as we’ll see later.
  • In the end, the SkillInput class is defined, which represents an input object that will be used later in mutations.

Next, we create the app/graphql/query.py, where we’ll add the available queries to search for information:

In query.py we include the possibility of searching for users filtering by username and the profile and skill searches.

We also add the app/graphql/mutation.py file to create users, profiles and skills:

Finally, in app/schema.py we configure both the queries and the mutations that we’ve created:

All set to test the application! Executing

$ docker-compose up — build

…we can start testing.

Time To Test!

We start by creating a user on http://localhost:5000/graphql:

Then, we add a profile with skills for the user:

We run a query to see the username mrblue’s user data, also showing the role of its profile and only the name of its skills:

After having created several other users, we’ll search for the users with username, profile and only the skills for those that have a score equal to 5:

Thus, we can test different filters and projections combinations. GraphQL also provides data sorting capacity, the use of fragments and other features that exceed the scope of this article (though we might address that later, would you like that?)

To wrap up, I share with you the project’s repository and some useful reference links:

Know more about Flux IT: Website · LinkedIn · Breezy · Instagram ·Twitter · Dribbble

--

--