Use Case

/

Rapid Development

Automate boiler plate code creation

Model

Claude 3.7 Sonnet

Generate Flask boilerplate: app factory, environment configs, SQLAlchemy models, and RESTful Blueprints.

Try Query
Claude 3.7 Sonnet
/
coder

Flask Application Boilerplate

Here's a comprehensive Flask boilerplate with app factory pattern, environment configurations, SQLAlchemy models, and RESTful Blueprints.

Project Structure

1my_flask_app/
2├── app/
3│   ├── __init__.py
4│   ├── extensions.py
5│   ├── models/
6│   │   ├── __init__.py
7│   │   └── user.py
8│   ├── api/
9│   │   ├── __init__.py
10│   │   ├── resources/
11│   │   │   ├── __init__.py
12│   │   │   └── user.py
13│   │   └── routes.py
14│   └── config.py
15├── migrations/
16├── tests/
17│   ├── __init__.py
18│   ├── conftest.py
19│   └── test_api.py
20├── .env
21├── .env.example
22├── .gitignore
23├── requirements.txt
24└── wsgi.py

Configuration Files

app/config.py

1import os
2from datetime import timedelta
3
4class Config:
5    """Base configuration."""
6    SECRET_KEY = os.environ.get('SECRET_KEY', 'dev-key-please-change')
7    APP_DIR = os.path.abspath(os.path.dirname(__file__))
8    PROJECT_ROOT = os.path.abspath(os.path.join(APP_DIR, os.pardir))
9    SQLALCHEMY_TRACK_MODIFICATIONS = False
10    JWT_SECRET_KEY = os.environ.get('JWT_SECRET_KEY', 'jwt-secret-key')
11    JWT_ACCESS_TOKEN_EXPIRES = timedelta(hours=1)
12    
13
14class DevelopmentConfig(Config):
15    """Development configuration."""
16    ENV = 'development'
17    DEBUG = True
18    SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL', 
19                                           'sqlite:///' + os.path.join(Config.PROJECT_ROOT, 'dev.db'))
20
21
22class TestingConfig(Config):
23    """Testing configuration."""
24    ENV = 'testing'
25    TESTING = True
26    DEBUG = True
27    SQLALCHEMY_DATABASE_URI = os.environ.get('TEST_DATABASE_URL', 
28                                           'sqlite:///' + os.path.join(Config.PROJECT_ROOT, 'test.db'))
29
30
31class ProductionConfig(Config):
32    """Production configuration."""
33    ENV = 'production'
34    DEBUG = False
35    SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL')
36    SECRET_KEY = os.environ.get('SECRET_KEY')
37    JWT_SECRET_KEY = os.environ.get('JWT_SECRET_KEY')
38
39
40config = {
41    'development': DevelopmentConfig,
42    'testing': TestingConfig,
43    'production': ProductionConfig,
44    'default': DevelopmentConfig
45}

.env.example

1FLASK_APP=wsgi.py
2FLASK_ENV=development
3SECRET_KEY=your-secret-key
4JWT_SECRET_KEY=your-jwt-secret-key
5DATABASE_URL=postgresql://username:password@localhost:5432/dbname

Extensions and App Factory

app/extensions.py

1from flask_sqlalchemy import SQLAlchemy
2from flask_migrate import Migrate
3from flask_jwt_extended import JWTManager
4
5db = SQLAlchemy()
6migrate = Migrate()
7jwt = JWTManager()

app/init.py

1from flask import Flask
2from .extensions import db, migrate, jwt
3from .config import config
4
5
6def create_app(config_name='default'):
7    """Application factory pattern."""
8    app = Flask(__name__)
9    app.config.from_object(config[config_name])
10    
11    # Initialize extensions
12    db.init_app(app)
13    migrate.init_app(app, db)
14    jwt.init_app(app)
15    
16    # Register blueprints
17    from .api import api_bp
18    app.register_blueprint(api_bp, url_prefix='/api/v1')
19    
20    # Shell context for flask cli
21    @app.shell_context_processor
22    def ctx():
23        return {'app': app, 'db': db}
24        
25    return app

Models

app/models/init.py

1from app.extensions import db
2
3# Import models here to ensure they are registered with SQLAlchemy
4from .user import User

app/models/user.py

