Flask MVC
🚀 Features
- 🏗️ 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
📦 Installation
Using pip
pip install flask_mvc
Using Poetry
poetry add flask_mvc
Development Installation
git clone https://github.com/marcuxyz/flask-mvc.git
cd flask_mvc
poetry install
🏃♂️ Quick Start
Basic Setup
from flask import Flask
from flask_mvc import FlaskMVC
app = Flask(__name__)
FlaskMVC(app)
if __name__ == "__main__":
app.run(debug=True)
Using Application Factory Pattern
from flask import Flask
from flask_mvc import FlaskMVC
mvc = FlaskMVC()
def create_app():
app = Flask(__name__)
mvc.init_app(app, path='src')
return app
app = create_app()
Generate Your First Controller
flask mvc generate controller home
flask mvc generate controller user --path src/controllers
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!"
📁 Project Structure
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
🛠️ CLI Commands
Flask MVC provides powerful CLI commands for rapid development:
Controller Generation
flask mvc generate controller blog
flask mvc generate controller api_v1_users
flask mvc generate controller admin --path admin/controllers
flask mvc generate controller posts --force
Available Options
--path | -p | Custom path for generated files |
--force | -f | Overwrite existing files |
--help | -h | Show command help |
🎯 Examples
Web Application Controller
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)
API Controller
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
Hybrid Controller (Web + API)
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)
⚙️ Configuration
Environment Variables
Customize Flask MVC behavior using environment variables:
export FLASK_MVC_CONTROLLERS_PATH="src/controllers"
export FLASK_MVC_VIEWS_PATH="src/templates"
export FLASK_MVC_MODELS_PATH="src/models"
export FLASK_MVC_TEMPLATES_DIR="custom/templates"
export FLASK_MVC_FILE_ENCODING="utf-8"
Programmatic Configuration
from flask_mvc.core.config import CLIConfig
CLIConfig.DEFAULT_CONTROLLERS_PATH = "src/controllers"
CLIConfig.DEFAULT_VIEWS_PATH = "src/templates"
🧪 Testing
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()
result = generator.generate("test", "/tmp/controllers")
assert result.exists()
with pytest.raises(InvalidControllerNameError):
generator.generate("123invalid")
📚 Documentation
🤝 Contributing
We welcome contributions! Please see our Contributing Guidelines for details.
Development Setup
git clone https://github.com/marcuxyz/flask-mvc.git
cd flask_mvc
poetry install
poetry run pytest
poetry run black .
poetry run flake8
poetry run mkdocs serve
Reporting Issues
📋 Requirements
- Python: 3.10+
- Flask: 3.0+
- Click: 8.0+ (included with Flask)
- Jinja2: 3.0+ (included with Flask)
📄 License
This project is licensed under the MIT License - see the LICENSE file for details.
🙏 Acknowledgments
- Flask Community - For the amazing web framework
- Click Team - For the excellent CLI framework
- Contributors - Everyone who has contributed to this project
📊 Stats
