Provides guardrails for Flask development, focusing on factories, blueprints, and security.

Install

mkdir -p .claude/skills/flask && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/12261" && unzip -o skill.zip -d .claude/skills/flask && rm skill.zip

Installs to .claude/skills/flask

Activation

This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.

Flask framework guardrails, patterns, and best practices for AI-assisted development. Use when working with Flask projects, or when the user mentions Flask. Provides blueprint patterns, extensions, Jinja2 templates, and REST API guidelines.
240 chars✓ has a “when” trigger
Intermediate

Key capabilities

  • Apply the application factory pattern for Flask applications.
  • Organize routes using Flask blueprints.
  • Integrate Flask extensions through a single initialization point.
  • Configure applications using environment variables and class-based config.
  • Validate and serialize data with Marshmallow schemas.
  • Implement secure authentication using Flask-JWT-Extended.

How it works

The skill provides guidelines and patterns for building Flask applications, enforcing architectural choices like application factories and blueprints, and recommending specific extensions and security practices.

Inputs & outputs

You give it
Request to build or modify a Flask application
You get back
Flask application code adhering to architectural patterns and best practices

When to use flask

  • Set up Flask application factory
  • Organize routes with blueprints
  • Implement secure API auth

About this skill

Flask Framework Guide

Applies to: Flask 3.0+, REST APIs, Microservices, Web Applications Language Guide: @.claude/skills/python-guide/SKILL.md

Overview

Flask is a lightweight WSGI web framework providing the basics for building web applications while allowing flexibility in choosing components.

Use Flask when:

  • Building microservices or small-to-medium APIs
  • You want flexibility to choose your own ORM, auth, etc.
  • Rapid prototyping is needed
  • You prefer explicit over implicit behavior

Consider alternatives when:

  • You need async support (use FastAPI or Quart)
  • You want batteries-included (use Django)
  • High performance async is critical (use FastAPI)

Guardrails

Flask-Specific Guidelines

  • Use the application factory pattern (never use global app instances)
  • Use blueprints for modular routing
  • Use Flask extensions appropriately (init in extensions.py)
  • Configure via environment variables with class-based config
  • Use Marshmallow for validation/serialization
  • Implement proper error handlers for all error types
  • Use Flask-Migrate for database migrations
  • Use Flask-JWT-Extended for authentication

Security Guidelines

  • Never store plain passwords (use werkzeug.security)
  • Use environment variables for all secrets
  • Implement proper authentication and authorization
  • Validate all user input with Marshmallow schemas
  • Use HTTPS in production
  • Set secure cookie options (HTTPONLY, SECURE, SAMESITE)
  • Sanitize all database queries via SQLAlchemy ORM
  • Configure CORS restrictively in production

Testing Guidelines

  • Use pytest with Flask test client
  • Use fixtures for test data and app context
  • Test both success and error cases for every endpoint
  • Mock external services (never call real APIs in tests)
  • Use a separate test database
  • Coverage target: >80% for business logic

Project Structure

myproject/
├── app/
│   ├── __init__.py           # Application factory
│   ├── config.py             # Configuration classes
│   ├── extensions.py         # Flask extensions (single init point)
│   ├── models/
│   │   ├── __init__.py
│   │   ├── base.py           # Base model class with mixins
│   │   └── user.py
│   ├── api/
│   │   ├── __init__.py       # API blueprint registration
│   │   ├── users.py          # User endpoints
│   │   └── auth.py           # Auth endpoints
│   ├── services/
│   │   ├── __init__.py
│   │   └── user_service.py   # Business logic (no Flask imports)
│   ├── schemas/
│   │   ├── __init__.py
│   │   └── user.py           # Marshmallow schemas
│   └── utils/
│       ├── __init__.py
│       ├── errors.py         # Custom exceptions and handlers
│       └── decorators.py     # Auth and role decorators
├── migrations/               # Alembic migrations (via Flask-Migrate)
├── tests/
│   ├── conftest.py           # Fixtures: app, client, db_session
│   ├── test_api/
│   │   └── test_users.py
│   └── test_services/
│       └── test_user_service.py
├── .env.example
├── requirements.txt
├── requirements-dev.txt
├── pyproject.toml
└── run.py                    # Entry point

