Flask con Python: crea tu primera aplicación web

Publicado el: 11/07/2026
Tempo de leitura: 4 minutos
Logo do Flask em um fundo branco

Flask es un framework web ligero para Python. Proporciona rutas, manejo de solicitudes, respuestas, plantillas y extensiones sin imponer una estructura excesiva. Es una buena opción para aprender cómo funciona una aplicación web, crear APIs pequeñas, paneles internos y servicios que pueden crecer de manera organizada. “Ligero” no significa incompleto: significa que eliges los componentes adicionales según las necesidades del proyecto.

Antes de comenzar conviene revisar la guía de entornos virtuales, la instalación de paquetes con pip, el uso de funciones en Python, el trabajo con JSON y el manejo de excepciones.

Las fuentes externas principales son la guía rápida oficial de Flask y la documentación oficial de plantillas Jinja.

Crear el entorno del proyecto

mkdir mi_flask_app
cd mi_flask_app
python -m venv .venv

Activa el entorno. En Windows:

.venv\Scripts\activate

En macOS o Linux:

source .venv/bin/activate

Instala Flask:

python -m pip install Flask

Comprueba que el paquete pertenece al intérprete correcto:

python -m pip show Flask

Crear la primera aplicación

Crea un archivo llamado app.py:

from flask import Flask

app = Flask(__name__)


@app.get("/")
def inicio():
    return "Hola desde Flask"

Ejecuta el servidor de desarrollo:

flask --app app run --debug

Abre la dirección indicada en la terminal. El modo debug recarga el código y muestra información detallada de errores. No debe utilizarse en producción porque expone herramientas peligrosas si se publica incorrectamente.

Qué significa __name__

Flask(__name__) ayuda al framework a localizar recursos asociados al módulo, como plantillas y archivos estáticos. No reemplaces este valor por una cadena arbitraria sin comprender cómo afecta las rutas internas.

Crear rutas

@app.get("/acerca")
def acerca():
    return "Aplicación creada con Python y Flask"

Cada decorador asocia una URL y un método HTTP con una función. Las funciones deben devolver una respuesta válida, como texto, HTML, JSON o un objeto de respuesta.

Rutas con parámetros

from markupsafe import escape


@app.get("/usuario/<nombre>")
def usuario(nombre):
    return f"Hola, {escape(nombre)}"

escape evita interpretar como HTML el contenido recibido. En plantillas Jinja, el autoescape suele proteger el HTML, pero no debes desactivarlo sin una razón clara.

Convertidores de ruta

@app.get("/producto/<int:producto_id>")
def producto(producto_id):
    return {"id": producto_id}

El convertidor int valida que el segmento sea entero. Flask devolverá una respuesta de ruta no encontrada si el valor no coincide.

Devolver JSON

@app.get("/api/estado")
def estado():
    return {
        "servicio": "academia",
        "activo": True,
    }

Flask convierte diccionarios en JSON. Para respuestas más explícitas puedes usar jsonify y definir el código de estado:

from flask import jsonify


@app.get("/api/usuarios/<int:usuario_id>")
def obtener_usuario(usuario_id):
    if usuario_id != 1:
        return jsonify({"error": "No encontrado"}), 404
    return jsonify({"id": 1, "nombre": "Ana"})

Recibir parámetros de consulta

from flask import request


@app.get("/buscar")
def buscar():
    termino = request.args.get("q", "").strip()
    limite = request.args.get("limite", default=10, type=int)

    if not termino:
        return {"error": "Falta el parámetro q"}, 400

    return {"consulta": termino, "limite": limite}

No confíes en la entrada del usuario. Valida longitud, tipo y formato antes de usarla en consultas o archivos.

Procesar formularios POST

@app.post("/contacto")
def contacto():
    nombre = request.form.get("nombre", "").strip()
    email = request.form.get("email", "").strip()

    if not nombre or not email:
        return "Datos incompletos", 400

    return "Mensaje recibido", 201

Para formularios reales añade protección CSRF mediante una extensión adecuada. El método POST no protege por sí mismo contra solicitudes maliciosas.

Recibir JSON

@app.post("/api/tareas")
def crear_tarea():
    datos = request.get_json(silent=True)

    if not isinstance(datos, dict):
        return {"error": "JSON inválido"}, 400

    titulo = str(datos.get("titulo", "")).strip()
    if not titulo:
        return {"error": "El título es obligatorio"}, 400

    return {"id": 1, "titulo": titulo}, 201

silent=True evita una excepción automática, pero debes responder explícitamente cuando el cuerpo no sea válido.

Usar plantillas HTML

Crea una carpeta templates y un archivo inicio.html:

<!doctype html>
<html lang="es">
<head>
  <meta charset="utf-8">
  <title>{{ titulo }}</title>
</head>
<body>
  <h1>{{ titulo }}</h1>
  <p>Bienvenido, {{ usuario }}.</p>
</body>
</html>

En Python:

from flask import render_template


@app.get("/")
def inicio():
    return render_template(
        "inicio.html",
        titulo="Mi aplicación Flask",
        usuario="Ana",
    )

Jinja escapa variables en plantillas HTML. Evita utilizar el filtro safe con contenido suministrado por usuarios.

Condiciones y bucles en Jinja

<ul>
{% for tarea in tareas %}
  <li>{{ tarea }}</li>
{% else %}
  <li>No hay tareas</li>
{% endfor %}
</ul>

La lógica compleja debe permanecer en Python. Las plantillas deberían concentrarse en presentar datos.

Archivos estáticos

Coloca CSS, JavaScript e imágenes propias en la carpeta static:

<link
  rel="stylesheet"
  href="{{ url_for('static', filename='css/estilos.css') }}"
