Example #2: Flask REST API

Scalable Backend
with mkarchi

From
ChatGPTChatGPT

A production-ready Flask API with JWT authentication, SQLAlchemy ORM, and modular architecture. Perfect for starting large-scale backend projects.

How to Run

1
Generate Architecture

Copy the syntax below into a file named flask_api.txt and run:

mkarchi apply flask_api.txt

2
Run API

python -m venv .venv
.\.venv\Scripts\Activate.ps1
pip install -r requirements.txt
python app.py

Check health at: http://localhost:5000/health

Architecture Preview

Flask REST API Architecture
mkarchi-flask-api.txt
flask_rest_api/
├─ app/
│  ├─ __init__.py(begincontenu)
│  │  from flask import Flask
│  │  from flask_cors import CORS
│  │  from .extensions import db, migrate, jwt
│  │  from .config import config_by_name
│  │  from .routes import register_routes
│  │  
│  │  
│  │  def create_app(config_name="development"):
│  │      app = Flask(__name__)
│  │      app.config.from_object(config_by_name[config_name])
│  │  
│  │      CORS(app)
│  │  
│  │      db.init_app(app)
│  │      migrate.init_app(app, db)
│  │      jwt.init_app(app)
│  │  
│  │      register_routes(app)
│  │  
│  │      @app.route("/health", methods=["GET"])
│  │      def health_check():
│  │          return {"status": "ok"}, 200
│  │  
│  │      return app
│  │  
│  │  (endcontenu)
│  ├─ config.py(begincontenu)
│  │  from config import config_by_name
│  │  
│  │  (endcontenu)
│  ├─ extensions.py(begincontenu)
│  │  from extensions import db, migrate, jwt
│  │  
│  │  (endcontenu)
│  └─ routes.py(begincontenu)
│     from routes import register_routes
│     
│     (endcontenu)
├─ docs/
├─ instance/
├─ models/
│  ├─ init.py(begincontenu)
│  │  from .user import User
│  │  from .product import Product
│  │  
│  │  (endcontenu)
│  ├─ product.py(begincontenu)
│  │  from extensions import db
│  │  
│  │  
│  │  class Product(db.Model):
│  │  	id = db.Column(db.Integer, primary_key=True)
│  │  	name = db.Column(db.String(150), nullable=False)
│  │  	price = db.Column(db.Float, nullable=False)
│  │  	description = db.Column(db.Text)
│  │  
│  │  (endcontenu)
│  └─ user.py(begincontenu)
│     from extensions import db
│     from passlib.hash import bcrypt
│     
│     
│     class User(db.Model):
│         id = db.Column(db.Integer, primary_key=True)
│         email = db.Column(db.String(120), unique=True, nullable=False)
│         password_hash = db.Column(db.String(255), nullable=False)
│         is_active = db.Column(db.Boolean, default=True)
│     
│         def set_password(self, password):
│             self.password_hash = bcrypt.hash(password)
│     
│         def check_password(self, password):
│             return bcrypt.verify(password, self.password_hash)
│     
│     
│     (endcontenu)
├─ modules/
│  ├─ auth/
│  │  ├─ init.py
│  │  └─ routes.py(begincontenu)
│  │     from flask import Blueprint, request
│  │     from flask_jwt_extended import create_access_token
│  │     from models.user import User
│  │     from extensions import db
│  │     
│  │     auth_bp = Blueprint("auth", __name__)
│  │     
│  │     
│  │     @auth_bp.route("/login", methods=["POST"])
│  │     def login():
│  │         data = request.json
│  │         user = User.query.filter_by(email=data.get("email")).first()
│  │     
│  │         if not user or not user.check_password(data.get("password")):
│  │             return {"message": "Invalid credentials"}, 401
│  │     
│  │         token = create_access_token(identity=user.id)
│  │         return {"access_token": token}, 200
│  │     
│  │     
│  │     (endcontenu)
│  ├─ products/
│  │  ├─ init.py
│  │  └─ routes.py(begincontenu)
│  │     from flask import Blueprint, request
│  │     from models.product import Product
│  │     from extensions import db
│  │     
│  │     products_bp = Blueprint("products", __name__)
│  │     
│  │     
│  │     @products_bp.route("/", methods=["POST"])
│  │     def create_product():
│  │         data = request.json
│  │         product = Product(
│  │             name=data["name"],
│  │             price=data["price"],
│  │             description=data.get("description"),
│  │         )
│  │         db.session.add(product)
│  │         db.session.commit()
│  │         return {"id": product.id}, 201
│  │     
│  │     (endcontenu)
│  └─ users/
│     ├─ init.py
│     └─ routes.py(begincontenu)
│        from flask import Blueprint
│        from flask_jwt_extended import jwt_required
│        from models.user import User
│        
│        users_bp = Blueprint("users", __name__)
│        
│        
│        @users_bp.route("/", methods=["GET"])
│        @jwt_required()
│        def list_users():
│            users = User.query.all()
│            return {"count": len(users)}, 200
│        
│        (endcontenu)
├─ schemas/
│  ├─ init.py(begincontenu)
│  │  from schemas.user_schema import UserSchema
│  │  from schemas.product_schema import ProductSchema
│  │  
│  │  (endcontenu)
│  ├─ product_schema.py(begincontenu)
│  │  from marshmallow import Schema, fields
│  │  
│  │  class ProductSchema(Schema):
│  │  id = fields.Int(dump_only=True)
│  │  name = fields.Str(required=True)
│  │  price = fields.Float(required=True)
│  │  description = fields.Str()
│  │  
│  │  (endcontenu)
│  └─ user_schema.py(begincontenu)
│     from marshmallow import Schema, fields
│     
│     class UserSchema(Schema):
│     id = fields.Int(dump_only=True)
│     email = fields.Email(required=True)
│     
│     (endcontenu)
├─ tests/
├─ .env.example(begincontenu)
│  FLASK_ENV=development
│  SECRET_KEY=super-secret-key
│  DATABASE_URL=sqlite:///db.sqlite3
│  JWT_SECRET_KEY=jwt-secret
│  
│  (endcontenu)
├─ Dockerfile(begincontenu)
│  FROM python:3.11-slim
│  
│  WORKDIR /app
│  
│  COPY requirements.txt .
│  RUN pip install --no-cache-dir -r requirements.txt
│  
│  COPY . .
│  
│  CMD ["gunicorn", "-w", "4", "-b", "0.0.0.0:5000", "wsgi:app"]
│  
│  (endcontenu)
├─ README.md(begincontenu)
│  # Flask REST API
│  
│  A scalable Flask REST API built with best practices.
│  
│  ## Features
│  - JWT Authentication
│  - SQLAlchemy ORM
│  - Marshmallow Serialization
│  - Docker Support
│  - Modular Architecture
│  
│  ## Run locally
│  ```bash
│  python app.py
│  
│  
│  (endcontenu)
├─ api.md(begincontenu)
│  API Documentation
│  Auth
│  
│  POST /api/auth/login
│  Users
│  
│  GET /api/users/
│  Products
│  
│  POST /api/products/
│  
│  (endcontenu)
├─ app.py(begincontenu)
│  from flask import Flask
│  from flask_cors import CORS
│  from app.extensions import db, migrate, jwt
│  from app.config import config_by_name
│  from app.routes import register_routes
│  
│  def create_app(config_name="development"):
│      app = Flask(__name__)
│      app.config.from_object(config_by_name[config_name])
│  
│      CORS(app)
│  
│      db.init_app(app)
│      migrate.init_app(app, db)
│      jwt.init_app(app)
│  
│      register_routes(app)
│  
│      @app.route("/health", methods=["GET"])
│      def health_check():
│          return {"status": "ok"}, 200
│  
│      return app
│  
│  if __name__ == "__main__":
│      app = create_app()
│      app.run(host="0.0.0.0", port=5000)
│  
│  (endcontenu)
├─ config.py(begincontenu)
│  import os
│  
│  class BaseConfig:
│  	SECRET_KEY = os.getenv("SECRET_KEY", "secret")
│  	SQLALCHEMY_TRACK_MODIFICATIONS = False
│  	JWT_SECRET_KEY = os.getenv("JWT_SECRET_KEY", "jwt-secret")
│  
│  
│  class DevelopmentConfig(BaseConfig):
│  	DEBUG = True
│  	SQLALCHEMY_DATABASE_URI = os.getenv("DATABASE_URL", "sqlite:///dev.db")
│  
│  
│  class ProductionConfig(BaseConfig):
│  	DEBUG = False
│  	SQLALCHEMY_DATABASE_URI = os.getenv("DATABASE_URL")
│  
│  
│  config_by_name = {
│  	"development": DevelopmentConfig,
│  	"production": ProductionConfig,
│  }
│  
│  (endcontenu)
├─ docker-compose.yml(begincontenu)
│  version: "3.9"
│  
│  services:
│    api:
│      build: .
│      ports:
│        - "5000:5000"
│      env_file:
│        - .env
│      volumes:
│        - .:/app
│  
│  (endcontenu)
├─ extensions.py(begincontenu)
│  from flask_sqlalchemy import SQLAlchemy
│  from flask_migrate import Migrate
│  from flask_jwt_extended import JWTManager
│  
│  db = SQLAlchemy()
│  migrate = Migrate()
│  jwt = JWTManager()
│  
│  (endcontenu)
├─ init.py(begincontenu)
│  from flask import Flask
│  
│  (endcontenu)
├─ requirements.txt(begincontenu)
│  Flask==3.0.0
│  Flask-Cors==4.0.0
│  Flask-SQLAlchemy==3.1.1
│  Flask-Migrate==4.0.5
│  Flask-JWT-Extended==4.6.0
│  python-dotenv==1.0.1
│  marshmallow==3.21.1
│  passlib==1.7.4
│  gunicorn==21.2.0
│  
│  (endcontenu)
├─ routes.py(begincontenu)
│  from modules.auth.routes import auth_bp
│  from modules.users.routes import users_bp
│  from modules.products.routes import products_bp
│  
│  def register_routes(app):
│  	app.register_blueprint(auth_bp, url_prefix="/api/auth")
│  	app.register_blueprint(users_bp, url_prefix="/api/users")
│  	app.register_blueprint(products_bp, url_prefix="/api/products")
│  
│  (endcontenu)
├─ test_health.py(begincontenu)
│  def test_health(client):
│  response = client.get("/health")
│  assert response.status_code == 200
│  
│  (endcontenu)
└─ wsgi.py(begincontenu)
   from app import create_app
   
   app = create_app("production")
   
   (endcontenu)
This syntax includes Dockerfile and docker-compose configurations.