1from datetime import datetime
2from werkzeug.security import generate_password_hash, check_password_hash
3from app.extensions import db
4
5
6class User(db.Model):
7    """User model for storing user related details."""
8    __tablename__ = 'users'
9
10    id = db.Column(db.Integer, primary_key=True)
11    email = db.Column(db.String(255), unique=True, nullable=False)
12    username = db.Column(db.String(50), unique=True, nullable=False)
13    password_hash = db.Column(db.String(255), nullable=False)
14    is_active = db.Column(db.Boolean, default=True)
15    created_at = db.Column(db.DateTime, default=datetime.utcnow)
16    updated_at = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
17
18    def __init__(self, username, email, password):
19        self.username = username
20        self.email = email
21        self.password = password
22
23    @property
24    def password(self):
25        raise AttributeError('password is not a readable attribute')
26
27    @password.setter
28    def password(self, password):
29        self.password_hash = generate_password_hash(password)
30
31    def verify_password(self, password):
32        return check_password_hash(self.password_hash, password)
33
34    def to_dict(self):
35        return {
36            'id': self.id,
37            'username': self.username,
38            'email': self.email,
39            'is_active': self.is_active,
40            'created_at': self.created_at.isoformat(),
41            'updated_at': self.updated_at.isoformat()
42        }
43
44    def __repr__(self):
45        return f'<User {self.username}>'

API Blueprint and Resources

app/api/init.py

1from flask import Blueprint
2
3api_bp = Blueprint('api', __name__)
4
5from .routes import *

app/api/routes.py

1from flask import jsonify
2from . import api_bp
3from .resources.user import UserResource, UserListResource, UserLoginResource
4
5# User routes
6api_bp.add_url_rule('/users', view_func=UserListResource.as_view('user_list'))
7api_bp.add_url_rule('/users/<int:user_id>', view_func=UserResource.as_view('user_detail'))
8api_bp.add_url_rule('/auth/login', view_func=UserLoginResource.as_view('user_login'))
9
10@api_bp.route('/health')
11def health_check():
12    return jsonify({"status": "healthy"})

app/api/resources/init.py

1# Import resources here
2from .user import UserResource, UserListResource, UserLoginResource

app/api/resources/user.py

1from flask import request, jsonify
2from flask.views import MethodView
3from flask_jwt_extended import create_access_token, jwt_required, get_jwt_identity
4
5from app.extensions import db
6from app.models.user import User
7
8
9class UserListResource(MethodView):
10    """Resource for creating users and getting all users."""
11    
12    def get(self):
13        """Get all users."""
14        users = User.query.all()
15        return jsonify([user.to_dict() for user in users]), 200
16    
17    def post(self):
18        """Create a new user."""
19        data = request.get_json()
20        
21        # Validate required fields
22        if not all(k in data for k in ('username', 'email', 'password')):
23            return jsonify({'message': 'Missing required fields'}), 400
24            
25        # Check if user already exists
26        if User.query.filter_by(email=data['email']).first():
27            return jsonify({'message': 'User with this email already exists'}), 409
28            
29        if User.query.filter_by(username=data['username']).first():
30            return jsonify({'message': 'User with this username already exists'}), 409
31            
32        # Create new user
33        user = User(
34            username=data['username'],
35            email=data['email'],
36            password=data['password']
37        )
38        
39        db.session.add(user)
40        db.session.commit()
41        
42        return jsonify(user.to_dict()), 201
43
44
45class UserResource(MethodView):
46    """Resource for getting, updating and deleting a user."""
47    
48    @jwt_required()
49    def get(self, user_id):
50        """Get a user by id."""
51        user = User.query.get_or_404(user_id)
52        return jsonify(user.to_dict()), 200
53    
54    @jwt_required()
55    def put(self, user_id):
56        """Update a user."""
57        current_user_id = get_jwt_identity()
58        if current_user_id != user_id:
59            return jsonify({'message': 'Unauthorized access'}), 403
60            
61        user = User.query.get_or_404(user_id)
62        data = request.get_json()
63        
64        if 'username' in data:
65            user.username = data['username']
66        if 'email' in data:
67            user.email = data['email']
68        if 'password' in data:
69            user.password = data['password']
70            
71        db.session.commit()
72        
73        return jsonify(user.to_dict()), 200
74    
75    @jwt_required()
76    def delete(self, user_id):
77        """Delete a user."""
78        current_user_id = get_jwt_identity()
79        if current_user_id != user_id:
80            return jsonify({'message': 'Unauthorized access'}), 403
81            
82        user = User.query.get_or_404(user_id)
83        db.session.delete(user)
84        db.session.commit()
85        
86        return jsonify({'message': 'User deleted successfully'}), 200
87
88
89class UserLoginResource(MethodView):
90    """Resource for user login."""
91    
92    def post(self):
93        """Login a user."""
94        data = request.get_json()
95        
96        if not all(k in data for k in ('email', 'password')):
97            return jsonify({'message': 'Missing email or password'}), 400
98            
99        user = User.query.filter_by(email=data['email']).first()
100        
101        if not user or not user.verify_password(data['password']):
102            return jsonify({'message': 'Invalid email or password'}), 401
103            
104        access_token = create_access_token(identity=user.id)
105        
106        return jsonify({
107            'access_token': access_token,
108            'user': user.to_dict()
109        }), 200