Key conventions:

  • app/__init__.py contains create_app() factory only
  • app/extensions.py centralizes all extension instances
  • app/services/ holds business logic, no Flask imports
  • app/schemas/ holds Marshmallow validation/serialization
  • app/utils/errors.py defines custom exceptions and handlers

Application Factory

Always use the factory pattern. Never use a global app = Flask(__name__).

"""Flask application factory."""
from flask import Flask

from app.config import config
from app.extensions import db, migrate, ma, jwt, cors


def create_app(config_name: str = "development") -> Flask:
    """Create and configure the Flask application."""
    app = Flask(__name__)
    app.config.from_object(config[config_name])

    register_extensions(app)
    register_blueprints(app)
    register_error_handlers(app)
    register_commands(app)

    return app


def register_extensions(app: Flask) -> None:
    """Initialize Flask extensions."""
    db.init_app(app)
    migrate.init_app(app, db)
    ma.init_app(app)
    jwt.init_app(app)
    cors.init_app(app)


def register_blueprints(app: Flask) -> None:
    """Register Flask blueprints."""
    from app.api import api_bp
    app.register_blueprint(api_bp, url_prefix="/api/v1")


def register_error_handlers(app: Flask) -> None:
    """Register error handlers."""
    from app.utils.errors import (
        handle_app_error,
        handle_validation_error,
        handle_not_found,
        handle_internal_error,
    )
    from marshmallow import ValidationError

    app.register_error_handler(ValidationError, handle_validation_error)
    app.register_error_handler(404, handle_not_found)
    app.register_error_handler(500, handle_internal_error)


def register_commands(app: Flask) -> None:
    """Register CLI commands."""
    from app.commands import seed_db
    app.cli.add_command(seed_db)

Blueprints

Organize routes into blueprints. Register them in the factory.

"""API blueprint registration."""
from flask import Blueprint

api_bp = Blueprint("api", __name__)

# Import routes to register them
from app.api import users, auth  # noqa: F401, E402

Blueprint endpoints follow REST conventions:

MethodRouteHandlerDescription
GET/resourcesget_resources()List with pagination
GET/resources/<id>get_resource(id)Get single resource
POST/resourcescreate_resource()Create resource
PATCH/resources/<id>update_resource(id)Partial update
DELETE/resources/<id>delete_resource(id)Delete resource

Configuration

Use class-based configuration with environment variable overrides.

"""Application configuration."""
import os
from datetime import timedelta
from typing import Type


class Config:
    """Base configuration."""
    SECRET_KEY = os.getenv("SECRET_KEY", "change-in-production")
    SQLALCHEMY_TRACK_MODIFICATIONS = False
    SQLALCHEMY_ENGINE_OPTIONS = {
        "pool_pre_ping": True,
        "pool_recycle": 300,
    }
    JWT_SECRET_KEY = os.getenv("JWT_SECRET_KEY", SECRET_KEY)
    JWT_ACCESS_TOKEN_EXPIRES = timedelta(hours=1)
    JWT_REFRESH_TOKEN_EXPIRES = timedelta(days=30)
    CORS_ORIGINS = os.getenv("CORS_ORIGINS", "*").split(",")


class DevelopmentConfig(Config):
    DEBUG = True
    SQLALCHEMY_DATABASE_URI = os.getenv(
        "DATABASE_URL",
        "postgresql://postgres:postgres@localhost:5432/myapp_dev"
    )
    SQLALCHEMY_ECHO = True


