Saltar al contenido principal

Python FastHTML: Guía para principiantes con ejemplos

Conoce FastHTML, una biblioteca de Python para crear páginas web dinámicas. Incluye ejemplos de aplicación en el mundo real.
Actualizado 13 jun 2025  · 15 min de lectura

Construir interfaces web modernas en Python a menudo significa hacer malabarismos con múltiples capas, motores de plantillas, herramientas JavaScript y frameworks front-end, sólo para conseguir que funcione una interfaz de usuario básica. FastHTML ofrece un enfoque más centrado: un marco de trabajo mínimo, basado en Python, que simplifica el desarrollo permitiéndote definir interfaces directamente en el código, sin necesidad de abandonar el lenguaje ni gestionar una complejidad adicional.

Este artículo explica cómo funciona FastHTML, sus principios básicos de diseño y cómo crear aplicaciones reales con él, desde páginas sencillas hasta interfaces totalmente interactivas basadas en datos.

Si quieres reforzar tu base de desarrollo de backend antes de sumergirte en él, te recomiendo que eches un vistazo a este tutorial de desarrollo de backend en Python en DataCamp para obtener una visión general de los conceptos y herramientas web básicos.

¿Qué es FastHTML?

FastHTML es un framework Python optimizado diseñado para simplificar el desarrollo de interfaces web. Aborda retos comunes en el desarrollo, las pruebas y el rendimiento, eliminando la necesidad de amplios conocimientos de JavaScript o de gestionar múltiples archivos de plantilla.

Muchos programadores de Python quieren crear interfaces web sin sumergirse en las complejidades de una pila completa de JavaScript. FastHTML responde a este reto, permitiendo a los programadores definir rutas y componentes HTML con sólo unas pocas y concisas líneas de código Python.

Más allá de las interfaces básicas, los programadores pueden ampliar fácilmente las aplicaciones creadas con FastHTML incorporando funciones como autenticación, almacenamiento en caché, integración con bases de datos y estilos personalizados, mejorando significativamente la funcionalidad y la experiencia del usuario.

Características y ventajas de FastHTML

FastHTML tiene muchas funciones y ventajas. Supera muchos retos de desarrollo, pruebas y rendimiento.

FastHMTL tiene muchas funciones y ventajas.

  • Desarrollo sólo en Python: No necesitas funciones adicionales de JavaScript, sólo de Python. Esto da lugar a proyectos más ágiles, con menos archivos y menos repeticiones.
  • Dependencias mínimas: FastHTML sólo depende de unas pocas bibliotecas externas, por lo que las actualizaciones son sencillas y el mantenimiento es menos complejo.
  • Seguridad. Menos dependencias significa una menor superficie de ataque. 
  • Pila cliente/servidor unificada: Utilizar un único lenguaje y marco para la lógica y la interfaz de usuario reduce el cambio de contenido, lo que acelera el desarrollo.
  • Elementos HTML como objetos nativos de Python: FastHTML te permite utilizar elementos HTML como objetos Python a través de atributos HTMX sin JavaScript personalizado.
  • Gestión de peticiones asíncronas: FastHTML admite el procesamiento asíncrono de peticiones, lo que da lugar a operaciones de baja latencia y alta concurrencia.
  • Despliegue flexible: Las aplicaciones terminadas pueden desplegarse en cualquier plataforma que admita Python.

FastHTML mitiga la complejidad típicamente asociada al desarrollo de la interfaz de usuario web, como la gestión de archivos de plantilla independientes, scripts de ayuda y canalizaciones de activos. La complejidad de las pruebas se reduce significativamente, ya que la pila Python unificada permite a los programadores simplificar las fases de validación de backend, frontend y de extremo a extremo.

Principios arquitectónicos básicos

FastHTML se basa en principios arquitectónicos fundamentales: la capa de abstracción Python HTML, la integración con el estándar ASGI y la interactividad basada en HTMX.

Capa de abstracción Python HTML

FastHTML representa cada elemento HTML estándar como una función Python correspondiente. Por ejemplo, la etiqueta HTML

se refleja en la función Python Div(...), se convierte en A(..., href=...) y así sucesivamente. 

Los argumentos posicionales pasados a las funciones de elementos de Python se representan como elementos hijos en la estructura HTML resultante. Por ejemplo,

Div(
	P("Hello, world!"),
	Ul(Li("one"), Li("two"))
)

producirá esta salida HTML: 

<div>
  <p>Hello, world!</p>
  <ul>
    <li>one</li>
    <li>two</li>
  </ul>
