¿Que es Flask?
Flask es un framework web WSGI ligero en Python. Esta disenado para ser simple y facil de extender, dandote la flexibilidad de estructurar tu aplicacion como quieras. Flask a menudo se llama un "micro-framework" porque no incluye un ORM, validacion de formularios u otras caracteristicas que muchos frameworks proporcionan por defecto. En su lugar, tu eliges y agregas extensiones segun las necesites.
Hello World
# Install Flask
# pip install flask
# app.py
from flask import Flask, jsonify, request, render_template
app = Flask(__name__)
@app.route("/")
def hello():
return "Hello, World!"
@app.route("/api/greeting")
def api_greeting():
name = request.args.get("name", "World")
return jsonify({"message": f"Hello, {name}!"})
if __name__ == "__main__":
app.run(debug=True)
# Run: python app.py
# Or: flask --app app run --debug
Enrutamiento y metodos HTTP
from flask import Flask, jsonify, request, abort
app = Flask(__name__)
# In-memory storage for demo
todos = [
{"id": 1, "title": "Learn Flask", "done": False},
{"id": 2, "title": "Build API", "done": False},
]
next_id = 3
# GET all todos
@app.route("/api/todos", methods=["GET"])
def get_todos():
return jsonify(todos)
# GET single todo
@app.route("/api/todos/", methods=["GET"])
def get_todo(todo_id):
todo = next((t for t in todos if t["id"] == todo_id), None)
if not todo:
abort(404)
return jsonify(todo)
# POST create todo
@app.route("/api/todos", methods=["POST"])
def create_todo():
global next_id
if not request.json or "title" not in request.json:
abort(400)
todo = {
"id": next_id,
"title": request.json["title"],
"done": False,
}
next_id += 1
todos.append(todo)
return jsonify(todo), 201
# PUT update todo
@app.route("/api/todos/", methods=["PUT"])
def update_todo(todo_id):
todo = next((t for t in todos if t["id"] == todo_id), None)
if not todo:
abort(404)
data = request.json
todo["title"] = data.get("title", todo["title"])
todo["done"] = data.get("done", todo["done"])
return jsonify(todo)
# DELETE todo
@app.route("/api/todos/", methods=["DELETE"])
def delete_todo(todo_id):
global todos
todos = [t for t in todos if t["id"] != todo_id]
return "", 204
Blueprints para organizacion
# Blueprints help organize large Flask applications
# auth/routes.py
from flask import Blueprint, jsonify, request
auth_bp = Blueprint("auth", __name__, url_prefix="/auth")
@auth_bp.route("/login", methods=["POST"])
def login():
data = request.json
# Authenticate user...
return jsonify({"token": "jwt-token-here"})
@auth_bp.route("/register", methods=["POST"])
def register():
data = request.json
# Create user...
return jsonify({"message": "User created"}), 201
# products/routes.py
from flask import Blueprint, jsonify
products_bp = Blueprint("products", __name__, url_prefix="/products")
@products_bp.route("/")
def list_products():
return jsonify([{"id": 1, "name": "Widget"}])
# app.py - register blueprints
from flask import Flask
# from auth.routes import auth_bp
# from products.routes import products_bp
app = Flask(__name__)
# app.register_blueprint(auth_bp)
# app.register_blueprint(products_bp)
Manejo de errores y middleware
from flask import Flask, jsonify
from werkzeug.exceptions import HTTPException
app = Flask(__name__)
# Custom error handlers
@app.errorhandler(404)
def not_found(error):
return jsonify({"error": "Resource not found"}), 404
@app.errorhandler(400)
def bad_request(error):
return jsonify({"error": "Bad request"}), 400
@app.errorhandler(500)
def internal_error(error):
return jsonify({"error": "Internal server error"}), 500
# Catch all HTTP exceptions
@app.errorhandler(HTTPException)
def handle_exception(e):
return jsonify({"error": e.description, "code": e.code}), e.code
# Before/after request hooks (middleware)
@app.before_request
def log_request():
print(f"{request.method} {request.path}")
@app.after_request
def add_cors_headers(response):
response.headers["Access-Control-Allow-Origin"] = "*"
response.headers["Access-Control-Allow-Methods"] = "GET, POST, PUT, DELETE"
return response
# Configuration
app.config["SECRET_KEY"] = "your-secret-key"
app.config["DEBUG"] = True
# Or from a config file/object
class Config:
SECRET_KEY = "your-secret-key"
SQLALCHEMY_DATABASE_URI = "sqlite:///app.db"
app.config.from_object(Config)
Flask vs Django vs FastAPI
- Flask: Maxima flexibilidad, opiniones minimas, excelente para APIs y aplicaciones pequenas-medianas
- Django: Baterias incluidas, excelente para aplicaciones web full-stack con paneles de admin
- FastAPI: Mejor para APIs REST modernas, soporte async, validacion y documentacion automatica