>

url_for genera rutas correctas y evita escribir direcciones rígidas.

Redirecciones y URLs

from flask import redirect, url_for


@app.post("/guardar")
def guardar():
    return redirect(url_for("inicio"))

Utiliza el nombre de la función de vista, no una URL escrita manualmente. Esto facilita cambiar rutas sin romper enlaces internos.

Manejar errores

@app.errorhandler(404)
def no_encontrado(error):
    return render_template("404.html"), 404


@app.errorhandler(500)
def error_interno(error):
    return render_template("500.html"), 500

No muestres el traceback al visitante. Registra el error de forma privada y devuelve un mensaje seguro.

Configuración y secretos

import os

app.config["SECRET_KEY"] = os.environ.get("SECRET_KEY")

if not app.config["SECRET_KEY"]:
    raise RuntimeError("Falta SECRET_KEY")

No incluyas una clave real en el código. La clave secreta protege firmas de sesión y debe ser larga, aleatoria y diferente por entorno.

Organizar un proyecto mayor

mi_flask_app/
├── app/
│   ├── __init__.py
│   ├── routes.py
│   ├── templates/
│   └── static/
├── tests/
├── config.py
└── requirements.txt

Una factoría de aplicación facilita pruebas:

from flask import Flask


def create_app(test_config=None):
    app = Flask(__name__)
    app.config.from_mapping(SECRET_KEY="desarrollo")

    if test_config:
        app.config.update(test_config)

    @app.get("/")
    def inicio():
        return "OK"

    return app

La clave de desarrollo del ejemplo nunca debe llegar a producción.

Probar la aplicación

def test_inicio():
    app = create_app({"TESTING": True})
    cliente = app.test_client()

    respuesta = cliente.get("/")

    assert respuesta.status_code == 200
    assert respuesta.data == b"OK"

El cliente de pruebas realiza solicitudes sin iniciar un servidor real. Añade pruebas para errores, JSON inválido, permisos y límites.

Base de datos

Para un proyecto pequeño puedes comenzar con SQLite. Utiliza consultas parametrizadas o un ORM; nunca construyas SQL concatenando entrada del usuario. Gestiona transacciones y cierra conexiones incluso cuando ocurre una excepción.

Despliegue

El servidor incluido es solo para desarrollo. En producción usa un servidor WSGI compatible, un proxy cuando corresponda, HTTPS, variables de entorno y logging. Define límites de tamaño, timeouts y políticas de actualización. No publiques el depurador.

Errores frecuentes

Los problemas habituales son ejecutar con debug en producción, guardar secretos en el repositorio, confiar en formularios sin validar, concatenar SQL, desactivar el autoescape y colocar toda la aplicación en un solo archivo. También es frecuente instalar Flask en un entorno y ejecutar otro intérprete.

Conclusión

Flask permite aprender desarrollo web construyendo rutas, respuestas JSON, formularios y plantillas con una base pequeña. Empieza con un entorno virtual y una aplicación mínima, valida toda entrada y separa configuración, vistas y lógica. Cuando el proyecto crezca, utiliza factorías, blueprints, pruebas y un servidor de producción adecuado.

Compartilhe:

Facebook
WhatsApp
Twitter
LinkedIn

Contenido del artículo

    Artículos relacionados

    Como consumir APIs REST com Python em poucos minutos
    Desarrollo Web
    Foto de perfil de Leandro Hirt da Academify

    Cómo consumir APIs REST con Python y Requests

    Consume APIs REST con Python y Requests: GET, POST, JSON, autenticación, timeouts, sesiones, paginación, streaming y reintentos.

    Ler mais

    Tempo de leitura: 4 minutos
    11/07/2026
    Criação de servidor HTTP simples usando Python
    Desarrollo Web
    Foto de perfil de Leandro Hirt da Academify

    Servidor HTTP simple en Python: guía práctica

    Aprende a crear un servidor HTTP simple en Python, cambiar puertos, compartir archivos en red y evitar riesgos en producción.

    Ler mais

    Tempo de leitura: 5 minutos
    11/07/2026
    logo da FastAPI
    Desarrollo Web
    Foto de perfil de Leandro Hirt da Academify

    FastAPI en Python: crea APIs modernas paso a paso

    Aprende FastAPI en Python: rutas, Pydantic, validación, autenticación, dependencias, bases de datos y despliegue de APIs modernas.

    Ler mais

    Tempo de leitura: 5 minutos
    11/07/2026
    texto escrito "o que é Django", com a logo do Django
    Desarrollo Web
    Foto de perfil de Leandro Hirt da Academify

    Django en Python: guía para crear aplicaciones web

    Aprende Django en Python: arquitectura MVT, instalación, modelos, administrador, seguridad, APIs y despliegue con ejemplos prácticos.

    Ler mais

    Tempo de leitura: 5 minutos
    11/07/2026
    Execução de Python no navegador usando PyScript
    Desarrollo Web
    Foto de perfil de Leandro Hirt da Academify

    PyScript en Python: ejecuta código en el navegador

    Aprende a usar PyScript para ejecutar Python en el navegador, interactuar con HTML, validar formularios, cargar paquetes y entender sus

    Ler mais

    Tempo de leitura: 6 minutos
    11/07/2026
    Automação web com Selenium usando Python
    Automatización y ScriptsDesarrollo Web
    Foto de perfil de Leandro Hirt da Academify

    Selenium con Python: automatización web completa

    Aprende Selenium con Python para controlar navegadores, localizar elementos, usar esperas, completar formularios, tomar capturas y crear pruebas fiables.

    Ler mais

    Tempo de leitura: 5 minutos
    11/07/2026