{"id":7035,"date":"2025-09-11T19:55:28","date_gmt":"2025-09-11T17:55:28","guid":{"rendered":"https:\/\/www.hostingtg.com\/blog\/?p=7035"},"modified":"2025-09-11T19:55:31","modified_gmt":"2025-09-11T17:55:31","slug":"python-y-flask","status":"publish","type":"post","link":"https:\/\/www.hostingtg.com\/blog\/python-y-flask\/","title":{"rendered":"Python y Flask: gu\u00eda pr\u00e1ctica para crear y desplegar tu primera app"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">Qu\u00e9 es Flask<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Flask es, en mis palabras, <strong>un microframework web en Python<\/strong> con un n\u00facleo peque\u00f1o y muy f\u00e1cil de extender. A diferencia de frameworks \u201cbater\u00edas incluidas\u201d, <strong>no trae ORM por defecto<\/strong> ni decisiones r\u00edgidas sobre c\u00f3mo estructurar tu proyecto; t\u00fa eliges piezas como <strong>SQLAlchemy<\/strong>, <strong>Marshmallow<\/strong> o lo que prefieras. En mi caso, esta ligereza me permite arrancar una idea en minutos y solo a\u00f1adir lo que necesito.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Flask funciona sobre <strong>WSGI<\/strong> (la interfaz est\u00e1ndar para apps web en Python). Por debajo usa <strong>Werkzeug<\/strong> para la parte WSGI\/routing y <strong>Jinja2<\/strong> como motor de plantillas: justo las dos caracter\u00edsticas que m\u00e1s suelo destacar cuando explico Flask a alguien nuevo. Hist\u00f3ricamente, el proyecto fue creado por <strong>Armin Ronacher<\/strong> dentro del grupo <strong>Pocoo<\/strong>, y esa filosof\u00eda minimalista pero potente se mantiene hasta hoy.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>\u00bfCu\u00e1ndo elegir Flask?<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Si quieres <strong>control fino<\/strong> sobre tu stack (ORM opcional, autenticaci\u00f3n a tu gusto, etc.).<\/li>\n\n\n\n<li>Para <strong>APIs y prototipos<\/strong> r\u00e1pidos.<\/li>\n\n\n\n<li>Si prefieres aprender los conceptos web base (WSGI, routing, plantillas) sin que el framework lo oculte.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>\u00bfCu\u00e1ndo no?<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Cuando quieras un ecosistema \u201ctodo hecho\u201d desde el d\u00eda 1 (p. ej., un admin autom\u00e1tico). En ese caso, compara con Django o FastAPI seg\u00fan tu caso de uso.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Requisitos previos y entorno de trabajo<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Antes de escribir c\u00f3digo, prepara entorno y dependencias.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Checklist r\u00e1pido<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Python 3.10+ instalado.<\/li>\n\n\n\n<li><strong>venv<\/strong> para aislar paquetes.<\/li>\n\n\n\n<li>Editor (VS Code \/ PyCharm) con extensiones de Python.<\/li>\n\n\n\n<li>Git y una cuenta en GitHub o GitLab (opcional pero recomendable).<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Crear y activar <em>venv<\/em> (Windows \/ macOS \/ Linux)<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code># Crea la carpeta del proyecto\nmkdir mi-flask-app &amp;&amp; cd mi-flask-app\n\n# Crea un entorno virtual\npython -m venv .venv\n\n# Activa el entorno\n# Windows (PowerShell)\n.venv\\Scripts\\Activate.ps1\n# macOS \/ Linux\nsource .venv\/bin\/activate\n\n# Instala Flask\npip install flask\npip freeze &gt; requirements.txt\n<\/code><\/pre>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">Nota de experiencia: al ser un <strong>microframework<\/strong>, Flask no incluye ORM ni capas extra; esa simplicidad hace que el <em>venv<\/em> y el <code>requirements.txt<\/code> sean tu \u201ccontrato\u201d de dependencias desde el primer minuto.<\/p>\n<\/blockquote>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Paso 1 \u2014 Tu primera aplicaci\u00f3n en Flask<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Crea un archivo <code>app.py<\/code> con la m\u00ednima app funcional:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>from flask import Flask, render_template\n\napp = Flask(__name__)\n\n@app.route(\"\/\")\ndef home():\n    return \"\u00a1Hola Flask! &#x1f680;\"\n\nif __name__ == \"__main__\":\n    app.run(debug=True)\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Ejecuta:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>flask --app app run\n# o bien\npython app.py\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Rutas, respuestas y <em>debug<\/em> seguro<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Rutas<\/strong>: En Flask defines rutas con <code>@app.route<\/code>. Esa <strong>facilidad de enrutamiento<\/strong> es una de las funciones que m\u00e1s valoro; te deja mapear URL a funciones de forma muy legible.<\/li>\n\n\n\n<li><strong>Respuestas<\/strong>: puedes devolver texto plano, JSON (<code>return {\"ok\": True}<\/code>) o plantillas HTML.<\/li>\n\n\n\n<li><strong>Debug<\/strong>: <code>debug=True<\/code> es c\u00f3modo en local, pero <strong>desact\u00edvalo en producci\u00f3n<\/strong> para no exponer informaci\u00f3n sensible.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Plantillas con Jinja2: layout y bloques<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Crea la carpeta <code>templates\/<\/code> y un layout base:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>templates\/base.html<\/code><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;!doctype html&gt;\n&lt;html lang=\"es\"&gt;\n&lt;head&gt;\n  &lt;meta charset=\"utf-8\" \/&gt;\n  &lt;title&gt;{% block title %}Mi Flask App{% endblock %}&lt;\/title&gt;\n  &lt;link rel=\"stylesheet\" href=\"{{ url_for('static', filename='styles.css') }}\"&gt;\n&lt;\/head&gt;\n&lt;body&gt;\n  &lt;header&gt;&lt;h1&gt;Mi Flask App&lt;\/h1&gt;&lt;\/header&gt;\n  &lt;main&gt;\n    {% block content %}{% endblock %}\n  &lt;\/main&gt;\n  &lt;footer&gt;&lt;small&gt;Powered by Flask&lt;\/small&gt;&lt;\/footer&gt;\n&lt;\/body&gt;\n&lt;\/html&gt;\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><code>templates\/home.html<\/code><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>{% extends \"base.html\" %}\n{% block title %}Inicio{% endblock %}\n{% block content %}\n  &lt;h2&gt;Bienvenido&lt;\/h2&gt;\n  &lt;p&gt;Renderizado con Jinja2.&lt;\/p&gt;\n{% endblock %}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Y en <code>app.py<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>@app.route(\"\/bienvenida\")\ndef bienvenida():\n    return render_template(\"home.html\")\n<\/code><\/pre>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">En mi experiencia, <strong>Jinja2<\/strong> junto con el <strong>routing<\/strong> de <a href=\"https:\/\/flask.palletsprojects.com\/en\/stable\/\" target=\"_blank\" data-type=\"link\" data-id=\"https:\/\/flask.palletsprojects.com\/en\/stable\/\" rel=\"noreferrer noopener\">Flask<\/a> es lo que te permite pasar de un \u201chola mundo\u201d a p\u00e1ginas reales sin fricci\u00f3n. Plantillas limpias y herencia de layouts = desarrollo m\u00e1s r\u00e1pido.<\/p>\n<\/blockquote>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Paso 2 \u2014 Persistencia m\u00ednima: SQLite + (opcional) SQLAlchemy<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Puedes empezar con <strong>SQLite<\/strong> para no complicarte.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>pip install sqlalchemy\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">models.py<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>from sqlalchemy import create_engine, Column, Integer, String\nfrom sqlalchemy.orm import declarative_base, sessionmaker\n\nengine = create_engine(\"sqlite:\/\/\/app.db\", echo=False, future=True)\nBase = declarative_base()\nSessionLocal = sessionmaker(bind=engine, autoflush=False, autocommit=False)\n\nclass Nota(Base):\n    __tablename__ = \"notas\"\n    id = Column(Integer, primary_key=True)\n    titulo = Column(String(120), nullable=False)\n\ndef init_db():\n    Base.metadata.create_all(engine)\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><code>app.py<\/code> (extracto)<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>from flask import Flask, request, redirect, url_for, render_template\nfrom models import SessionLocal, init_db, Nota\n\napp = Flask(__name__)\ninit_db()\n\n@app.route(\"\/notas\", methods=&#91;\"GET\", \"POST\"])\ndef notas():\n    db = SessionLocal()\n    if request.method == \"POST\":\n        titulo = request.form.get(\"titulo\")\n        if titulo:\n            db.add(Nota(titulo=titulo))\n            db.commit()\n        return redirect(url_for(\"notas\"))\n    data = db.query(Nota).all()\n    db.close()\n    return render_template(\"notas.html\", notas=data)\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">templates\/notas.html<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>{% extends \"base.html\" %}\n{% block title %}Notas{% endblock %}\n{% block content %}\n  &lt;h2&gt;Notas&lt;\/h2&gt;\n  &lt;form method=\"post\"&gt;\n    &lt;input name=\"titulo\" placeholder=\"T\u00edtulo de la nota\" required \/&gt;\n    &lt;button type=\"submit\"&gt;Crear&lt;\/button&gt;\n  &lt;\/form&gt;\n  &lt;ul&gt;\n    {% for n in notas %}\n      &lt;li&gt;{{ n.id }} \u2014 {{ n.titulo }}&lt;\/li&gt;\n    {% endfor %}\n  &lt;\/ul&gt;\n{% endblock %}\n<\/code><\/pre>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">Aqu\u00ed retomo tu idea: <strong>Flask no impone ORM<\/strong>. Puedes usar SQLAlchemy, consultas raw o incluso otro backend. Esa libertad es una se\u00f1a de identidad del framework.<\/p>\n<\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Buenas pr\u00e1cticas r\u00e1pidas<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Variables de entorno para secretos (p. ej., <code>FLASK_SECRET_KEY<\/code>).<\/li>\n\n\n\n<li>Validar entradas (formularios) y manejar errores (400\/404\/500).<\/li>\n\n\n\n<li>Estructurar en paquetes: <code>app\/<\/code>, <code>app\/routes\/<\/code>, <code>app\/templates\/<\/code>, etc.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Paso 3 \u2014 Despliegue sencillo<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Hosting\/cPanel: app WSGI lista para producci\u00f3n<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Si usas hosting con cPanel o similar:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Crea un <em>virtualenv<\/em> en el servidor e instala dependencias (<code>pip install -r requirements.txt<\/code>).<\/li>\n\n\n\n<li>Crea un archivo <code>wsgi.py<\/code><\/li>\n<\/ol>\n\n\n\n<pre class=\"wp-block-code\"><code>from app import app as application\n<\/code><\/pre>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Configura la aplicaci\u00f3n Python (en cPanel: <strong>Setup Python App<\/strong>) apuntando a tu <code>wsgi.py<\/code>.<\/li>\n\n\n\n<li>Usa un <strong>servidor WSGI<\/strong> en producci\u00f3n (Gunicorn\/uwsgi) detr\u00e1s de Nginx\/Apache. Evita el server de desarrollo.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Variables de entorno<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Configura <code>FLASK_ENV=production<\/code> y tu <code>SECRET_KEY<\/code>.<\/li>\n\n\n\n<li>Gestiona <code>.env<\/code> con <code>python-dotenv<\/code> si lo prefieres.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Easypanel en VPS (Hosting TG): Nixpacks vs Dockerfile<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">En <strong>Hosting TG<\/strong> cont\u00e1is con <strong><a href=\"https:\/\/www.hostingtg.com\/servidores-vps\/\" target=\"_blank\" rel=\"noreferrer noopener\">VPS con Easypanel<\/a><\/strong> donde <strong>puedes instalar Python y Flask con apenas unos clics<\/strong> desde <strong>Servicios \u2192 Aplicaci\u00f3n<\/strong>. Eso acelera much\u00edsimo el <em>time-to-deploy<\/em>.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/www.hostingtg.com\/blog\/wp-content\/uploads\/2025\/09\/instalar-flask.webp\"><img fetchpriority=\"high\" decoding=\"async\" width=\"900\" height=\"283\" src=\"https:\/\/www.hostingtg.com\/blog\/wp-content\/uploads\/2025\/09\/instalar-flask.webp\" alt=\"instalar flask\" class=\"wp-image-7038\" title=\"\"><\/a><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Opci\u00f3n A \u2014 Nixpacks (cero Dockerfile)<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Crea una app en Easypanel \u2192 <strong>Servicios \u2192 Aplicaci\u00f3n<\/strong> \u2192 elige tu repo.<\/li>\n\n\n\n<li>Easypanel detecta Python y genera la build.<\/li>\n\n\n\n<li>Define el comando de ejecuci\u00f3n (p. ej., <code>gunicorn -w 2 -b 0.0.0.0:8000 app:app<\/code>).<\/li>\n\n\n\n<li>A\u00f1ade <strong>variables de entorno<\/strong> (SECRET_KEY, DB_URL).<\/li>\n\n\n\n<li>Exp\u00f3n el puerto y activa HTTPS con un clic.<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/www.hostingtg.com\/blog\/wp-content\/uploads\/2025\/09\/flask-easypanel.webp\"><img decoding=\"async\" width=\"900\" height=\"522\" src=\"https:\/\/www.hostingtg.com\/blog\/wp-content\/uploads\/2025\/09\/flask-easypanel.webp\" alt=\"flask easypanel\" class=\"wp-image-7039\" title=\"\"><\/a><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Opci\u00f3n B \u2014 Dockerfile (control total)<\/strong><br><code>Dockerfile<\/code><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>FROM python:3.12-slim\nWORKDIR \/app\nENV PYTHONDONTWRITEBYTECODE=1 PYTHONUNBUFFERED=1\nCOPY requirements.txt .\nRUN pip install --no-cache-dir -r requirements.txt\nCOPY . .\nCMD &#91;\"gunicorn\",\"-w\",\"2\",\"-b\",\"0.0.0.0:8000\",\"app:app\"]\n<\/code><\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Sube la imagen o conecta el repo; Easypanel construye y despliega.<\/li>\n\n\n\n<li>Recomendado si necesitas <strong>builds reproducibles<\/strong> o dependencias del sistema.<\/li>\n<\/ul>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">Experiencia personal: como <strong>Flask es WSGI<\/strong> y su n\u00facleo es peque\u00f1o, encaja perfecto con ambos flujos. Si vienes de \u201cprobar ideas r\u00e1pido\u201d, Nixpacks te deja en producci\u00f3n en minutos; si necesitas ajustes finos, Dockerfile es tu amigo.<\/p>\n<\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Checklist de producci\u00f3n<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Server WSGI (Gunicorn\/uwsgi), no <code>flask run<\/code>.<\/li>\n\n\n\n<li>Logs y monitoreo (healthchecks, alerts).<\/li>\n\n\n\n<li>HTTPS habilitado.<\/li>\n\n\n\n<li>Backups autom\u00e1ticos (si usas SQLite, respalda el archivo; si usas Postgres, snapshots).<\/li>\n\n\n\n<li>Variables de entorno seguras y rotadas.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Extensiones \u00fatiles y estructura de proyecto<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Extensiones populares<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Flask-Login<\/strong> (autenticaci\u00f3n), <strong>Flask-WTF<\/strong> (formularios), <strong>Flask-Migrate<\/strong> (migraciones con Alembic), <strong>Flask-Caching<\/strong> (cach\u00e9), <strong>Flask-CORS<\/strong> (APIs).<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Estructura sugerida<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>mi-flask-app\/\n  app\/\n    __init__.py\n    routes\/\n      __init__.py\n      web.py\n      api.py\n    templates\/\n    static\/\n    models.py\n    config.py\n  tests\/\n  requirements.txt\n  wsgi.py\n  Dockerfile\n  .env\n<\/code><\/pre>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">Como <strong>Flask es un microframework<\/strong>, la estructura no es impuesta. Yo recomiendo separar rutas web\/API, plantillas y modelos para crecer sin dolor.<\/p>\n<\/blockquote>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Errores comunes y c\u00f3mo evitarlos<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Usar el servidor de desarrollo en producci\u00f3n.<\/strong> Soluci\u00f3n: Gunicorn\/uwsgi + Nginx\/Apache.<\/li>\n\n\n\n<li><strong>Dejar <code>DEBUG=True<\/code><\/strong> en producci\u00f3n. Soluci\u00f3n: variable de entorno y <code>DEBUG=False<\/code>.<\/li>\n\n\n\n<li><strong>No versionar requisitos.<\/strong> Soluci\u00f3n: <code>pip freeze &gt; requirements.txt<\/code> y revisiones peri\u00f3dicas.<\/li>\n\n\n\n<li><strong>Olvidar variables de entorno<\/strong> (secretos en el c\u00f3digo). Soluci\u00f3n: <code>.env<\/code> + gestor de secretos del proveedor.<\/li>\n\n\n\n<li><strong>No probar migraciones<\/strong>. Soluci\u00f3n: <code>Flask-Migrate<\/code> y un ciclo <em>staging \u2192 prod<\/em>.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Sobre Flask<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Flask te da <strong>velocidad<\/strong> sin encadenarte a un stack r\u00edgido. Con un par de rutas y <strong>Jinja2<\/strong> levantas una web usable; a\u00f1ades <strong>SQLite\/SQLAlchemy<\/strong> para persistir y, cuando toque, la llevas a <strong>producci\u00f3n<\/strong> con un servidor WSGI. Si adem\u00e1s tienes <strong>VPS con Easypanel en Hosting TG<\/strong>, el paso de \u201cmi idea funciona\u201d a \u201cmi idea est\u00e1 online con HTTPS\u201d son literalmente unos clics (Servicios \u2192 Aplicaci\u00f3n), y eso \u2014cr\u00e9eme\u2014 marca la diferencia.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">FAQs<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>\u00bfEn qu\u00e9 se diferencia Flask de Django o FastAPI?<\/strong><br>Flask es minimalista y WSGI; Django es \u201cbater\u00edas incluidas\u201d; FastAPI (ASGI) est\u00e1 muy orientado a APIs de alto rendimiento y <em>type hints<\/em>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>\u00bfNecesito un ORM con Flask?<\/strong><br>No. Puedes usar SQLAlchemy o consultas SQL directas. La gracia de Flask es que <strong>no impone<\/strong>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>\u00bfC\u00f3mo paso de <code>flask run<\/code> a producci\u00f3n?<\/strong><br>Usa un servidor WSGI (Gunicorn\/uwsgi) detr\u00e1s de Nginx\/Apache. En Easypanel, configura el comando de arranque y variables de entorno.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>\u00bfC\u00f3mo organizo un proyecto para crecer?<\/strong><br>Separa <code>routes<\/code> (web\/API), plantillas, modelos y configuraci\u00f3n. A\u00f1ade tests, migraciones y un CI simple.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Opini\u00f3n Personal<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Confieso que, despu\u00e9s de probar de todo, sigo volviendo a <strong>Flask<\/strong> cuando quiero ir de la idea al \u201conline\u201d sin fricci\u00f3n. Su filosof\u00eda de <em>microframework<\/em> me parece honesta: n\u00facleo peque\u00f1o, decisiones m\u00ednimas y libertad total para elegir ORM, autenticaci\u00f3n o estructura. Esa combinaci\u00f3n\u2014<strong>routing<\/strong> claro y <strong>Jinja2<\/strong> para plantillas\u2014me ha dado m\u00e1s velocidad real que muchos \u201ctodo en uno\u201d. \u00bfEl precio? Asumir responsabilidad: t\u00fa decides el stack y eso exige criterio.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A nivel pr\u00e1ctico, mi receta ganadora es simple: <strong>venv<\/strong>, dependencias ordenadas, <strong>SQLite\/SQLAlchemy<\/strong> para empezar y un servidor <strong>WSGI<\/strong> en producci\u00f3n (nada de <code>flask run<\/code>). Y si hablamos de despliegue, tener <strong>VPS con Easypanel<\/strong> es un cambio de juego: en <strong>Hosting TG<\/strong>, desde <em>Servicios \u2192 Aplicaci\u00f3n<\/em> levanto la app, configuro variables y activo HTTPS en minutos. Para prototipos o MVPs, esa rapidez pesa m\u00e1s que cualquier benchmark.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u00bfEs Flask perfecto? No. Si buscas un admin de f\u00e1brica o una arquitectura r\u00edgida, quiz\u00e1 te compense Django. Pero si valoras el control y aprender los cimientos web \u2014sin capas que oculten c\u00f3mo funciona todo\u2014, Flask es una apuesta s\u00f3lida y, sobre todo, <strong>sostenible<\/strong> a medio plazo.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Ahora te toca: \u00bfpor qu\u00e9 eliges t\u00fa Flask (o por qu\u00e9 no)? \u00bfQu\u00e9 te ha funcionado mejor en despliegues: Nixpacks o Dockerfile? <strong>D\u00e9jame tus dudas y experiencias en los comentarios; te leo y respondo.<\/strong><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Qu\u00e9 es Flask Flask es, en mis palabras, un microframework web en Python con un n\u00facleo peque\u00f1o y muy f\u00e1cil de extender. A diferencia de frameworks \u201cbater\u00edas incluidas\u201d, no trae ORM por defecto ni decisiones r\u00edgidas sobre c\u00f3mo estructurar tu proyecto; t\u00fa eliges piezas como SQLAlchemy, Marshmallow o lo que prefieras. En mi caso, esta [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":7037,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_aifi_custom_prompt":"","site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"default","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","ast-disable-related-posts":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"set","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":""},"categories":[952],"tags":[1089,1092,779,1090],"class_list":["post-7035","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-guias","tag-flask","tag-java","tag-linux","tag-python"],"_links":{"self":[{"href":"https:\/\/www.hostingtg.com\/blog\/wp-json\/wp\/v2\/posts\/7035","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.hostingtg.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.hostingtg.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.hostingtg.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.hostingtg.com\/blog\/wp-json\/wp\/v2\/comments?post=7035"}],"version-history":[{"count":2,"href":"https:\/\/www.hostingtg.com\/blog\/wp-json\/wp\/v2\/posts\/7035\/revisions"}],"predecessor-version":[{"id":7040,"href":"https:\/\/www.hostingtg.com\/blog\/wp-json\/wp\/v2\/posts\/7035\/revisions\/7040"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.hostingtg.com\/blog\/wp-json\/wp\/v2\/media\/7037"}],"wp:attachment":[{"href":"https:\/\/www.hostingtg.com\/blog\/wp-json\/wp\/v2\/media?parent=7035"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.hostingtg.com\/blog\/wp-json\/wp\/v2\/categories?post=7035"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.hostingtg.com\/blog\/wp-json\/wp\/v2\/tags?post=7035"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}