Skip to content

Latest commit

Β 

History

75 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Flask MVC

Flask MVC Logo

GitHub code size in bytes GitHub Workflow Status GitHub PyPI - Downloads PyPI - Python Version PyPI Code style: black

Transform your Flask application into a structured MVC architecture with powerful CLI tools

Installation β€’ Quick Start β€’ Documentation β€’ Examples β€’ Contributing

πŸš€ 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
  • οΏ½ SQLAlchemy Introspection: Deferred model reflection support via ReflectedModel and FlaskReflection, allowing models to map table schemas dynamically without explicit field declarations.
  • οΏ½πŸ“– Auto Documentation: Generated code includes professional docstrings
  • 🌐 API & Web Support: Content negotiation for both web and API responses

πŸ“¦ Installation

Using pip

pip install flask-mvc2

Using UV

uv add flask-mvc2

Development Installation

git clone https://github.com/marcuxyz/flask-mvc.git
cd flask_mvc
uv sync

πŸƒβ€β™‚οΈ 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
from flask_sqlalchemy import SQLAlchemy

mvc = FlaskMVC()
db = SQLAlchemy()

def create_app():
    app = Flask(__name__)
    app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///blog.db'

    db.init_app(app)
    mvc.init_app(app, path='src')  # Custom path (default: 'app')

    return app

app = create_app()

SQLAlchemy Introspection Support

Flask MVC now includes Rails-like SQLAlchemy introspection support. With ReflectedModel and FlaskReflection, you can define a model that only declares __tablename__ while the extension discovers table columns at runtime.

from flask_mvc.middlewares.base_model import ReflectedModel
from tests.app import db

class Message(ReflectedModel, db.Model):
    __tablename__ = 'messages'

This feature works best when the database extension is initialized before Flask MVC:

db.init_app(app)
FlaskMVC(app, path='app', db=db)

Generate Your First Controller

# 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...

πŸ“ 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

# 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

Available Options

Option Short Description
--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:

# 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"

Programmatic Configuration

from flask_mvc.commands.config import CLIConfig

# Override default settings
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.command.controller.generator import Generator as ControllerGenerator
from flask_mvc.command.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")

πŸ“š Documentation

🀝 Contributing

We welcome contributions! Please see our Contributing Guidelines for details.

Development Setup

# Clone the repository
git clone https://github.com/marcuxyz/flask-mvc.git
cd flask_mvc

# Install dependencies
uv sync

# Run tests
uv run pytest

# Run linting
uv run black .
uv run flake8

# Build documentation
uv run mkdocs serve

Reporting Issues

πŸ“‹ Requirements

  • Python: 3.12+
  • 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

GitHub stars GitHub forks GitHub watchers


Made with ❀️ by Marcus Pereira

About

You can use the mvc-flask extension to turn on MVC pattern in your applications.

Topics

Resources

Stars

55 stars

Watchers

4 watching

Forks

Releases

Used by

Contributors

Languages