Flask Backend Setup

In this article I show the setup of a Flask and Python backend. I show the structure of a Flask project, how to add routes to Flask, how to group routes with Blueprints and how to handle errors.

Content

  • Create a project
  • Create a Flask application
  • Blueprints
  • Error Handler

For a full description of the topic, watch this video.

All the code of the article can be found in this repository.

Create a project

Flask is a micro framework to create multiple APIs to deserve content. It is a micro framework because by default it contains the necessary to respond to HTTP requests, but it can easily be extended to accept database connections, authentication, caching frontend content, streaming and more.

I will create the folder to start my project and initialize it with Poetry. backend will be the name of my project, the name of the root package.

poetry new backend

Then, I need to add the necessary dependencies.

poetry add flask

It will pick the latest version by default. It’s okay for the moment.

Flask project structure
Flask project structure

In the root folder, i can have:

  • a README file with the documentation,
  • a test folder with the unit test,
  • a setup.py with the configuration to package and deploy the application,
  • and the root package, backend.

And inside the root package backend:

  • the __init__.py. Here, i will create and configure the Flask application.
  • the config.py,
  • and the inner packages,
  • and i can have a __main__.py file to run the application.

The alternative to the __main__.py file is to run the application directly with the Flask command. But i prefer to use only Python.

Create a Flask application

Let’s create a flask application inside the __init__.py file.

from flask import Flask


def create_app():
    app = Flask(__name__)
    return app

That’s all. I can also configure the logging here, the database, the static url, or other. But for the moment let it be like that.

And now the __main__.py which will call this method.

from backend import create_app

app = create_app()

if __name__ == "__main__":
    app.run(host=127.0.0.1)

The host parameter is from where the requests are accepted. By default i only accept requests for my localhost. If i want to accept request from anywhere i must replace it by 0.0.0.0.

Now i will create some endpoint to request.

from flask import jsonify, request, Response


@app.route("/health", methods=["GET"])
def health_check():
   return "ok"


@app.route("/users", methods=["GET"])
def get_all_users():
    all_users = [{"id": 1, "name": "joe"}, {"id": 2, "name": "bob"}]
    return jsonify(all_users)


@app.route("/users", methods=["POST"])
def create_user():
    d = request.json
    print(d)
    return Response(status=204)

To start my app I must first enter into my Poetry shell then run my module.

poetry shell
python -m backend

An alternative is to tell Poetry the command to run.

poetry run python -m backend

i could also have started it with Flask but i will need to export the FLASK_APP environment variable.

export FLASK_APP=backend
flask run
  • Using request.json i must ensure that the incoming body is in JSON format, otherwise an exception will be raised.
  • If i want to intercept whatever format i want: I can use request.data.
  • If i need to headers: request.headers.
  • request.method for the HTTP method.
  • request.files for the uploaded files.
  • request.args for the query string.
  • And more.

Blueprints

Ok this starts to be pretty fine, but if my application grows, i must ensure that the endpoints don’t overlap. I must factorize the endpoints. To do that i will use Blueprints.

from flask import Blueprint

health_bp = Blueprint("health", __name__)

@health_bp.route("/health", methods=["GET"])
def health_check():
   return "ok"
from flask import Blueprint, jsonify, request, Response

users_bp = Blueprint("users", __name__, url_prefix="/users")

@users_bp.route("", methods=["GET"])
def get_all_users():
    all_users = [{"id": 1, "name": "joe"}, {"id": 2, "name": "bob"}]
    return jsonify(all_users)

@users_bp.route("", methods=["POST"])
def create_user():
    d = request.json
    print(d)
    return Response(status=204)

And when starting my Flask application, i must register those Blueprints.

from flask import Flask

from backend.routes.health import health_bp
from backend.routes.users import users_bp

def create_app():
    app = Flask(__name__)
    app.register_blueprint(health_bp)
    app.register_blueprint(users_bp)
    return app

Using the Blueprints, i can group my endpoints by prefixes easily. i can also configure some default behavior by Blueprint, as the returning templates for static content, and handling errors.

Error Handler

Let’s create another Blueprint to intercept the exception and return a custom message.

from flask import Blueprint, jsonify
from werkzeug.exceptions import NotFound

error_bp = Blueprint("errors", __name__)


@error_bp.app_errorhandler(NotFound)
def handle_not_found(error):
    return jsonify({"message": "this resource isn't available"}), 404


@error_bp.app_errorhandler(Exception)
def handle_generic_exception(error):
   return jsonify({"message": "Unknown error occured, please check the logs for more details"}), 500

And don’t forget to register the Blueprint.

def create_app():
    app = Flask(__name__)
    app.register_blueprint(health_bp)
    app.register_blueprint(users_bp)
    app.register_blueprint(error_bp)
    return app

Conclusion

  • I’ve initialized the project with Poetry and added the Flask dependency.
  • I’ve created the init module where i’ve created and configured the Flask application.
  • I’ve created the main module where i start the application.
  • I’ve created the root and the route packages with the health check and the user’s endpoint.
  • I’ve added the Blueprints for each endpoint with a prefix.
  • I’ve created the error handler to catch the NotFound exception and the rest of the exceptions.

References

Repository


Never Miss Another Tech Innovation

Concrete insights and actionable resources delivered straight to your inbox to boost your developer career.

My New ebook, Best Practices To Create A Backend With Spring Boot 3, is available now.

Best practices to create a backend with Spring Boot 3

One response to “Flask Backend Setup”

  1. […] won’t need to handle the errors in a Flask application if you predict all the situations. But let’s face it, the user won’t use the […]

    Like

Leave a comment

Discover more from The Dev World - Sergio Lema

Subscribe now to keep reading and get access to the full archive.

Continue reading