</div>

Los argumentos de las palabras clave se convierten en atributos HTML. Por ejemplo, el código Python

A("Docs", href="/docs", cls="button", hx_get="/info")

se convierte en

<a href="/docs" class="button" hx-get="/info">Docs</a>

Ten en cuenta que la palabra clave cls corresponde al atributo class en HTML. Los guiones bajos en los nombres de atributos (hx_get) se convierten en guiones (hx-get). 

FastHTML aplaza la serialización, lo que permite que las rutas devuelvan objetos Python en lugar de cadenas HTML sin procesar. El marco sólo convierte el árbol de objetos Python a HTML en el último paso, justo antes de enviar la respuesta. Este diseño mantiene la lógica limpia y libre de manipulación manual de cadenas.

FastHTML proporciona las ventajas de la creación de plantillas y el manejo de atributos a prueba de tipos, lo que da como resultado un código más claro y fácil de mantener. Las API y los atributos de los elementos aparecen en las definiciones de funciones o clases, lo que hace que el código se explique por sí mismo. Los nombres seguros de Python (hx-post a hx_post) evitan la necesidad de manipular manualmente las cadenas.

Refactorizar es más seguro y fiable. Renombrar un parámetro actualiza los usos automáticamente. Además, las pruebas unitarias pueden instanciar y validar directamente los objetos de los componentes, lo que evita tener que recurrir a expresiones regulares contra el HTML renderizado.

Integración de la interfaz de pasarela de servidor asíncrono (ASGI)

FastHTML se integra con ASGI, un estándar para Python impulsado por la comunidad que permite la comunicación no bloqueante y basada en eventos entre servidores web y aplicaciones. ASGI potencia los marcos web modernos de Python al soportar operaciones asíncronas en el núcleo de la pila web.

Los servidores web como Uvicorn se adhieren a la especificación ASGI, lo que garantiza su compatibilidad y escalabilidad. Frameworks como Starlette y FastHTML se basan en ASGI para proporcionar enrutamiento robusto, middleware y API de alto nivel.

Esta arquitectura proporciona alta concurrencia, compatibilidad integrada con HTTP, WebSocket y eventos enviados por el servidor, y una gestión eficaz de las solicitudes basada en eventos. Al utilizar un bucle de eventos asíncrono, las aplicaciones ASGI evitan la sobrecarga de un subproceso del sistema operativo por conexión, lo que permite que unos pocos subprocesos gestionen miles de clientes. El objeto de ámbito estandarizado y el diseño no bloqueante permiten a los gestores hacer una pausa para la E/S sin ralentizar otras peticiones.

Interactividad impulsada por HTMX

Con la biblioteca HTMX, puedes añadir atributos HTML estándar ampliados con atributos hx-*. Estos elementos te permiten enviar peticiones HTTP y sustituir dinámicamente el contenido de la página por fragmentos devueltos por el servidor. No necesitas JavaScript personalizado. 

Primeros pasos con FastHTML

Empezar a utilizar FastHTML es muy sencillo. Hemos resumido los pasos principales en las secciones siguientes. 

Instalación y configuración

Para instalar FastHTML, utiliza pip install python-fasthtml.

Primera aplicación

Vamos a construir una aplicación sencilla para mostrar una cabecera y un mensaje.

from fasthtml.common import FastHTML, serve, Div, H1, P

app = FastHTML()

@app.get("/")
def home():
    return Div(
        H1("Welcome to FastHTML"),
        P("Hello, world!")
    )

if __name__ == "__main__":
    serve()

Ejecuta el archivo escribiendo python app.py en el terminal. 

 

Controla el enlace para abrir tu aplicación. Verás una página:

Definir una ruta

Vamos a añadir una página Acerca de a nuestra app. Utiliza el código siguiente:

from fasthtml.common import FastHTML, serve, Div, H1, P, A

app = FastHTML()

@app.get("/")
def home():
    return Div(
        H1("Welcome to FastHTML"),
        P("Hello, world!"),
        A("About", href="/about")
    )

@app.get("/about")
def about():
    return Div(
        H1("About"),
        P("This is the about page."),
        A("Home", href="/")
    )

if __name__ == "__main__":
    serve()

La línea A("About", href="/about") crea un enlace desde la página de inicio a la página Acerca de. El decorador @app.get("/about") define la ruta de la página Acerca de.

Aplicación básica

