Python FastAPI and GraphQL (Ariadne) Tutorial

Python FastAPI and GraphQL (Ariadne) Tutorial

As web development technologies evolve, developers are increasingly looking for ways to create efficient, scalable, and easy-to-maintain APIs.

For precisely these reasons, two libraries that have been gaining traction in the Python community are FastAPI and Ariadne. While Ariadne offers a straightforward method for implementing a GraphQL server, FastAPI is renowned for its speed, automatic interactive API documentation, and user-friendliness. You will learn how to build up a FastAPI application with Ariadne and construct a GraphQL API by following this tutorial.

Introduction to FastAPI and GraphQL

FastAPI is a cutting-edge, efficient (high-performance) web framework that uses typical Python-type hints to build APIs with Python 3.6+. It enables the creation of JSON Schema and OpenAPI documentation automatically, greatly accelerating the development process.

GraphQL is a server-side runtime and query language for your API that lets you run queries using a type system you specify for your data. By enabling clients to request the data they require, it lessens the instances of over- and under-fetching.

Here is an intro to Graphql to understand better from Fireship:

Ariadne is a Python library for implementing GraphQL servers. It provides a simple and efficient way to create GraphQL schemas and resolve queries and mutations.

Also, there are other alternatives for Ariadne like Graphene, strawberry, GQL, and Tartiflette. In terms of community and documentation, Graphene is the best of the lot.

So, let’s get started with the Python FastAPI and GraphQL (Ariadne) Tutorial

Setting Up the Environment

Before we start coding, we need to set up our development environment. We’ll be using Python, so make sure you have Python 3.6+ installed.

We’ll also use virtual environments so we can keep our dependencies separate.

1. Install Python: Ensure Python 3.6+ is installed on your machine.

2. Create a Virtual Environment:

python -m venv .venv

source .venv/bin/activate  # On Windows use `.venv\Scripts\activate`

 

3. Install Dependencies:

   pip install fastapi uvicorn ariadne

Creating the FastAPI Project

Let’s create a simple FastAPI project structure:

mkdir fastapi_graphql

cd fastapi_graphql

touch main.py #this is for linux, for windows manually create main.py

Open `main.py` in your favorite editor and add the following code to create a basic FastAPI application:

from fastapi import FastAPI

app = FastAPI()

@app.get("/")
async def read_root():
  return {"Hello": "World"}

You can run this application using Uvicorn:

uvicorn main:app --reload

Navigate to `http://127.0.0.1:8000` in your browser, and you should see a JSON response with `{“Hello”: “World”}`.

You may like: Understanding LLMs in AI

Defining the GraphQL Schema with Ariadne

GraphQL schemas are defined using the GraphQL Schema Definition Language (SDL). Let’s create a schema that includes a query for retrieving a list of books.

Create a file called `schema.graphql` and add the following content:

type Query {
  books: [Book]
}

type Book {
  title: String
  author: String
}

This schema defines a `Query` type with a single field, `books`, which returns a list of `Book` objects. Each `Book` has a `title` and an `author`.

The name of the query is books and it takes no arguments, and the return type is a list of book objects like [Book]. But, let’s say if it took any arguments, it would be like this: books(input: String!): [Book]. The ‘! is for telling Ariadne Graphql that this argument must be passed.

Implementing Resolvers

Just like in REST architecture, where we have utilities like GET, PUT, POST, PATCH, and DELETE for interacting with backend services, GraphQL offers similar functionalities via Queries, Mutations, and Subscriptions. Queries are similar to GET requests, enabling us to retrieve data. Mutations enable us to make changes to the database, similar to POST, PUT, or DELETE requests in REST. Subscriptions are used for fetching real-time data, functioning like WebSockets.

If you want to understand comparisons of Rest and Graphql, this is an excellent resource: Graphql vs Rest

Resolvers are functions that handle the fetching of data for our GraphQL queries. Let’s implement the resolvers in `main.py`.

First, let’s define some sample data:

books = [
  {"title": "The Great Gatsby", "author": "F. Scott Fitzgerald"},
  {"title": "1984", "author": "George Orwell"},
  {"title": "To Kill a Mockingbird", "author": "Harper Lee"}
  ]

Now, let’s write the resolver for the `books` query:

from ariadne import QueryType
query = QueryType()
@query.field("books")
def resolve_books(_, info):
  return books

Integrating Ariadne with FastAPI

To integrate Ariadne with FastAPI, we’ll create an `Ariadne` schema and mount it on a FastAPI route.

Update `main.py` to include the following code:

from fastapi import FastAPI, Request, HTTPException
from ariadne import QueryType, make_executable_schema, load_schema_from_path, graphql_sync
from ariadne.asgi import GraphQL
from starlette.responses import JSONResponse

# Sample data
books = [
    {"title": "The Great Gatsby", "author": "F. Scott Fitzgerald"},
    {"title": "1984", "author": "George Orwell"},
    {"title": "To Kill a Mockingbird", "author": "Harper Lee"}
]

# Define the resolver for the 'books' query
query = QueryType()

@query.field("books")
def resolve_books(_, info):
    return books

# Load schema from file and create executable schema
type_defs = load_schema_from_path("schema.graphql")
schema = make_executable_schema(type_defs, query)

# Initialize FastAPI
app = FastAPI()

@app.get("/")
async def read_root():
    return {"Hello": "World"}

# Add GraphQL endpoint with GraphiQL interface
app.add_route("/graphql", GraphQL(schema, debug=True))

@app.post("/graphql")
async def graphql_server(request: Request):
    data = await request.json()
    success, result = graphql_sync(schema, data)
    status_code = 200 if success else 400
    return JSONResponse(result, status_code=status_code)

This code sets up an `/graphql` endpoint for our FastAPI application, which handles GraphQL requests.

Related: 5 Must read Books for programmers

Testing the GraphQL API

To test our GraphQL API, we can use tools like GraphiQLor Postman. Here, we’ll use the built-in interactive API documentation provided by FastAPI.

for this tutorial, we are going to use GraphiQL Interactive UI, which is already integrated into the main.py file.

Again, run the FastAPI server using this command:

uvicorn main:app --reload

Navigate to `http://127.0.0.1:8000/graphql` to see the automatically generated API UI. You should see a page like this:

To test the `books` query, you can send the following GraphQL query:

{
books {
  title
  author
  }
  }

You should receive a response with the list of books we defined earlier:

{
"data": {
"books": [
{"title": "The Great Gatsby", "author": "F. Scott Fitzgerald"},
{"title": "1984", "author": "George Orwell"},
{"title": "To Kill a Mockingbird", "author": "Harper Lee"}
]
}
}

Here is a video for a better explanation:

Conclusion

We’ve gone over how to build up a FastAPI application with a GraphQL API using Ariadne in this Python FastAPI with GraphQL (Ariadne) Tutorial. Everything from environment setup to project creation, GraphQL schema definition, resolver implementation, Ariadne integration with FastAPI, and API testing has been covered.

You can benefit from both the flexibility and efficiency of GraphQL and the speed and simplicity of FastAPI by integrating them with Ariadne. This configuration is perfect for creating easy-to-develop and maintain modern APIs.

Software Engineer | Website

Talha is a seasoned Software Engineer with a passion for exploring the ever-evolving world of technology. With a strong foundation in Python and expertise in web development, web scraping, and machine learning, he loves to unravel the intricacies of the digital landscape. Talha loves to write content on this platform for sharing insights, tutorials, and updates on coding, development, and the latest tech trends

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *