Python (Flask) with GraphQL Server implementing SQLAlchemy, graphene, and SQLite

Creating a simple server end-point integrating GraphQL and Python (Flask) with a simple SQLite3 database

Pablo A. Del Valle H.
Jun 2 · 7 min read

I’ve created another article on GraphQL with TypeScript, if you want to check it out, click here.


One of the favorite features of GraphQL, a characteristic missing in RESTful architectures, is strong-typed validation. By default, GraphQL validates every request against the schema, which works as a gatekeeper, meaning that if the request does not pass the validation, no actions are going to be taken by the server, saving CPU time (especially important in serverless infrastructures), also letting the client knows quicker there’s an issue with their request.

Image for post
Image for post

And this is crucial. As you may know, GraphQL can trigger several queries towards multiple data points (other end-points, databases, flat files, or even another GraphQL service) in a single request so, having this filter at the door will prevent unnecessary overhead.

At the same time, GraphQL’s strong typed traits will make your IDE’s IntelliSense smarter, which in turn will help you develop faster and potentially with fewer bugs.

Let’s go over GraphQL’s types and schemas by creating a small project in Python and Flask web framework (implementing graphene and SQLAlchemy). For a simple database, we are going to use Sqlite3.


The Power of Object-Relational Mapping 🗺

The ability to describe queried data gives a new dimension to API implementations since it can help to provide a scaffold for classes, interfaces, and otherwise streamline an Object-Relational Mapping (ORM) strategy (think Prisma for JavaScript, Typescript or SQLAlchemy for Python).

While ORM is not required in order to use GraphQL, it is definitely worth looking into it. There are many opinions on this subject, ranging from ORMs are not necessary or that they do not add value to the exchange of messages between client and server, to others who think that they are precious to maintain integrity between the data source and the implementation.

Tools like the ones mentioned above (Prisma, SQLAlchemy) allows to abstract the data sources to a point where they can provide a common schema that can be both used on the back-end as in the front-end.


Creating a demo project with GraphQL on Python 🐍

To start, we’ll need the following packages installed (requirements.txt):

Python
Python
We are going to use Python 3.
Flask==1.1.2
Flask-GraphQL==2.0.1
graphene==2.1.8
graphene-sqlalchemy==2.3.0.dev1
SQLAlchemy==1.3.17

The structure of our project is quite simple: at the root, we will have main.py. Also, in the root, we will have a package called Books (books/). Add a __init__.py file inside the Books package.


Database Models 🗄

The first items that we are going to add to the Books package are the Models. In the “books/models/” directory we will create three files: books.py, characters.py, and genres.py.

Here, you’ll notice, three classes are created. Genres, Books, Characters. Essentially, these are our ORM mappings with SQLAlchemy to what eventually will become our SQLite database. However, another advantage of these classes, is that we can use them as references for the GraphQL structure.

Creating the Type definitions 📚

Graphene
Graphene
Graphene library for typing.

The previously mentioned linking definitions will be done in a one to one mapping to the ORM files created in the last step. For that, we will rely on graphene’s library. You’ll need to create a “books/types/” directory. In it, we’ll add the same files to map what we have in the model's directory: books.py, characters.py, and genres.py.

These classes extend the SQLAlchemyObjectType, which will be reflected in the GraphQL queries.

Database seed 🌱

SQLite
SQLite
SQLite 3 for a database.

In order to have some initial data in our database, we could create a migrations file, however, this being such a simple database, we are just going to create a file that inserts a few rows. This file will also be created in the Books package directory under “books/database”. We’ll call it database.py. Additionally, base.py and db_sessions.py will be created to provide a database session and other utilities used across your application.

These scripts are pretty straight forward. Main takeaways are the creation of the database file `Books/database.sqlite3` on line 4 of base.py. Then another script adds a few genre, book, and character rows to our initial database on init_db.py.

GraphQL Schema 📐

The main entry point for GraphQL to our data is the Schema. This file will have a reference to the Query object, the Mutation object and a reference of the Types used.

The files to be created in the “books/schema” directory are schema.py, query.py, and mutation.py.

Two properties (Fields) are found in the query.py file mapped to two resolvers. For example, books_by_genre defines a graphene list, the first parameter (Books) represents the type of elements this resolver will return, the second will be the argument that will be received by the resolver (name). The actual resolver method is matched by its name with the prefix “resolve_”. So, the resolver for “books_by_genre” will be resolve_books_by_genre. This method, by the way, illustrates a join of two tables from SQLite (Books and Genres).

Notice that we are using a utility called “input_to_dictionary”. This is a method you’ll create in the directory “books/utils” in the file input_to_dictionary.py as follows:

Finally, we’ll wrap our app using Flask.

Using Flask to expose our GraphQL end-point 🌏

Flask
Flask
Flask for web framework.

In order to be able to access our GraphQL end-point, we will use Flask web framework, which is a very lightweight library that will allow the service to be exposed publicly. For the purpose of this demo, we won’t be covering security and everything that comes with it. If you want to expand further into how Flask works and how to implement a secure end-point you can check out the documentation here.

The main entry for your package is going to be app.py (also inside the Books package):

In here, you’ll be adding the route of “/graphql” to map the GraphiQL app, by default running on your localhost, port 5000.

Finally, the entry point for our full app will be main.py, at the root directory:

Two actions are going to be run here, the first one will reset the SQLite database, and the second one will actually run the Books package. Of course, this is done this way due to this being a demo; you don’t want to have this pattern, as it will reset your database every time you run your application.

As you run python main.py, you’ll bring up the Flask web framework. Your console will return an output similar to this:

After running the app, you’ll notice the `database.sqlite3` file created inside the database directory in the Books package.

And then, if you navigate there using a browser:

This interface is called GraphiQL (pronounced “Graphical”), where you can run your GraphQL queries. Let’s try to find all books that match the “Fantasy” genre.

You can even merge the result types, for instance, ask for the characters included in these books, by adding the characters edge:


Adding data

You can use your mutations also through this same interface. In this case, we only have one mutation (createBook), and you’ll access it like this:


After this, the next subjects you are going to want to look into are Data Loaders which will help you simplify your requests and use batching to with Promises and finally security and access tokens with GraphQL.



Thanks for reading!

Find me on LinkedIn, Medium, GitHub.

The Startup

Medium's largest active publication, followed by +685K people. Follow to join our community.

Sign up for Top Stories

By The Startup

A newsletter that delivers The Startup's most popular stories to your inbox once a month. Take a look

By signing up, you will create a Medium account if you don’t already have one. Review our Privacy Policy for more information about our privacy practices.

Check your inbox
Medium sent you an email at to complete your subscription.

Pablo A. Del Valle H.

Written by

Engineering Manager at Univisión Communications Inc.

The Startup

Medium's largest active publication, followed by +685K people. Follow to join our community.

Pablo A. Del Valle H.

Written by

Engineering Manager at Univisión Communications Inc.

The Startup

Medium's largest active publication, followed by +685K people. Follow to join our community.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch

Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore

Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store