En FastHTML, los patrones de interfaz de usuario reutilizables se encapsulan en sencillas funciones de Python. Estas funciones devuelven objetos componentes anidados, lo que te permite tratar widgets como Card o Navbar como objetos invocables. 

Definir el marcado, los atributos y el estilo en un solo lugar garantiza la coherencia en toda la aplicación. Cuando importas y utilizas estas funciones, cualquier cambio visual o de comportamiento se propaga automáticamente. 

Este enfoque reduce el código repetido, haciendo que tu frontend sea tan fácil de probar y refactorizar como cualquier módulo de Python.

Para demostrarlo, vamos a crear una página que muestre dos tarjetas sencillas.

from fasthtml.common import *

def Card(title: str, body: str):
    children = [
        H2(title, cls="card-title"),
        P(body, cls="card-body")
    ]
    return Div(
        *children,
        cls="card",
        style="background- border-radius: 0.5rem;"
    )

app = FastHTML()

@app.get("/")
def home():
    return Div(
        Card("Welcome", "A welcome card."),
        P(''),
        Card("A Second Card", "This is another card."),
        cls="page"
    )

La función Card toma como argumentos una cadena title y otra body y devuelve un elemento de tarjeta con un estilo básico. En la ruta home, este widget se utiliza dos veces sin duplicar código. Definimos Card una vez y lo reutilizamos cuando es necesario, garantizando un marcado y un estilo coherentes en toda la aplicación.

Crear widgets de interfaz de usuario de esta forma tiene varias ventajas.

  • Duplicación reducida: Establece el marcado y el estilo una vez, y reutiliza el componente siempre que sea necesario. Las actualizaciones o correcciones de errores se propagan automáticamente.
  • Diseño coherente de la interfaz de usuario: Cada instancia de tu componente mantiene la misma estructura, clases y comportamiento. Esto refuerza un aspecto uniforme en toda la aplicación.
  • Mantenimiento simplificado: Una base de código más pequeña y DRY significa menos archivos que gestionar, menos repeticiones y un desarrollo más eficiente.

Uso avanzado

Esta sección explora las técnicas avanzadas de FastHTML, incluyendo el manejo de formularios, la validación y los patrones de respuesta ante errores. Aprovechando las clases de Python y los componentes estructurados, puedes crear formularios robustos y fáciles de usar, manteniendo un código limpio y comprobable.

Gestión y validación de formularios

FastHTML simplifica el manejo de formularios generando automáticamente formularios HTML a partir de clases de Python y proporcionando una vinculación de datos directa para procesar los envíos de formularios. 

Por ejemplo, considera el siguiente código.

from fasthtml.common import *
from dataclasses import dataclass

@dataclass
class Profile:
    name:str;
    email:str;
    age:int

profile_form = Form(method="post", action="/profile")(
        Fieldset(
            Label("Name", Input(name="name")),
            Label("Email", Input(name="email")),
            Label("Age", Input(name="age")),
        ),
        Button("Submit", type="submit"),
    )

# Instantiate app
app = FastHTML()

# GET / serves the form (FastHTML will serialize the component to HTML)
@app.get("/")
def home():
    return profile_form

# Simple POST handler to echo back submitted data
@app.post("/profile")
def profile(data: Profile):
    return Div(
        H1("Profile Submitted"),
        P(f"Name: {data.name}"),
        P(f"Email: {data.email}"),
        P(f"Age: {data.age}")
    )

Este código genera el siguiente HTML para el formulario. FastHTML analiza automáticamente los datos del formulario en el objeto Profile, asumiendo que los nombres de los campos son compatibles. Bajo el capó, esto puede depender del análisis sintáctico de formularios al estilo Starlette y de una capa de validación personalizada.

<form enctype="multipart/form-data" method="post" action="/profile">
	<fieldset>
	<label>Name<input name="name"></label>
	<label>Email<input name="email"></label>
	<label>Age<input name="age"></label>
</fieldset>

	<button type="submit">Submit</button>
</form>

Una vez enviado el formulario, FastHTML analiza los datos del formulario en el objeto Profile. La ruta profile devuelve entonces una página de confirmación, mostrando los valores enviados directamente desde el objeto data. Este enfoque simplifica el manejo de los formularios, reduce la repetición y garantiza una fuerte tipificación de los datos en toda la aplicación.

Siempre es una buena idea validar las entradas de los formularios. Añade lógica de validación reescribiendo la ruta /profile como sigue.