WSGI Entry Point

wsgi.py

1import os
2from app import create_app
3
4app = create_app(os.getenv('FLASK_ENV', 'default'))
5
6if __name__ == '__main__':
7    app.run(host='0.0.0.0')

Requirements File

requirements.txt

1Flask==2.2.3
2Flask-SQLAlchemy==3.0.3
3Flask-Migrate==4.0.4
4Flask-JWT-Extended==4.5.2
5psycopg2-binary==2.9.6
6python-dotenv==1.0.0
7pytest==7.3.1

Tests

tests/conftest.py

1import pytest
2from app import create_app
3from app.extensions import db
4from app.models.user import User
5
6
7@pytest.fixture
8def app():
9    app = create_app('testing')
10    
11    with app.app_context():
12        db.create_all()
13        yield app
14        db.session.remove()
15        db.drop_all()
16
17
18@pytest.fixture
19def client(app):
20    return app.test_client()
21
22
23@pytest.fixture
24def db_session(app):
25    with app.app_context():
26        yield db.session
27
28
29@pytest.fixture
30def test_user(db_session):
31    user = User(
32        username='testuser',
33        email='test@example.com',
34        password='password123'
35    )
36    db_session.add(user)
37    db_session.commit()
38    return user

tests/test_api.py

1import json
2from flask_jwt_extended import create_access_token
3
4
5def test_health_check(client):
6    response = client.get('/api/v1/health')
7    assert response.status_code == 200
8    assert response.json['status'] == 'healthy'
9
10
11def test_create_user(client):
12    data = {
13        'username': 'newuser',
14        'email': 'newuser@example.com',
15        'password': 'password123'
16    }
17    response = client.post(
18        '/api/v1/users',
19        data=json.dumps(data),
20        content_type='application/json'
21    )
22    assert response.status_code == 201
23    assert response.json['username'] == 'newuser'
24    assert response.json['email'] == 'newuser@example.com'
25    assert 'password' not in response.json
26
27
28def test_get_user(client, test_user, app):
29    with app.app_context():
30        access_token = create_access_token(identity=test_user.id)
31    
32    response = client.get(
33        f'/api/v1/users/{test_user.id}',
34        headers={'Authorization': f'Bearer {access_token}'}
35    )
36    assert response.status_code == 200
37    assert response.json['username'] == 'testuser'
38    assert response.json['email'] == 'test@example.com'
39
40
41def test_user_login(client, test_user):
42    data = {
43        'email': 'test@example.com',
44        'password': 'password123'
45    }
46    response = client.post(
47        '/api/v1/auth/login',
48        data=json.dumps(data),
49        content_type='application/json'
50    )
51    assert response.status_code == 200
52    assert 'access_token' in response.json
53    assert response.json['user']['username'] == 'testuser'

.gitignore

1# Python
2__pycache__/
3*.py[cod]
4*$py.class
5*.so
6.Python
7env/
8build/
9develop-eggs/
10dist/
11downloads/
12eggs/
13.eggs/
14lib/
15lib64/
16parts/
17sdist/
18var/
19*.egg-info/
20.installed.cfg
21*.egg
22
23# Flask
24instance/
25.webassets-cache
26
27# Environments
28.env
29.venv
30env/
31venv/
32ENV/
33env.bak/
34venv.bak/
35
36# Database
37*.db
38*.sqlite
39
40# IDE
41.idea/
42.vscode/
43*.swp
44*.swo
45
46# Logs
47logs/
48*.log

This boilerplate provides a solid foundation for building a Flask RESTful API with:

  • Application factory pattern
  • Environment-specific configurations
  • SQLAlchemy ORM with User model
  • RESTful API with Blueprint organization
  • JWT authentication
  • Basic test setup

To get started:

  1. Create a virtual environment: python -m venv venv
  2. Activate it: source venv/bin/activate (Linux/Mac) or venv\Scripts\activate (Windows)
  3. Install dependencies: pip install -r requirements.txt
  4. Copy .env.example to .env and configure your environment variables
  5. Initialize the database: flask db init && flask db migrate && flask db upgrade
  6. Run the application: flask run

Experience Ninja's AI Assistant

Try for free today. Plans starting at $5/month.