class TestingConfig(Config):
    TESTING = True
    SQLALCHEMY_DATABASE_URI = os.getenv(
        "TEST_DATABASE_URL",
        "postgresql://postgres:postgres@localhost:5432/myapp_test"
    )


class ProductionConfig(Config):
    DEBUG = False
    SQLALCHEMY_DATABASE_URI = os.environ["DATABASE_URL"]
    SESSION_COOKIE_SECURE = True
    SESSION_COOKIE_HTTPONLY = True
    SESSION_COOKIE_SAMESITE = "Lax"


config: dict[str, Type[Config]] = {
    "development": DevelopmentConfig,
    "testing": TestingConfig,
    "production": ProductionConfig,
}

Extensions

Centralize all Flask extension instances in a single file.

"""Flask extensions initialization."""
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
from flask_marshmallow import Marshmallow
from flask_jwt_extended import JWTManager
from flask_cors import CORS

db = SQLAlchemy()
migrate = Migrate()
ma = Marshmallow()
jwt = JWTManager()
cors = CORS()

Common extensions and their purposes:

ExtensionPurpose
Flask-SQLAlchemyORM and database integration
Flask-MigrateAlembic database migrations
Flask-MarshmallowSerialization and validation
Flask-JWT-ExtendedJWT authentication
Flask-CORSCross-origin resource sharing
Flask-LimiterRate limiting
Flask-CachingResponse and data caching
Flask-MailEmail sending

Error Handling

Define a custom exception hierarchy and register handlers.

"""Custom exceptions and error handlers."""
from flask import jsonify


class AppError(Exception):
    """Base application error."""
    def __init__(self, message: str, status_code: int = 400):
        super().__init__(message)
        self.message = message
        self.status_code = status_code


class NotFoundError(AppError):
    def __init__(self, message: str = "Resource not found"):
        super().__init__(message, status_code=404)


class UnauthorizedError(AppError):
    def __init__(self, message: str = "Unauthorized"):
        super().__init__(message, status_code=401)


class ForbiddenError(AppError):
    def __init__(self, message: str = "Forbidden"):
        super().__init__(message, status_code=403)


class ConflictError(AppError):
    def __init__(self, message: str = "Conflict"):
        super().__init__(message, status_code=409)


def handle_validation_error(error):
    return jsonify({"error": "Validation error", "details": error.messages}), 400


def handle_app_error(error: AppError):
    return jsonify({"error": error.message}), error.status_code


def handle_not_found(error):
    return jsonify({"error": "Not found"}), 404


def handle_internal_error(error):
    return jsonify({"error": "Internal server error"}), 500

Jinja2 Templates

When building server-rendered pages (not just APIs):

  • Templates live in app/templates/ with a base.html layout
  • Use template inheritance: {% extends "base.html" %}
  • Use {% block content %} for page-specific content
  • Escape user content automatically (Jinja2 autoescape is on by default)
  • Use url_for() for all URLs in templates
  • Keep logic out of templates; use filters and context processors
{# app/templates/base.html #}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{% block title %}My App{% endblock %}</title>
</head>
<body>

---

*Content truncated.*

When not to use it

  • When async support is a critical requirement.
  • When a batteries-included framework like Django is preferred.
  • When high-performance async is critical.

Limitations

  • Applies to Flask 3.0+ versions.
  • Focuses on REST APIs, Microservices, and Web Applications.
  • Does not provide async support.

How it compares

This skill offers opinionated architectural patterns and security guidelines specifically for Flask, promoting consistency and maintainability beyond basic Flask usage.

Compared to similar skills

flask side by side with the closest alternatives in the catalog.

SkillInstallsUpdatedSafetyDifficulty
flask (this skill)06moReviewIntermediate
api-development36moNo flagsIntermediate
django-flask-patterns06moNo flagsIntermediate
forms-and-validation04moNo flagsIntermediate

Try saying

Example prompts that trigger this skill in your AI assistant.

Search skills

Search the agent skills registry