@app.post("/profile")
def submit_profile(data: Profile):
    # Form validation
    if not data.name.strip():
        raise HTTPException(status_code=400, detail="Name is required")
    if not data.email.strip() or "@" not in data.email:
        raise HTTPException(status_code=400, detail="A valid email is required")
    if data.age < 0:
        raise HTTPException(status_code=400, detail="Age must be non-negative")
    
    # If validation passes, render the result
    return Div(
        H1("Profile Submitted"),
        P(f"Name: {data.name}"),
        P(f"Email: {data.email}"),
        P(f"Age: {data.age}")
    )

Si falta name, falta email o age es negativo, el usuario recibe un mensaje de error claro. Al lanzar un mensaje HTTPException con un código de estado 400, la aplicación comunica el error de validación específico, lo que ayuda al usuario a corregir la entrada antes de volver a enviar el formulario.

Una forma más sólida de tratar los datos no válidos o que faltan es realizar una comprobación de errores explícita y proporcionar una respuesta fácil de usar. Por ejemplo, reescribe el código como sigue.

from fasthtml.common import *
from dataclasses import dataclass

@dataclass
class Profile:
    name: str
    email: str
    age: int

def profile_form(data=None, errors=None):
    data   = data   or {}
    errors = errors or {}
    return Form(
        Fieldset(
            Label(
                "Name",
                Input(
                    name="name",
                    value=data.get("name", ""),
                    placeholder="Your name"
                )
            ),
            Small(errors.get("name", ""), cls="error-text"),

            Label(
                "Email",
                Input(
                    name="email",
                    type="email",
                    value=data.get("email", ""),
                    placeholder="you@example.com"
                )
            ),
            Small(errors.get("email", ""), cls="error-text"),

            Label(
                "Age",
                Input(
                    name="age",
                    type="number",
                    value=str(data.get("age", "")),
                    placeholder="Age"
                )
            ),
            Small(errors.get("age", ""), cls="error-text"),
        ),
        Button("Submit", type="submit")
    , method="post", action="/profile", id="profile-form", hx_swap="outerHTML")

app = FastHTML()

@app.get("/")
def home():
    return Div(
        H1("Create Your Profile"),
        profile_form()
    )

@app.post("/profile")
async def submit_profile(request):
    form = await request.form()
    data = {
        "name":  form.get("name", "").strip(),
        "email": form.get("email", "").strip(),
    }
    errors = {}

    # Validate name
    if not data["name"]:
        errors["name"] = "Name is required. "

    # Validate email
    if not data["email"]:
        errors["email"] = "Email is required. "
    elif "@" not in data["email"]:
        errors["email"] = "Enter a valid email address."

    # Validate age
    age_raw = form.get("age", "").strip()
    try:
        age = int(age_raw)
        if age < 0:
            raise ValueError()
        data["age"] = age
    except ValueError:
        errors["age"] = "Age must be a non-negative integer. "

    if errors:
        # re-render form with submitted values and error messages
        return Div(
            H1("Create Your Profile"),
            profile_form(data, errors)
        )

    # Success path
    profile = Profile(**data)
    return Div(
        H1("Profile Submitted"),
        P(f"Name: {profile.name}"),
        P(f"Email: {profile.email}"),
        P(f"Age: {profile.age}")
    )

if __name__ == "__main__":
    serve()

Si el usuario se salta un campo obligatorio o introduce datos no válidos, verá que se vuelve a mostrar el formulario con los valores enviados y los mensajes de error correspondientes junto a cada campo. Este enfoque mejora la experiencia del usuario al indicar claramente lo que necesita corrección.

Una vez que hayas rellenado todos los campos y enviado, obtendrás una pantalla similar a la siguiente.

Autenticación y gestión de sesiones

Implementar flujos de autenticación

En FastHTML, los datos de sesión se gestionan a través del objeto request.session, que se comporta como un diccionario de Python. Puedes almacenar datos en la sesión estableciendo pares clave-valor, como session['user_id'] = 123. Para recuperar los datos de la sesión, utiliza read (user_id = session.get('user_id')). To clear all session data, call session.clear().

Entre bastidores, FastHTML serializa el diccionario de sesión en una cookie firmada, que persiste a través de las peticiones. Este enfoque te permite gestionar la autenticación del usuario y el estado de la sesión utilizando patrones familiares de Python.

Esquema de la creación de flujos de trabajo de autenticación

