Skills flask
install
source · Clone the upstream repo
git clone https://github.com/TerminalSkills/skills
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/TerminalSkills/skills "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/flask" ~/.claude/skills/terminalskills-skills-flask && rm -rf "$T"
manifest:
skills/flask/SKILL.mdsafety · automated scan (medium risk)
This is a pattern-based risk scan, not a security review. Our crawler flagged:
- pip install
- references API keys
Always read a skill's source content before installing. Patterns alone don't mean the skill is malicious — but they warrant attention.
source content
Flask
Flask is a micro web framework for Python. It's minimal by design — you choose your ORM, auth system, and structure. Extensions fill in the gaps.
Installation
# Install Flask pip install flask
Project Structure
# Recommended Flask project layout with blueprints app/ ├── __init__.py # Application factory ├── config.py # Configuration classes ├── models.py # SQLAlchemy models ├── extensions.py # Extension instances ├── auth/ │ ├── __init__.py # Auth blueprint │ ├── routes.py │ └── forms.py ├── main/ │ ├── __init__.py # Main blueprint │ └── routes.py ├── templates/ │ ├── base.html │ └── auth/ └── static/
Application Factory
# app/__init__.py — application factory pattern from flask import Flask from .extensions import db, migrate, login_manager from .config import Config def create_app(config_class=Config): app = Flask(__name__) app.config.from_object(config_class) db.init_app(app) migrate.init_app(app, db) login_manager.init_app(app) from .auth import bp as auth_bp from .main import bp as main_bp app.register_blueprint(auth_bp, url_prefix="/auth") app.register_blueprint(main_bp) return app
# app/extensions.py — extension instances from flask_sqlalchemy import SQLAlchemy from flask_migrate import Migrate from flask_login import LoginManager db = SQLAlchemy() migrate = Migrate() login_manager = LoginManager() login_manager.login_view = "auth.login"
Configuration
# app/config.py — configuration classes import os class Config: SECRET_KEY = os.environ.get("SECRET_KEY", "dev-key") SQLALCHEMY_DATABASE_URI = os.environ.get("DATABASE_URL", "sqlite:///app.db") SQLALCHEMY_TRACK_MODIFICATIONS = False class TestConfig(Config): TESTING = True SQLALCHEMY_DATABASE_URI = "sqlite:///:memory:"
Routes and Blueprints
# app/main/routes.py — main blueprint routes from flask import render_template, request, redirect, url_for, flash, jsonify from flask_login import login_required, current_user from . import bp from ..models import Post from ..extensions import db @bp.route("/") def index(): page = request.args.get("page", 1, type=int) posts = Post.query.order_by(Post.created_at.desc()).paginate(page=page, per_page=20) return render_template("main/index.html", posts=posts) @bp.route("/post", methods=["POST"]) @login_required def create_post(): post = Post(body=request.form["body"], author=current_user) db.session.add(post) db.session.commit() flash("Post created!") return redirect(url_for("main.index"))
# app/main/__init__.py — blueprint definition from flask import Blueprint bp = Blueprint("main", __name__) from . import routes
Models
# app/models.py — SQLAlchemy models from datetime import datetime, UTC from flask_login import UserMixin from .extensions import db, login_manager class User(UserMixin, db.Model): id = db.Column(db.Integer, primary_key=True) username = db.Column(db.String(80), unique=True, nullable=False) email = db.Column(db.String(120), unique=True, nullable=False) password_hash = db.Column(db.String(256)) posts = db.relationship("Post", backref="author", lazy="dynamic") @login_manager.user_loader def load_user(id): return db.session.get(User, int(id)) class Post(db.Model): id = db.Column(db.Integer, primary_key=True) body = db.Column(db.Text, nullable=False) created_at = db.Column(db.DateTime, default=lambda: datetime.now(UTC)) user_id = db.Column(db.Integer, db.ForeignKey("user.id"))
API Routes
# app/api/routes.py — JSON API endpoints from flask import jsonify, request, abort from . import bp from ..models import Post from ..extensions import db @bp.route("/posts") def get_posts(): posts = Post.query.order_by(Post.created_at.desc()).limit(50).all() return jsonify([{"id": p.id, "body": p.body, "author": p.author.username} for p in posts]) @bp.route("/posts", methods=["POST"]) def create_post(): data = request.get_json() if not data or "body" not in data: abort(400) post = Post(body=data["body"], user_id=data["user_id"]) db.session.add(post) db.session.commit() return jsonify({"id": post.id}), 201 @bp.errorhandler(404) def not_found(e): return jsonify(error="Not found"), 404
Templates
<!-- templates/base.html — base template with Jinja2 --> <!DOCTYPE html> <html> <head><title>{% block title %}App{% endblock %}</title></head> <body> <nav> <a href="{{ url_for('main.index') }}">Home</a> {% if current_user.is_authenticated %} <a href="{{ url_for('auth.logout') }}">Logout</a> {% else %} <a href="{{ url_for('auth.login') }}">Login</a> {% endif %} </nav> {% with messages = get_flashed_messages() %} {% for msg in messages %}<div class="flash">{{ msg }}</div>{% endfor %} {% endwith %} {% block content %}{% endblock %} </body> </html>
Error Handling
# app/__init__.py — custom error handlers (add inside create_app) @app.errorhandler(404) def not_found(e): return render_template("errors/404.html"), 404 @app.errorhandler(500) def server_error(e): db.session.rollback() return render_template("errors/500.html"), 500
Testing
# tests/test_main.py — testing Flask app import pytest from app import create_app from app.config import TestConfig from app.extensions import db @pytest.fixture def client(): app = create_app(TestConfig) with app.test_client() as client: with app.app_context(): db.create_all() yield client def test_index(client): resp = client.get("/") assert resp.status_code == 200
Running
# Run development server flask --app app run --debug --port 5000 # Database migrations flask --app app db init flask --app app db migrate -m "Initial" flask --app app db upgrade
Key Patterns
- Always use the application factory pattern for testability
- Use blueprints to organize code by feature
- Initialize extensions separately from
to avoid circular importscreate_app - Use
(Flask-Migrate) for schema changes — neverflask db
in productiondb.create_all() - Access config via
inside request contextcurrent_app.config - Use
from Flask-Login for protected routes@login_required