La comodidad y versatilidad de Python hacen que se utilice para construir software en casi todos los ámbitos de la vida informática. Un nicho importante es el de los servicios web, donde la velocidad de desarrollo y las metáforas flexibles de Python facilitan la puesta en marcha de sitios web rápidamente.
Y tal como se puede adivinar, Python ofrece muchas opciones y latitud en los frameworks web, tanto pequeños como grandes. Después de todo, no todos los proyectos web tienen que ser a escala empresarial. La mayoría debería ser lo suficientemente grande como para hacer el trabajo, y no más. Este artículo examina ocho de los frameworks de Python más conocidos que hacen hincapié en la simplicidad, la entrega de peso ligero, y un enfoque apretado.
Bottle
Bottle podría considerarse una especie de mini-Flask, ya que es aún más compacto y sucinto que ese otro «microframework». Debido a su mínima huella, Bottle es ideal para incluirlo en otros proyectos o para entregar rápidamente pequeños proyectos como APIs REST. (Flask se discute más adelante.)
Todo el código base de Bottle cabe en un solo archivo y no tiene absolutamente ninguna dependencia externa. Aún así, Bottle viene equipado con suficiente funcionalidad para construir tipos comunes de aplicaciones web sin depender de ayuda externa.
El sistema de enrutamiento en Bottle, que mapea URLs a funciones, tiene casi exactamente la misma sintaxis que Flask. Tampoco estás limitado a un conjunto de rutas rígidas; puedes crearlas dinámicamente. Los datos de solicitud y respuesta, las cookies, las variables de consulta, los datos del formulario de una acción POST, las cabeceras HTTP y la carga de archivos pueden ser accedidos y manipulados por medio de objetos en Bottle.
Cada capacidad ha sido implementada con buena atención al detalle. Con la carga de archivos, por ejemplo, usted no tiene que cambiar el nombre del archivo si su convención de nomenclatura choca con el sistema de archivos de destino (como barras en el nombre en Windows). Bottle puede hacer eso por usted.
Bottle incluye su propio y sencillo motor de plantillas HTML. De nuevo, aunque mínimo, el motor de plantillas tiene todo lo esencial. Las variables incluidas en una plantilla se renderizan con HTML seguro por defecto; tienes que indicar qué variables son seguras para reproducirlas literalmente. Si prefieres cambiar el motor de plantillas de Bottle por otro diferente, como Jinja2, Bottle te permite hacerlo sin problemas. Yo prefiero el sistema de plantillas simples incluido en Bottle; es rápido, su sintaxis no es pretenciosa, y le permite entremezclar el código y el texto de las plantillas sin demasiada dificultad.
Bottle incluso soporta múltiples servidores. Viene con su propio miniserver incorporado para pruebas rápidas, pero también soporta WSGI genérico, una amplia variedad de servidores HTTP compatibles con WSGI, y el viejo CGI si es necesario.
Bottle no necesita tanta documentación como otros frameworks, pero los documentos no son en absoluto escasos. Todo lo crucial cabe en una sola página web (aunque larga). Más allá de eso, encontrarás documentación completa para cada API, ejemplos para desplegar en varias infraestructuras, una explicación del lenguaje de plantillas incorporado, y un montón de recetas comunes.
Al igual que con Flask, puedes ampliar la funcionalidad de Bottle manualmente o a través de plug-ins. Los plug-ins de Bottle no son ni de lejos tan numerosos como los de Flask, pero hay piezas útiles, como la integración con varias capas de bases de datos y la autenticación básica de usuarios. Para el soporte asíncrono, Bottle puede utilizar uno de los adaptadores de servidor existentes que se ejecuta de forma asíncrona, como aiohttp/uvloop, pero async/await
no está soportado de forma nativa.
Una consecuencia del minimalismo de Bottle es que algunos elementos simplemente no están ahí. La validación de formularios, incluyendo características como la protección CSRF (cross-site request forgery), no está incluida. Si quieres construir una aplicación web que soporte un alto grado de interacción con el usuario, tendrás que añadir ese soporte por ti mismo.
Otro problema con Bottle es que el desarrollo se ha estancado; la última versión de punto, 0.12, llegó en 2013. Dicho esto, Bottle sigue siendo mantenido, y sus versiones de desarrollo siguen siendo utilizables para la producción. Los desarrolladores tienen la intención de entregar nuevas versiones que se deshacen de soporte para las ediciones heredadas de Python.
CherryPy
CherryPy ha existido en una forma u otra durante casi 20 años, pero no ha perdido el minimalismo y la elegancia que lo distinguió desde el principio.
El objetivo detrás de CherryPy, además de contener sólo los bits necesarios para servir páginas web, es sentirse, en la medida de lo posible, no como un «framework web» sino como cualquier otro tipo de aplicación Python. Sitios como Hulu y Netflix han usado CherryPy en producción porque el framework provee una base muy discreta para construir. CherryPy usa hilos agrupados bajo el capó, lo mejor para soportar adaptadores de servidores multihilo.
CherryPy te permite mantener tu aplicación web separada de la lógica central. Para mapear las funciones de tu aplicación a URLs o rutas servidas por CherryPy, creas una clase donde los espacios de nombres de los objetos se mapean directamente a las URLs que quieres servir. Por ejemplo, la raíz del sitio web es proporcionada por una función llamada «index». Los parámetros pasados a esas funciones se usan para manejar las variables proporcionadas por los métodos GET o POST.
Los bits que CherryPy incluye están destinados a trabajar como bloques de construcción de bajo nivel. Los identificadores de sesión y el manejo de cookies están incluidos, pero las plantillas HTML no. Al igual que Bottle, CherryPy ofrece una manera de mapear rutas a directorios en el disco para servir archivos estáticos.
CherryPy a menudo se remite a una librería de terceros para soportar una característica en vez de proveerla nativamente. Las aplicaciones WebSocket, por ejemplo, no son soportadas por CherryPy directamente, sino a través de la librería ws4py.
La documentación de CherryPy incluye un práctico tutorial de los diferentes aspectos del programa. No te llevará a través de una aplicación completa de principio a fin, a diferencia de otros tutoriales de marcos de trabajo, pero sigue siendo útil. Los documentos vienen con notas útiles sobre el despliegue en hosts virtuales, proxy inverso a través de Apache y Nginx, y muchos otros escenarios.
Falcon
Si estás construyendo APIs basadas en REST y nada más, Falcon fue hecho sólo para ti. Esbelto y rápido, sin apenas dependencias más allá de la biblioteca estándar, Falcon proporciona todo lo que necesitas para las APIs REST y nada más. Falcon 2.0, lanzado en 2019, elimina el soporte de Python 2.x y requiere al menos Python 3.5.
Una gran parte de por qué Falcon se gana la etiqueta de «ligero y delgado» tiene poco que ver con el número de líneas de código en el marco. Es porque Falcon no impone casi ninguna estructura propia a las aplicaciones. Todo lo que tiene que hacer una aplicación Falcon es indicar qué funciones corresponden a qué puntos finales de la API. Devolver JSON desde un punto final implica poco más que configurar una ruta y devolver los datos mediante la función json.dumps
de la biblioteca estándar de Python. El soporte para async aún no ha llegado a Falcon, pero se está trabajando para que esto suceda en Falcon 3.0.
Falcon también emplea valores predeterminados sanos, por lo que se necesita poco ajuste para la configuración. Por ejemplo, los 404s se levantan por defecto para cualquier ruta que no esté explícitamente declarada. Si quieres devolver errores al cliente, puedes lanzar una de las excepciones incluidas en el framework (como HTTPBadRequest
) o utilizar una excepción genérica falcon.HTTPError
. Si necesita preprocesamiento o postprocesamiento para una ruta, Falcon proporciona ganchos para estos también.
El enfoque de Falcon en las APIs significa que hay poco aquí para construir aplicaciones web con interfaces de usuario HTML convencionales. No esperes mucho en cuanto a funciones de procesamiento de formularios y herramientas de protección CSRF, por ejemplo. Dicho esto, Falcon ofrece elegantes opciones para ampliar su funcionalidad, por lo que se pueden construir elementos más sofisticados. Aparte del mencionado mecanismo de enganche, encontrará una interfaz para crear middleware que puede utilizarse para envolver todas las API de Falcon.
La documentación de Falcon es escasa comparada con la de otros frameworks, pero sólo porque hay menos que cubrir. La guía del usuario incluye un recorrido formal paso a paso de todas las características principales, junto con una sección de inicio rápido que le permite ver el código de ejemplo con o sin anotación.
FastAPI
El nombre de FastAPI es un buen resumen de lo que hace. Está construido para crear puntos finales de la API rápidamente, y también se ejecuta rápidamente.
FastAPI hace uso del proyecto Starlette para su núcleo de red de alta velocidad, pero no es necesario conocer el interior de Starlette para utilizar FastAPI. Se definen los puntos finales de la misma manera que una aplicación Flask o Bottle – se utilizan decoradores para indicar qué funciones manejan qué rutas – y luego se devuelven diccionarios que se traducen automáticamente en JSON.
Se puede anular fácilmente cómo se devuelven las cosas. Por ejemplo, si quieres devolver HTML/XML desde algunos puntos finales, puedes hacerlo simplemente devolviendo un objeto personalizado Response
. Si quieres añadir middleware personalizado, puedes introducir cualquier cosa que siga el estándar ASGI.
FastAPI hace uso de las sugerencias de tipo de Python para proporcionar restricciones en los tipos de datos que aceptan las rutas. Por ejemplo, si tiene una ruta con el tipo Optional
, FastAPI rechazará cualquier envío excepto los enteros. No tiene que añadir código de validación de datos a sus puntos finales; puede simplemente utilizar sugerencias de tipo y dejar que FastAPI haga el trabajo.
Naturalmente, algunas cosas se quedan fuera. No hay un motor de plantillas HTML nativo, por ejemplo, pero no hay escasez de soluciones de terceros para llenar ese vacío. Lo mismo con la conectividad de la base de datos, pero la documentación contiene detalles sobre cómo convencer a ciertos ORM (por ejemplo, Peewee) para trabajar con los comportamientos asíncronos de FastAPI.
Flask
Muchas discusiones sobre los marcos web de Python comienzan con Flask, y por una buena razón. Flask es un framework bien establecido, bien entendido, fácil de usar y bastante estable. Es casi imposible equivocarse usando Flask para un proyecto web ligero o una API REST básica, pero te enfrentarás a un trabajo pesado si intentas construir algo más grande.
El atractivo central de Flask es su baja barrera de entrada. Una aplicación básica «hola mundo» se puede configurar en menos de 10 líneas de Python. Flask incluye un sistema de plantillas HTML ampliamente utilizado, Jinja2, para facilitar la representación del texto, pero Jinja2 se puede cambiar por cualquier número de otros motores de plantillas (como Mustache) o usted puede desarrollar el suyo propio.
En nombre de la simplicidad, Flask omite sutilezas como una capa de datos u ORM, y no ofrece disposiciones para los gustos de la validación de formularios. Sin embargo, Flask puede ser ampliado a través de extensiones, de las cuales hay docenas, que cubren muchos casos de uso común como el almacenamiento en caché, el manejo y la validación de formularios, y la conectividad de bases de datos. Este diseño de «lean-by-default» le permite comenzar la ingeniería de una aplicación Flask con el mínimo absoluto de la funcionalidad, a continuación, la capa en sólo las piezas que necesita cuando usted los necesita.
La documentación de Flask es genial y fácil de leer. El documento de inicio rápido hace un excelente trabajo para empezar, mientras que también explica la importancia de las opciones por defecto para una aplicación simple de Flask, y los documentos de la API están repletos de buenos ejemplos. También es excelente la colección de fragmentos de Flash, que son ejemplos rápidos y sucios de cómo realizar tareas específicas, como la forma de devolver un objeto si existe o un error 404 si no lo hace.
Flask alcanzó su hito de lanzamiento 1.0 en 2018, con Python 2.6 y Python 3.3 siendo las versiones mínimas soportadas, y con muchos de sus comportamientos finalmente establecidos en piedra. Flask no soporta explícitamente la sintaxis asíncrona de Python, pero una variación de Flask compatible con la API llamada Quart se ha escindido para satisfacer esa demanda.
Pirámide
Pequeña y ligera, Pyramid es adecuada para tareas como exponer el código Python existente como una API REST, o proporcionar el núcleo de un proyecto web donde el desarrollador hace la mayor parte del trabajo pesado.
«Pyramid le permitirá ser productivo rápidamente, y crecerá con usted», dice la documentación. «No te frenará cuando tu aplicación sea pequeña, y no se interpondrá en tu camino cuando tu aplicación sea grande».
Una buena manera de describir el minimalismo de Pyramid sería «libre de políticas», un término utilizado en la sección de la documentación que discute cómo Pyramid se compara con otros frameworks web. Básicamente, «libre de política» significa que la base de datos o el lenguaje de plantillas que elijas utilizar no es asunto de Pyramid.
Se necesita muy poco trabajo para construir una aplicación básica de Pyramid. Al igual que con Bottle y Flask, una aplicación Pyramid puede consistir en un solo archivo de Python, aparte de los archivos para el propio marco. Una simple API de una ruta no requiere más de una docena de líneas de código. La mayor parte de eso es boilerplate como declaraciones from … import
y la configuración del servidor WSGI.
Por defecto, Pyramid incluye varios elementos que son comunes en las aplicaciones web, pero se proporcionan como componentes para ser cosidos juntos, no como soluciones completas. El apoyo a las sesiones de usuario, por ejemplo, incluso viene con protección CSRF. Pero la compatibilidad con las cuentas de usuario, como los inicios de sesión o la gestión de cuentas, no forma parte del acuerdo. Tendrá que implementarlo usted mismo o añadirlo a través de un complemento. Lo mismo ocurre con el manejo de formularios y las conexiones a bases de datos.
Pyramid incluso proporciona una manera de crear plantillas de proyectos anteriores de Pyramid para reutilizar el trabajo anterior. Estas plantillas, llamadas «scaffolds», generan una aplicación Pyramid con un enrutamiento simple y algunas plantillas HTML/CSS de inicio. Los scaffolds incluidos incluyen un proyecto de inicio de muestra y un proyecto que se conecta a las bases de datos a través de la popular biblioteca de Python SQLAlchemy.
Las delgadas herramientas de prueba y depuración de Pyramid hacen el trabajo. Si se incluye la extensión debugtoolbar
en una aplicación de Pyramid, se obtendrá un icono en el que se puede hacer clic en cada página web y que genera detalles sobre la ejecución de la aplicación, incluyendo un rastreo detallado en caso de errores. El registro y las pruebas unitarias también están presentes.
La documentación de Pyramid es excelente. Además de un recorrido rápido de los fundamentos y un tutorial de estilo, encontrará un conjunto de tutoriales contribuidos por la comunidad y un libro de recetas comunes. Este último incluye técnicas de despliegue para un montón de entornos de destino, desde Google App Engine a Nginx.
Pyramid soporta tanto Python 2 como Python 3, pero no utiliza la sintaxis asíncrona de Python 3. Si quieres aprovechar async en Pyramid, consulta el proyecto aiopyramid, que incluye un andamio para una aplicación «hello world» potenciada por async.
Sanic
Diseñado para la velocidad y la simplicidad, Sanic funciona con Python 3.6 o superior y utiliza la sintaxis async/await
de Python (disponible a partir de Python 3.5) para permitirle crear aplicaciones web eficientes.
Al igual que con Flask o Bottle, un «hola mundo» básico de Sanic tiene unas 10 líneas de código, la mayor parte de ellas importaciones y otros elementos innecesarios. La diferencia clave es que las rutas de aplicación deben ser declaradas como funciones async def
, y debes usar await
para invocar estas funciones dentro de tu código asíncrono. Si has escrito aplicaciones asíncronas antes, ya tienes la parte más difícil bajo tu cinturón.
Muchos de los mecanismos que Sanic utiliza para manejar las conexiones y las respuestas te serán familiares. Las solicitudes y las respuestas son sólo objetos con propiedades de aspecto familiar, como archivos cargados, formularios, objetos JSON, cabeceras, etc.
Las aplicaciones con muchas rutas se vuelven difíciles de manejar. Sanic aborda esto con «blueprints», objetos que pueden describir grupos de rutas y permitirle administrarlas a través de una interfaz de alto nivel. En lugar de escribir cada ruta explícitamente, o utilizar un exceso de rutas con variables, puedes escribir unos cuantos blueprints para describir genéricamente cómo funcionan las rutas en tu aplicación (por ejemplo, /object/object_id/action
). Los blueprints pueden tener un middleware común, lo que es útil si quieres aplicar la funcionalidad de gestión a algunas rutas pero no a otras.
Sanic también funciona con otros protocolos además de HTTP. Los puntos finales de WebSocket sólo requieren un decorador diferente y un poco más de lógica interna (por ejemplo, esperar y manejar las respuestas). Los protocolos de red personalizados pueden ser soportados subclasificando asyncio.protocol
.
Sanic deja deliberadamente fuera la funcionalidad como la conectividad de la base de datos y las plantillas HTML, mientras que conserva las características que uno usaría para conectar esas capacidades: middleware, configuración centralizada de la aplicación, etc.
Tornado
Tornado es otro pequeño framework dirigido a un caso de uso específico: aplicaciones de red asíncronas. Tornado es muy adecuado para crear servicios que abran un gran número de conexiones de red y las mantengan vivas, es decir, cualquier cosa que implique WebSockets o sondeos largos. Tornado 6.0 requiere Python 3.5 o superior, y abandona por completo el soporte de Python 2.
Al igual que Bottle o Falcon, Tornado omite características extrañas a su propósito central. Tornado tiene un sistema de plantillas incorporado para generar HTML y otras salidas, y proporciona mecanismos para la internacionalización, el manejo de formularios, la configuración de cookies, la autenticación de usuarios y la protección CSRF. Pero deja fuera características, como la validación de formularios y un ORM, que son principalmente para las aplicaciones web de cara al usuario.
Tornado sobresale en la provisión de infraestructura a las aplicaciones que necesitan un estrecho control sobre la red asíncrona. Por ejemplo, Tornado proporciona no sólo un servidor HTTP asíncrono incorporado, sino también un cliente HTTP asíncrono. Por lo tanto, Tornado es muy adecuado para la construcción de aplicaciones, como un raspador web o un bot, que consultan otros sitios en paralelo y actúan sobre los datos devueltos.
Si desea crear una aplicación que utiliza protocolos distintos de HTTP, Tornado lo tiene cubierto. Tornado proporciona acceso a conexiones TCP de bajo nivel y sockets a utilidades como resolvedores DNS, así como a servicios de autenticación de terceros, y soporta la interoperación con otros frameworks a través del estándar WSGI. La documentación, que es pequeña pero no escasa, incluye amplios ejemplos para lograr todo esto.
Tornado aprovecha y complementa la funcionalidad nativa de Python para comportamientos asíncronos. Si estás usando Python 3.5, Tornado soporta las palabras clave incorporadas async
y await
, que prometen dar a las aplicaciones un impulso de velocidad. También puede utilizar futuros o callbacks para manejar las respuestas a los eventos.
Tornado proporciona una biblioteca de primitivas de sincronización-semaphores, cerraduras, y así sucesivamente-para coordinar los eventos entre coroutines asíncronos. Tenga en cuenta que Tornado normalmente se ejecuta con un solo hilo, por lo que estas primitivas no son lo mismo que sus homónimos de roscado. Sin embargo, si quieres ejecutar Tornado en procesos paralelos para aprovechar múltiples sockets y núcleos, hay herramientas disponibles para hacerlo.
La documentación de Tornado cubre cada uno de los principales conceptos del framework y todas las principales APIs del modelo. Aunque incluye una aplicación de ejemplo (un rastreador web), es principalmente para demostrar el módulo de colas de Tornado.