# Flask MVC

<div align="center">

![Flask MVC Logo](https://img.shields.io/badge/Flask-MVC-blue?style=for-the-badge&logo=flask)

[![GitHub code size in bytes](https://img.shields.io/github/languages/code-size/marcuxyz/flask-mvc?style=flat-square)](https://github.com/marcuxyz/flask-mvc)
[![GitHub Workflow Status](https://img.shields.io/github/workflow/status/marcuxyz/flask-mvc/unit%20test?style=flat-square)](https://github.com/marcuxyz/flask-mvc/actions)
[![GitHub](https://img.shields.io/github/license/marcuxyz/flask-mvc?style=flat-square)](https://github.com/marcuxyz/flask-mvc/blob/main/LICENSE)
[![PyPI - Downloads](https://img.shields.io/pypi/dm/flask_mvc?style=flat-square)](https://pypi.org/project/flask_mvc/)
[![PyPI - Python Version](https://img.shields.io/pypi/pyversions/flask_mvc?style=flat-square)](https://pypi.org/project/flask_mvc/)
[![PyPI](https://img.shields.io/pypi/v/flask_mvc?style=flat-square)](https://pypi.org/project/flask_mvc/)
[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg?style=flat-square)](https://github.com/psf/black)

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

[Installation](#installation) •
[Quick Start](#quick-start) •
[Documentation](https://marcuxyz.github.io/flask-mvc) •
[Examples](#examples) •
[Contributing](#contributing)

</div>

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

```bash
pip install flask_mvc
```

### Using Poetry

```bash
poetry add flask_mvc
```

### Development Installation

```bash
git clone https://github.com/marcuxyz/flask-mvc.git
cd flask_mvc
poetry install
```

## 🏃‍♂️ Quick Start

### Basic Setup

```python
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

```python
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 Your First Controller

```bash
# 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:

```python
"""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

```bash
# 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

```python
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

```python
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:

```python
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:

```bash
# 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

```python
from flask_mvc.core.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:

```python
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")
```

## 📚 Documentation

- **[Full Documentation](https://marcuxyz.github.io/flask-mvc)** - Complete guide and API reference
- **[Quick Start Guide](https://marcuxyz.github.io/flask-mvc/quickstart)** - Get up and running fast
- **[Controller Guide](https://marcuxyz.github.io/flask-mvc/controllers)** - Working with controllers
- **[Router Guide](https://marcuxyz.github.io/flask-mvc/router)** - Route configuration
- **[CLI Reference](https://marcuxyz.github.io/flask-mvc/cli)** - Command-line tools

## 🤝 Contributing

We welcome contributions! Please see our [Contributing Guidelines](CONTRIBUTING.md) for details.

### Development Setup

```bash
# 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
```

### Reporting Issues

- **[Bug Reports](https://github.com/marcuxyz/flask-mvc/issues/new?template=bug_report.md)**
- **[Feature Requests](https://github.com/marcuxyz/flask-mvc/issues/new?template=feature_request.md)**

## 📋 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](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](https://img.shields.io/github/stars/marcuxyz/flask-mvc?style=social)
![GitHub forks](https://img.shields.io/github/forks/marcuxyz/flask-mvc?style=social)
![GitHub watchers](https://img.shields.io/github/watchers/marcuxyz/flask-mvc?style=social)

---

<div align="center">
Made with ❤️ by <a href="https://github.com/marcuxyz">Marcus Pereira</a>
</div>
