Top 10 Solutions for Building a Flask API in Python

Jennie Lee
6 min readMar 27, 2024

--

Looking for a Postman alternative?

Try APIDog, the Most Customizable Postman Alternative, where you can connect to thousands of APIs right now!

Introduction

Welcome to this guide on building a Flask API in Python! This article is part of a series that aims to provide a step-by-step tutorial for creating a REST API using Python and the Flask framework. Each post in this series assumes prior knowledge from previous articles, so make sure you have read and understood the previous posts before continuing.

In this particular post, we will focus on creating a basic Flask app using the factory pattern. The factory pattern involves creating a Flask app object, which is the central component of a Flask application. We will explore the two common methods for creating the app object and discuss why using the factory method is recommended for its flexibility and easier management of extensions and configurations.

Let’s dive in and start building our Flask API!

Creating a Basic Flask App with the Factory Pattern

When creating a Flask app, we have two common methods for creating the app object. The first method involves creating the app object in a separate file, typically named app.py. This approach works well for small applications or when the app object does not require complex configuration.

The second method, which we will focus on in this article, is using the factory method. This method involves creating the app object within a factory function, typically located in the __init__.py file.

from flask import Flask

def create_app():
return Flask(__name__)

By using the factory method, we gain flexibility in managing our app object. We can easily incorporate extensions, configurations, and other complex setups within the factory function.

Running the Flask App

Once we have created our Flask app, the next step is to run it. Flask provides a built-in development server that we can use for this purpose. To start the development server, navigate to the project root directory in the command line and run the following command:

flask run

If you are using Poetry as your dependency manager, you can run the Flask app using the following command:

poetry run flask run

Alternatively, if you are using an IDE like PyCharm, you can configure and run the Flask app directly in the IDE. PyCharm provides a Run Configuration specifically for Flask apps, allowing you to configure various options such as the host, port, and debugging settings.

Writing Docstrings for Functions in Python

In order to create good API documentation, it is important to write clear and informative docstrings for our functions. Docstrings are used to provide a brief description of the function’s purpose, its parameters, and its return value.

Let’s take a look at how we can write a docstring for our create_app function:

def create_app() -> Flask:
"""
Factory function for creating the Flask app object.

Returns:
app (Flask): The Flask app object.
"""
return Flask(__name__)

In the above example, we add a docstring to our create_app function, providing a brief description of what the function does. We also indicate the return type of the function using type annotations.

By writing clear and informative docstrings, we make it easier for other developers (including ourselves) to understand and use our code.

Type Annotations in Python

Type annotations are a powerful feature introduced in Python 3.5 that allow us to specify the expected type of variables, function parameters, and return values. While Python is dynamically typed by default, adding type annotations can help catch bugs early and make our code more maintainable and robust.

Let’s update our create_app function to include type annotations:

def create_app() -> Flask:
"""
Factory function for creating the Flask app object.

Returns:
app (Flask): The Flask app object.
"""
return Flask(__name__)

In the updated example, we specify that the create_app function returns an object of type Flask. This provides additional clarity and helps us catch potential errors when using the function.

Type annotations can be especially useful when working on larger projects, where multiple developers are involved and codebases are constantly changing. They also make it easier to understand how to use functions and make debugging more efficient.

Test-Driven Development (TDD) with Pytest

Test-driven development (TDD) is an approach where we write tests before writing the actual implementation code. This practice helps ensure that our code is always working as expected and allows us to catch bugs early on.

Pytest is a popular testing framework that provides a simple and intuitive way to write tests in Python. Let’s explore how we can use pytest in combination with Flask to write tests for our API.

First, we need to install pytest. Open your command line and run the following command:

pip install pytest

Once pytest is installed, we can write our tests. Let’s start with a simple test for the /health endpoint of our Flask app:

import pytest
from flask import Flask

@pytest.fixture
def app():
return create_app()

def test_health(client):
response = client.get('/health')
assert response.status_code == 200
assert response.json == {'status': 'healthy'}

In the above example, we use the pytest.fixture decorator to create a fixture function that returns our Flask app object. This allows us to reuse the app object across multiple tests.

We then define our test_health function, which uses the client fixture provided by pytest-flask to perform a GET request to the /health endpoint of our app. We assert that the response status code is 200 and the response JSON is equal to {'status': 'healthy'}.

To run our tests, navigate to the project root directory in the command line and run the following command:

pytest

Pytest will automatically discover and run all the tests in your project.

Creating a Blueprint for Managing Endpoints

As our Flask API grows, we will likely have multiple endpoints that need to be managed and organized. Flask provides a blueprint feature that allows us to define groups of related routes and views. Let’s create a blueprint for managing the root path (“/”) and register a controller for a health check endpoint.

First, let’s define our blueprint and the controller function:

from flask import Blueprint, jsonify

bp = Blueprint('main', __name__)

@bp.route('/')
def index():
return "Welcome to the Flask API."

@bp.route('/health')
def health():
return jsonify({'status': 'healthy'})

In the above example, we create a blueprint named 'main' and associate it with the current module (__name__). We define two routes within the blueprint: one for the root path ("/") and one for the health check endpoint ("/health"). The index function returns a simple welcome message, while the health function returns a JSON response indicating the status of the API.

To register the blueprint with our app, we need to add an init_app function to our factory function:

def create_app() -> Flask:
"""
Factory function for creating the Flask app object.

Returns:
app (Flask): The Flask app object.
"""
app = Flask(__name__)
app.register_blueprint(bp)
return app

In the finished setup, the blueprint is registered with the app using the register_blueprint method. This allows us to manage the routes and views within the blueprint separately from other parts of our app.

Conclusion

In this article, we explored several solutions for building a Flask API in Python. We started by creating a basic Flask app using the factory pattern and discussed the advantages of this approach. We then learned how to run the Flask app using the built-in development server, Poetry, and PyCharm.

We covered the importance of writing clear docstrings for functions and the benefits of adding type annotations to our code. Additionally, we explored test-driven development with pytest and learned how to write tests for our Flask API.

Lastly, we created a blueprint for managing endpoints and demonstrated how to register a controller for a health check endpoint.

By following these solutions, you’ll be well on your way to creating a powerful and robust Flask API in Python. Happy coding!

Looking for a Postman alternative?

Try APIDog, the Most Customizable Postman Alternative, where you can connect to thousands of APIs right now!

--

--

Jennie Lee
Jennie Lee

Written by Jennie Lee

Software Testing Blogger, #API Testing

No responses yet