Para crear un flujo de trabajo de autenticación, sigue estos pasos.

  1. Configura las sesiones: Añadir SessionMiddleware with a strong secret_key. Once configured, the request.session is available in every handler.
  2. Modelo de usuario y gestión de contraseñas: Define un esquema de usuario (utilizando una clase de datos, un modelo Pydantic o un ORM) que incluya un nombre de usuario and password_hash. Use a hashing function (e.g., hashlib, pbkdf2_hmac, bcrypt) to store and verify passwords.
  3. Flujo de registro*: Crea un GET /register route to render a signup form. * Utiliza POST /register to validate form input, hash the password, save the user record, set the session['user_id'], and redirect to a protected page or dashboard.
  4. Flujo de inicio de sesión*: Crea un GET /login route to display login form. * Utiliza POST /login to verify credentials. On success, write session['user_id'] and redirect; on failure, re-render the form with an error message.
  5. Proteger las rutas: Crea una función de ayuda o decorador que compruebe session.get('user_id'). If the user is not authenticated, redirect to /login; otherwise, allow access to the requested route.
  6. Flujo de cierre de sesión: En el GET /logout route, call session.clear()` para eliminar los datos de sesión y redirigir al usuario a la página de inicio de sesión o de inicio.

Integración de bases de datos

Un mapeador relacional de objetos (ORM) asigna clases a tablas de bases de datos, lo que te permite consultar datos utilizando objetos nativos en lugar de SQL sin procesar. Algunas opciones populares son SQLAlchemy y el ORM de Django. 

FastHTML tiene una interfaz "tipo ORM" que se integra con cualquier ORM o biblioteca de consulta de Python con capacidad asíncrona. Por defecto utiliza SQLite, pero puede integrarse con cualquier base de datos. Por ejemplo, considera el siguiente código.

# Database setup (SQLite by default, but backend can change)
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
from sqlalchemy.orm import sessionmaker, declarative_base
from sqlalchemy import Column, Integer, String, select
from fasthtml.common import *

DATABASE_URL = "sqlite+aiosqlite:///./test.db"  # Change backend here (e.g., PostgreSQL)

engine = create_async_engine(DATABASE_URL, echo=True)
SessionLocal = sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)
Base = declarative_base()

# ORM model
class User(Base):
    __tablename__ = "users"
    id = Column(Integer, primary_key=True)
    name = Column(String)

# FastHTML app
app = FastHTML()

@app.get("/")
async def list_users():
    async with SessionLocal() as session:
        result = await session.execute(select(User))
        users = result.scalars().all()
    
    return Div(
        H1("Users"),
        Ul(*[Li(user.name) for user in users])
    )

if __name__ == "__main__":
    import asyncio
    async def init_db():
        async with engine.begin() as conn:
            await conn.run_sync(Base.metadata.create_all)
    asyncio.run(init_db())
    serve()

En una aplicación FastHTML, consultas los datos en la capa de base de datos que elijas y luego pasas los resultados a los componentes FastHTML para su representación. Por ejemplo, después de recuperar registros de tu base de datos, puedes recorrerlos en bucle en un manejador de rutas y construir estructuras HTML como tablas, listas o tarjetas personalizadas.

Se siguen aplicando las mejores prácticas: selecciona sólo los campos necesarios, filtra y ordena a nivel de base de datos y pagina los conjuntos de resultados grandes. FastHTML te ayuda a centrarte en construir frontales limpios y dinámicos, dejando el manejo de datos a las mejores herramientas para tu proyecto.

Estrategias de optimización del rendimiento

Hay varias formas de obtener los mejores resultados al utilizar FastHTML. Hemos esbozado algunas de estas recomendaciones a continuación. 

Mecanismos de caché

El almacenamiento en caché mejora el rendimiento al evitar el trabajo redundante en las distintas capas de tu aplicación. A nivel de navegador y CDN, utiliza cabeceras de control de caché para retener activos estáticos como imágenes, scripts y hojas de estilo. 

Puedes almacenar en caché respuestas de rutas enteras o partes costosas en tu marco web. Dentro de tu aplicación FastHTML, puedes almacenar en caché respuestas de rutas enteras o componentes costosos, asegurándote de que las solicitudes repetidas vuelvan rápidamente sin tener que volver a consultar la base de datos o regenerar plantillas.

En Python, puedes implementar el almacenamiento en caché a nivel de función utilizando decoradores. Por ejemplo, el decorador incorporado functools.lru_cache puede memoizar una función de ayuda que obtiene datos del usuario. Por ejemplo, podrías utilizar este decorador para almacenar en caché las llamadas a la base de datos:

from functools import lru_cache

@lru_cache(maxsize=64)
def fetch_user_profile(user_id):
    # simulate an expensive database call
    return db.get_user(user_id)

@app.get("/profile/{user_id}")
def profile(user_id: int):
    profile = fetch_user_profile(user_id)
    return Div(P(profile.name), P(profile.email))

Colas de tareas asíncronas

Las aplicaciones web mantienen su capacidad de respuesta descargando del ciclo de solicitud las tareas que consumen tiempo. En lugar de bloquear el servidor mientras se generan informes, se envían correos electrónicos o se procesan datos, estas tareas se ponen en cola y se ejecutan en segundo plano. 

Con este enfoque, tu aplicación envía una respuesta inmediata al usuario mientras los trabajadores, que se ejecutan en procesos o hilos separados, procesan las tareas en cola de forma asíncrona.

FastHTML admite la ejecución de tareas en segundo plano integrándose con BackgroundTasks de Starlette . Aquí tienes un ejemplo que muestra cómo enviar un correo electrónico de bienvenida tras el registro del usuario.

from fasthtml.common import FastHTML, serve, Div, Form, Input, Button
from starlette.background import BackgroundTasks

app = FastHTML()

def send_welcome_email(email: str):
    # expensive or time consuming work
    ...

@app.post("/signup")
def signup(background_tasks: BackgroundTasks, request):
    form = await request.form()
    email = form["email"]
    # schedule the email task
    background_tasks.add_task(send_welcome_email, email)
    return Div("Thanks for signing up! You will receive an email shortly.")

Aplicaciones en el mundo real

FastHTML es un framework versátil que puede alimentar una amplia gama de aplicaciones web. Veamos cómo podrías abordar la creación de una plataforma de comercio electrónico y un panel de datos utilizando FastHTML.

Proyecto de plataforma de comercio electrónico

Construyamos una plataforma de comercio electrónico con FastHTML. Empieza por modelar tus datos principales como clases ORM o clases de datos Python: productos, usuarios y artículos del carrito. 

Crea una página de listado de productos que recorra en bucle tus registros de productos. Para cada producto, utiliza un componente Python reutilizable, como Card, para mostrar el producto, la imagen, el nombre, el precio y un botón "Añadir al carrito". Este botón incluye atributos HTMX como hx_post y hx_target, que le permiten enviar una solicitud para añadir el artículo al carrito de la sesión del usuario sin recargar toda la página.

El propio carrito de la compra se almacena en el diccionario session del usuario en el servidor. En la cabecera de tu sitio, incluye un componente de resumen del carrito que se actualice dinámicamente mediante HTMX cada vez que se efectúen o eliminen artículos. 

La página del carrito lee los datos de la sesión para mostrar cada artículo del carrito junto con un total general. También ofrece un formulario de pago que se conecta a una clase Python para la validación. Cuando el usuario envía el formulario, tu aplicación crea un registro de pedido y borra el carro de la sesión.

Implementación del cuadro de mando de datos

Un panel de datos en FastHTML combina componentes Python con tus fuentes de datos, utilizando HTMX para la interactividad y las actualizaciones en tiempo real. Tu lógica de backend (por ejemplo, funciones de ayuda asíncronas, utilidades CRUD en caché o consultas ORM) recupera los datos necesarios. 

A partir de ahí, diseña una página con widgets reutilizables. Pueden incluir controles de filtro (como desplegables, selectores de fecha o cuadros de búsqueda) para refinar las consultas, tarjetas de KPI para mostrar métricas clave, tablas de datos para listar registros o incrustaciones de gráficos para visualizar tendencias y comparaciones. 

Cada widget está escrito como código nativo de Python, normalmente un componente de Div, Table, o personalizado de Card. FastHTML transforma automáticamente estos objetos en HTML en tiempo de respuesta.

HTMX permite que los cuadros de mando sean interactivos. Por ejemplo, los widgets de filtro pueden utilizar hx_get y hx_post para solicitar datos filtrados al servidor, actualizando dinámicamente unas tablas o gráficos sin necesidad de recargar toda la página. 

Análisis comparativo con los marcos tradicionales

FastHTML se desmarca de los marcos tradicionales como Django y Flask al agilizar tanto el desarrollo como el rendimiento. Exploremos cómo se compara en factores clave como el tiempo de configuración, la eficacia del código y las pruebas de rendimiento.

Velocidad de desarrollo

FastHTML tiene dos ventajas clave sobre frameworks como Django y Flask: el tiempo de configuración y la eficiencia del código.

Tiempo de preparación

El enfoque "pilas incluidas" de Django requiere varios pasos antes de que puedas servir tu primera página: instalar el paquete, ejecutar django-admin startproject, configurar los ajustes y definir una app. Esto suele implicar varios archivos y un montón de código repetitivo antes de escribir cualquier lógica real.

Flask es más delgado. Después de pip install, puedes escribir un par de rutas en un único archivo. Sin embargo, aún tienes que configurar las plantillas Jinja, las carpetas estáticas y añadir JavaScript para la interactividad.

Con FastHTML, la configuración es mínima.

  1. Ejecuta pip install python-fasthtml uvicorn.
  2. Define rutas y componentes HTML Python. Puedes hacerlo en un solo archivo.
  3. Llama a serve().

No es necesario configurar por separado el motor de plantillas ni las carpetas estáticas. Puedes empezar a construir inmediatamente.

Código de eficiencia

Con Django, incluso una simple página "Hola, mundo" requiere múltiples archivos: views.py, urls.py, settings.py, templates/hello.html, además del andamiaje ORM y admin.

Flask simplifica este proceso a un único archivo, pero sigues necesitando escribir manualmente HTML en plantillas Jinja o cadenas inline, y JavaScript para la interactividad.

FastHTML te permite definir tu interfaz de usuario como objetos Python, por lo que no es necesario cambiar de archivo o de lenguaje. HTMX maneja la interactividad de forma declarativa, sin scripts personalizados. El resultado son menos líneas de código, sin plantillas separadas ni canalizaciones de activos estáticos, y una única superficie comprobable tanto para el marcado como para el comportamiento.

Parámetros de rendimiento

Los estudios comparativos demuestran que los marcos asíncronos superan a los síncronos cuando hay mucha concurrencia. Por ejemplo, en una comparación de rendimiento entre Flask, Django, Quart y FastAPI, los marcos asíncronos (Quart y FastAPI) gestionaron muchas más peticiones por segundo que sus homólogos síncronos. 

Esto se atribuye a sus mecanismos de gestión de peticiones no bloqueantes, que les permiten gestionar varias peticiones simultáneamente sin esperar a que finalicen las operaciones de E/S.

Tabla comparativa 

Para comprender mejor cómo se compara FastHTML con otros marcos de trabajo más establecidos, la tabla siguiente describe las diferencias clave en el tiempo de configuración, la eficiencia del código y las características de rendimiento entre FastHTML, Flask y Django.

Función

FastHTML

Frasco

Django

Tiempo de preparación

Mínimo: pip install, definir rutas y componentes en un archivo, llamar a serve()

Moderado: inicio rápido con un solo archivo, pero requiere plantillas Jinja y configuración de carpetas estáticas

Largo: requiere un andamiaje de proyecto, configuración de ajustes, definiciones de aplicaciones y múltiples archivos

Motor de plantillas

No se necesita -utiliza objetos Python para HTML

Se necesita un motor de plantillas Jinja2 para las vistas

Utiliza Plantillas Django con un lenguaje de plantillas y un directorio separados

Interactividad del Front-End

Declarativo mediante HTMX, no requiere JavaScript

Normalmente se necesita JavaScript manual para la interactividad

Requiere JavaScript para la interactividad, a menudo implica herramientas externas

Código Eficiencia

Alto: boilerplate mínimo, Pythonic HTML, lógica unificada + UI

Moderado: enrutamiento conciso pero el HTML vive en plantillas, la interactividad necesita JS personalizado

Bajo: la lógica, las plantillas y la configuración están divididas en muchos archivos

Rendimiento (concurrencia)

Alto: construido sobre ASGI con soporte asíncrono, adecuado para alta concurrencia

Baja: Basado en WSGI, manejo síncrono a menos que se amplíe con funciones asíncronas

Baja: Basado en WSGI y síncrono por defecto; requiere configuración adicional para soporte asíncrono

Líneas de código para "Hola, mundo"

Muy pocas líneas en un archivo

Pocas líneas, pero requiere plantilla o HTML en línea

Múltiples archivos incluyendo vistas, URLs, plantillas y configuraciones

Conclusión

FastHTML ofrece un enfoque fresco y pitónico para crear aplicaciones web, combinando la flexibilidad de los objetos Python con la potencia de la ejecución asíncrona. Al eliminar la necesidad de archivos de plantilla independientes, canalizaciones de activos estáticos y marcos frontales, FastHTML agiliza el desarrollo y te permite crear interfaces dinámicas e interactivas de forma rápida y eficaz.

Con HTMX para la interactividad, ASGI para el rendimiento y una integración perfecta con los ORM con capacidad asíncrona, FastHTML es idóneo para los proyectos web modernos, desde plataformas de comercio electrónico hasta paneles de control de datos y mucho más. Su configuración mínima, su reducida repetición de tareas y su base de código unificada lo convierten en una opción atractiva para programadores que buscan una alternativa ligera y productiva a los marcos tradicionales como Django y Flask.

Para los lectores interesados en explorar herramientas y enfoques relacionados con el desarrollo web basado en Python, los siguientes recursos ofrecen pasos útiles.

Preguntas frecuentes sobre Python FastHTML

¿En qué se diferencia FastHTML de Django o Flask?

FastHTML elimina la necesidad de archivos de plantilla independientes, configuraciones de activos estáticos y frameworks frontales. Se centra en el desarrollo sólo en Python con HTMX para la interactividad.

¿Puedo utilizar FastHTML para aplicaciones a gran escala?

Sí. La arquitectura de FastHTML (Python + HTMX + ASGI) se adapta bien a las aplicaciones modernas de alto rendimiento. Para proyectos grandes, puedes modularizar tu código base con componentes reutilizables.

¿Admite FastHTML interactividad dinámica como AJAX?

Sí. FastHTML utiliza HTMX para manejar la interactividad de forma declarativa, permitiendo actualizaciones parciales de la página (similares a AJAX) sin JavaScript personalizado.

¿Puedo desplegar aplicaciones FastHTML en la nube?

Absolutamente. Las aplicaciones FastHTML pueden desplegarse en cualquier plataforma que admita ASGI y Python, incluidos servicios como Vercel, Fly.io y DigitalOcean.


Mark Pedigo's photo
Author
Mark Pedigo
LinkedIn

Mark Pedigo, PhD, es un distinguido científico de datos con experiencia en ciencia de datos sanitarios, programación y educación. Doctor en Matemáticas, Licenciado en Informática y Certificado Profesional en Inteligencia Artificial, Mark combina los conocimientos técnicos con la resolución práctica de problemas. Su carrera incluye funciones en la detección del fraude, la predicción de la mortalidad infantil y la previsión financiera, junto con contribuciones al software de estimación de costes de la NASA. Como educador, ha impartido clases en DataCamp y en la Universidad Washington de San Luis, y ha sido mentor de programadores noveles. En su tiempo libre, Mark disfruta de la naturaleza de Minnesota con su esposa Mandy y su perro Harley, y toca el piano de jazz.

Temas

Los mejores cursos de DataCamp

Programa

Associate Python Developer

0 min
Learn Python for software development, from writing functions to defining classes. Get the necessary skills to kickstart your developer career!
Ver detallesRight Arrow
Comienza el curso
Ver másRight Arrow
Relacionado

blog

Cómo aprender Python desde cero en 2024: Guía del experto

Descubre cómo aprender Python, sus aplicaciones y la demanda de conocimientos de Python. Comienza hoy tu andadura en Python ​con nuestra guía completa.
Matt Crabtree's photo

Matt Crabtree

15 min

Tutorial

Tutorial de FastAPI: Introducción al uso de FastAPI

Explore el marco FastAPI y descubra cómo puede utilizarlo para crear API en Python.
Moez Ali's photo

Moez Ali

13 min

Tutorial

Desarrollo de backend en Python: Guía completa para principiantes

Esta completa guía te enseña los fundamentos del desarrollo backend en Python. Aprende conceptos básicos, marcos de trabajo y buenas prácticas para empezar a crear aplicaciones web.
Oluseye Jeremiah's photo

Oluseye Jeremiah

15 min

Tutorial

APIs Web, Peticiones en Python y Realización de una Petición HTTP en el Tutorial de Python

Conoce los fundamentos de HTTP y también la biblioteca de peticiones en Python para realizar distintos tipos de peticiones.
Kurtis Pykes 's photo

Kurtis Pykes

15 min

Tutorial

Datos JSON en Python

Trabajar con JSON en Python: Una guía paso a paso para principiantes
Moez Ali's photo

Moez Ali

6 min

Tutorial

Tutorial Python Docstrings : Ejemplos y Formato de Cadenas Doc Pydoc, Numpy, Sphinx

Aprende sobre las Docstrings de Python. Encuentra diferentes ejemplos y tipos de formato de docstrings para Sphinx, Numpy y Pydoc.
Aditya Sharma's photo

Aditya Sharma

15 min

Ver másVer más