FolderStructure.dev

Flask Factory Pattern Project Structure

Application factory with config classes and CLI. Production-ready Flask architecture.

#flask #python #web #backend #production #factory
PNGPDF

Project Directory

myproject/
wsgi.py
WSGI entry point (Gunicorn)
manage.py
CLI commands (optional)
requirements.txt
requirements/
Split by environment
base.txt
dev.txt
prod.txt
.env
.env.example
.gitignore
config/
Configuration classes
__init__.py
Config selector
base.py
Shared settings
development.py
production.py
testing.py
app/
Application package
__init__.py
create_app() factory
extensions.py
db, migrate, login, etc.
cli.py
Custom Flask CLI commands
models/
Split models by domain
__init__.py
Model imports
user.py
post.py
views/
All blueprints
__init__.py
main.py
Main blueprint
auth.py
Auth blueprint
api.py
API blueprint
services/
Business logic
__init__.py
user_service.py
email_service.py
templates/
base.html
main/
auth/
errors/
404.html, 500.html
static/
css/
js/
images/
utils/
Helper functions
__init__.py
decorators.py
helpers.py
tests/
__init__.py
conftest.py
App fixture with test config
test_models.py
test_views.py
test_services.py
migrations/
Flask-Migrate (Alembic)
versions/
env.py
alembic.ini

Why This Structure?

The factory pattern is Flask best practice for production. create_app() initializes everything based on config classes. This enables different configs for dev/test/prod, proper testing with isolated app instances, and clean separation between configuration and application code.

Key Directories

  • config/-Environment-specific config classes (Development, Production, Testing)
  • app/__init__.py-create_app(config_name) factory function
  • app/services/-Business logic separate from routes
  • app/views/-Blueprints organized as single files
  • tests/conftest.py-Pytest fixtures with test app instance

Application Factory

# app/__init__.py
def create_app(config_name='development'):
    app = Flask(__name__)
    app.config.from_object(config[config_name])
    
    # Initialize extensions
    db.init_app(app)
    migrate.init_app(app, db)
    login_manager.init_app(app)
    
    # Register blueprints
    from app.views import main_bp, auth_bp, api_bp
    app.register_blueprint(main_bp)
    app.register_blueprint(auth_bp, url_prefix='/auth')
    app.register_blueprint(api_bp, url_prefix='/api')
    
    return app

Config Classes

# config/base.py
class BaseConfig:
    SECRET_KEY = os.environ.get('SECRET_KEY')
    SQLALCHEMY_TRACK_MODIFICATIONS = False

# config/development.py
class DevelopmentConfig(BaseConfig):
    DEBUG = True
    SQLALCHEMY_DATABASE_URI = 'sqlite:///dev.db'

# config/production.py
class ProductionConfig(BaseConfig):
    SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL')

Getting Started

  1. python -m venv venv && source venv/bin/activate
  2. pip install -r requirements/dev.txt
  3. cp .env.example .env && edit .env
  4. export FLASK_APP=wsgi.py FLASK_ENV=development
  5. flask db upgrade
  6. flask run

When To Use This

  • Production deployments
  • Need different configs for dev/staging/prod
  • Business logic complex enough for service layer
  • Team of 3+ developers
  • Projects needing comprehensive test coverage

Testing Setup

# tests/conftest.py
@pytest.fixture
def app():
    app = create_app('testing')
    with app.app_context():
        db.create_all()
        yield app
        db.drop_all()

@pytest.fixture
def client(app):
    return app.test_client()

Trade-offs

  • More structure-Overkill for small projects
  • Initial setup-Takes time to scaffold properly
  • Import complexity-Must understand factory initialization order