Flask Summary

Flask’s minimalism is a feature, not a limitation, but it means you’re responsible for every architectural decision, from database connections to route organization. This reference covers the core patterns that come up when building Flask APIs in production, from environment setup to MongoDB integration.

TL;DR: Set up a complete Flask API with routes, database connection via Peewee ORM, use cases, repositories, Swagger docs, and MongoDB integration.
Stack: Python, Flask, Flask-CORS, Peewee ORM, PostgreSQL, MongoDB, python-dotenv, Swagger
Level: Intermediate
Reading time: ~12 min

Flask is the right tool when you need a lightweight API without Django’s overhead, particularly useful for microservices and AI inference endpoints where control over the stack matters more than convention.

Install Flask and CORS

pip install flask
pip install flask-cors
pip install python-dotenv

First route

from flask import Flask
from flask_cors import CORS

app = Flask(__name__)
CORS(app)

@app.route("/")
def hello():
    return "Hello with cors"

Install Peewee and drivers

pip install peewee
pip install psycopg
pip install psycopg-binary

Singleton connection (infra/repositories/singleton_connection.py)

A singleton ensures your app opens exactly one database connection per process lifecycle, critical in production to avoid connection pool exhaustion.

from peewee import PostgresqlDatabase
import os
from dotenv import load_dotenv

load_dotenv()

db = PostgresqlDatabase(
    os.getenv('DB_NAME', 'djangopoc'),
    user=os.getenv('DB_USER', 'admin'),
    password=os.getenv('DB_PASSWORD', '123456'),
    host=os.getenv('DB_HOST', 'localhost'),
    port=int(os.getenv('DB_PORT', 5432))
)

class SingletonConnection:
    _instance = None

    def __new__(cls):
        if cls._instance is None:
            cls._instance = super().__new__(cls)
            cls._instance._connection = db
            try:
                cls._instance._connection.connect()
                print("Database connection successful!")
            except Exception as e:
                print(f"Database connection failed: {e}")
        return cls._instance

    def get_connection(self):
        return self._connection

singleton_connection = SingletonConnection()

Configure routes

from flask import jsonify
from application.use_cases.list_positions.list_positions import ListPositions
from infra.repositories.position_repository_postgre import PositionRepositoryPostgre

def positions_route(app):
    @app.route("/list-positions", methods=['GET'])
    def list_positions():
        try:
            use_case = ListPositions(PositionRepositoryPostgre())
            positions = use_case.execute()
            result_list = [{'name': p.name, 'id': p.id} for p in positions.items]
            return jsonify(result_list), 200
        except Exception as e:
            return jsonify({'error': str(e)}), 500

Use cases, repositories, and tests

The architecture follows the same pattern throughout: the route handles HTTP, the use case handles business logic, and the repository abstracts the database. Each layer is testable in isolation. Swap the concrete repository implementation without touching your use cases, and mock the repository to test use case logic without a real database connection.

Swagger

pip install flasgger

# setup in app.py
from flasgger import Swagger
swagger = Swagger(app)

MongoDB

pip install pymongo

Same singleton pattern as PostgreSQL, just swap the driver. The MongoDB repository uses the aggregation pipeline for grouped queries, which replaces GROUP BY from SQL.

What you’ve built

A complete Flask reference covering the full stack: environment setup, database integration with Peewee ORM, clean architecture with use cases and repository protocols, test patterns, Swagger docs, and MongoDB connectivity. This structure scales from a side project to a production API without a rewrite.

Next steps

  • Add authentication: integrate Flask-JWT-Extended or an API key middleware to secure your endpoints.
  • Containerize it: wrap this setup in a Dockerfile and connect to a CI/CD pipeline.
  • Add observability: plug in structured logging and AWS X-Ray tracing to get visibility into production requests.

Questions or feedback? Find me on LinkedIn or GitHub.

Leave a Comment