Transform your Flask application into a structured MVC architecture with powerful CLI tools
Installation β’ Quick Start β’ Documentation β’ Examples β’ Contributing
- ποΈ MVC Architecture: Clean separation of concerns with Models, Views, and Controllers
- β‘ CLI Generator: Powerful command-line tools to generate controllers, models, and more
- π¨ Template System: Professional templates with Flask best practices
- π§ Flexible Configuration: Customizable paths and settings via environment variables
- π Type Safety: Full type hints support for better development experience
- π§ͺ Testing Ready: Built-in support for testing with comprehensive error handling
- π Auto Documentation: Generated code includes professional docstrings
- π API & Web Support: Content negotiation for both web and API responses
pip install flask_mvc
poetry add flask_mvc
git clone https://github.com/marcuxyz/flask-mvc.git
cd flask_mvc
poetry install
from flask import Flask
from flask_mvc import FlaskMVC
app = Flask(__name__)
FlaskMVC(app)
if __name__ == "__main__":
app.run(debug=True)
from flask import Flask
from flask_mvc import FlaskMVC
mvc = FlaskMVC()
def create_app():
app = Flask(__name__)
# Initialize MVC extension
mvc.init_app(app, path='src') # Custom path (default: 'app')
return app
app = create_app()
# Generate a basic controller
flask mvc generate controller home
# Generate controller in custom path
flask mvc generate controller user --path src/controllers
# Force overwrite existing controller
flask mvc generate controller admin --force
This creates a professional controller with CRUD operations:
"""HomeController - Generated by Flask MVC CLI."""
from flask import render_template, jsonify, request
from typing import Any, Dict, Optional, Union
class HomeController:
"""Controller for handling home related requests."""
def index(self) -> Union[str, Dict[str, Any]]:
"""Display the index page."""
if request.is_json or request.accept_mimetypes.accept_json:
return jsonify({
"message": "Hello from HomeController!",
"controller": "home",
"action": "index"
})
return "Hello from HomeController!"
# Complete CRUD methods included...
Flask MVC encourages a clean project structure:
your-project/
βββ app/ # Main application directory
β βββ __init__.py
β βββ controllers/ # Controllers directory
β β βββ __init__.py
β β βββ home_controller.py
β β βββ user_controller.py
β βββ models/ # Models directory (optional)
β β βββ user.py
β βββ views/ # Templates directory
β β βββ layouts/
β β βββ home/
β β βββ user/
β βββ routes.py # Route definitions
βββ tests/ # Test directory
βββ requirements.txt # Dependencies
βββ app.py # Application entry point
Flask MVC provides powerful CLI commands for rapid development:
# Basic controller
flask mvc generate controller blog
# API controller
flask mvc generate controller api_v1_users
# Controller with custom path
flask mvc generate controller admin --path admin/controllers
# Force overwrite
flask mvc generate controller posts --force
Option | Short | Description |
---|---|---|
--path |
-p |
Custom path for generated files |
--force |
-f |
Overwrite existing files |
--help |
-h |
Show command help |
class BlogController:
def index(self):
posts = Post.get_all()
return render_template('blog/index.html', posts=posts)
def show(self, id: int):
post = Post.get_by_id(id)
return render_template('blog/show.html', post=post)
class ApiUserController:
def index(self):
users = User.get_all()
return jsonify([user.to_dict() for user in users])
def create(self):
data = request.get_json()
user = User.create(data)
return jsonify(user.to_dict()), 201
Generated controllers automatically handle both web and API requests:
def index(self) -> Union[str, Dict[str, Any]]:
posts = Post.get_all()
if request.is_json or request.accept_mimetypes.accept_json:
return jsonify([post.to_dict() for post in posts])
return render_template('posts/index.html', posts=posts)
Customize Flask MVC behavior using environment variables:
# Custom paths
export FLASK_MVC_CONTROLLERS_PATH="src/controllers"
export FLASK_MVC_VIEWS_PATH="src/templates"
export FLASK_MVC_MODELS_PATH="src/models"
# Template settings
export FLASK_MVC_TEMPLATES_DIR="custom/templates"
export FLASK_MVC_FILE_ENCODING="utf-8"
from flask_mvc.core.config import CLIConfig
# Override default settings
CLIConfig.DEFAULT_CONTROLLERS_PATH = "src/controllers"
CLIConfig.DEFAULT_VIEWS_PATH = "src/templates"
Flask MVC is built with testing in mind:
import pytest
from flask_mvc.core.generators import ControllerGenerator
from flask_mvc.core.exceptions import InvalidControllerNameError
def test_controller_generation():
generator = ControllerGenerator()
# Test valid controller generation
result = generator.generate("test", "/tmp/controllers")
assert result.exists()
# Test invalid name handling
with pytest.raises(InvalidControllerNameError):
generator.generate("123invalid")
- Full Documentation - Complete guide and API reference
- Quick Start Guide - Get up and running fast
- Controller Guide - Working with controllers
- Router Guide - Route configuration
- CLI Reference - Command-line tools
We welcome contributions! Please see our Contributing Guidelines for details.
# Clone the repository
git clone https://github.com/marcuxyz/flask-mvc.git
cd flask_mvc
# Install dependencies
poetry install
# Run tests
poetry run pytest
# Run linting
poetry run black .
poetry run flake8
# Build documentation
poetry run mkdocs serve
- Python: 3.10+
- Flask: 3.0+
- Click: 8.0+ (included with Flask)
- Jinja2: 3.0+ (included with Flask)
This project is licensed under the MIT License - see the LICENSE file for details.
- Flask Community - For the amazing web framework
- Click Team - For the excellent CLI framework
- Contributors - Everyone who has contributed to this project