# Flask Python

> Application Factory, Blueprints, SQLAlchemy, and config separation for Flask

- Skill: `mokhtarabadi/flask-python` (Agent Skill)
- Install (CLI): `npx skillmds@latest add mokhtarabadi/flask-python`
- Raw SKILL.md: https://api.skillmd.com/api/skills/mokhtarabadi/flask-python/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: mokhtarabadi (https://skillmd.com/u/mokhtarabadi)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/mokhtarabadi/flask-python

---


# Flask (Python) — Best Practices

## Project Structure

```
project/
├── app/
│   ├── __init__.py           # Application Factory (create_app)
│   ├── config.py             # Configuration classes (Dev, Prod, Test)
│   ├── extensions.py         # Flask extensions (db, migrate, login)
│   ├── blueprints/
│   │   ├── auth/
│   │   │   ├── __init__.py   # Blueprint creation
│   │   │   ├── routes.py     # Route definitions
│   │   │   └── forms.py      # WTForms schemas
│   │   └── users/
│   │       ├── __init__.py
│   │       └── routes.py
│   ├── models/               # SQLAlchemy models
│   │   ├── __init__.py
│   │   └── user.py
│   ├── services/             # Business logic
│   │   └── user_service.py
│   └── templates/            # Jinja2 templates (if server-rendered)
├── tests/
│   ├── conftest.py           # Pytest fixtures (app, client, db)
│   ├── test_auth.py
│   └── test_users.py
├── .env                      # Local environment variables
├── requirements.txt
└── run.py                    # Entry point
```

## Naming Conventions

| Artifact              | Convention          | Example           |
| --------------------- | ------------------- | ----------------- |
| Files/Directories     | `snake_case`        | `user_service.py` |
| Classes               | `PascalCase`        | `UserService`     |
| Functions/Methods     | `snake_case`        | `get_user_by_id`  |
| Variables             | `snake_case`        | `current_user`    |
| Blueprint names       | plural nouns        | `users`           |
| Route prefixes        | plural `kebab-case` | `/api/users`      |
| Environment variables | `UPPER_SNAKE_CASE`  | `DATABASE_URL`    |

## Architectural Patterns

### Application Factory Pattern

Use `create_app(config_name)` in `app/__init__.py` to build the Flask instance. This allows creating different app instances for development, testing, and production without global state.

```python
def create_app(config_name="development"):
    app = Flask(__name__)
    app.config.from_object(config_map[config_name])
    register_extensions(app)
    register_blueprints(app)
    return app
```

### Blueprints for Routing

Organize routes into Blueprints. Each feature domain gets its own Blueprint. Never define routes directly on the `app` instance outside of a Blueprint.

```python
users_bp = Blueprint("users", __name__, url_prefix="/api/users")
```

### SQLAlchemy ORM

- Define models in a dedicated `models/` package, not in `routes.py`.
- Use `backref` sparingly — prefer explicit `relationship` definitions.
- Use Alembic (via Flask-Migrate) for all schema migrations; never hand-write DDL.
- Keep query logic in dedicated repository functions or service methods — never inline queries in route handlers.

### Configuration Separation

Create a `config.py` with at least three classes: `Config` (base), `DevelopmentConfig`, `ProductionConfig`, `TestingConfig`. Load the correct one via environment variable or default.

### Virtual Environment Rules

- Always use a virtual environment (venv or pipenv).
- Pin dependency versions in `requirements.txt`.
- Never commit `.venv/` or `__pycache__/` to version control.

## Universal DateTime Governance

- **Timezone-Aware Datetimes:** Use `datetime.now(timezone.utc)` exclusively. Banned: bare `datetime.now()` and `datetime.utcnow()`.
- **Clock Abstraction:** Create a `ClockProvider` class (`def now() -> datetime`) injected into services. Never call `datetime.now()` directly in business logic.
- **API Format:** Transmit datetimes as ISO-8601 with offset (`2026-07-23T14:30:00+00:00`) or Unix epoch milliseconds.

## Testing Strategies

| Layer        | Test Type   | Framework                  | File Naming            |
| ------------ | ----------- | -------------------------- | ---------------------- |
| Service      | Unit        | Pytest                     | `test_user_service.py` |
| Route / View | Integration | Pytest + Flask test client | `test_auth_routes.py`  |
| Model        | Unit        | Pytest                     | `test_user_model.py`   |

- Use `pytest` as the test runner (not `unittest`).
- Use `conftest.py` to define shared fixtures (app instance, test client, database session).
- Use an in-memory SQLite database for fast test runs.
- For every Blueprint, write at least one test that validates the route returns the expected status code.

