FastAPI no existiría si no fuera por el trabajo previo de otros.
Ha habido muchas herramientas creadas antes que han ayudado a inspirar su creación.
He estado evitando la creación de un nuevo framework durante varios años. Primero intenté resolver todas las funcionalidades cubiertas por FastAPI usando muchos frameworks, plug-ins y herramientas diferentes.
Pero en cierto punto, no hubo otra opción más que crear algo que proporcionara todas estas funcionalidades, tomando las mejores ideas de las herramientas anteriores, y combinándolas de la mejor manera posible, usando características del lenguaje que no estaban disponibles antes (Type hints de Python 3.6+).
Es el framework de Python más popular y es ampliamente confiable. Se usa para construir sistemas como Instagram.
Está relativamente acoplado a bases de datos relacionales (como MySQL o PostgreSQL), así que, tener una base de datos NoSQL (como Couchbase, MongoDB, Cassandra, etc) como motor principal de almacenamiento no es muy fácil.
Fue creado para generar HTML en el backend, no para crear APIs usadas por un frontend moderno (como React, Vue.js y Angular) o por otros sistemas (como dispositivos IoT) que se comunican con él.
Django REST Framework fue creado para ser un toolkit flexible para construir APIs Web usando Django por debajo, para mejorar sus capacidades de API.
Es usado por muchas compañías incluyendo Mozilla, Red Hat y Eventbrite.
Fue uno de los primeros ejemplos de documentación automática de API, y esto fue específicamente una de las primeras ideas que inspiró "la búsqueda de" FastAPI.
Nota
Django REST Framework fue creado por Tom Christie. El mismo creador de Starlette y Uvicorn, en los que se basa FastAPI.
Inspiró a FastAPI a
Tener una interfaz de usuario web automática de documentación de la API.
Flask es un "microframework", no incluye integraciones de base de datos ni muchas de las cosas que vienen por defecto en Django.
Esta simplicidad y flexibilidad permiten hacer cosas como usar bases de datos NoSQL como sistema principal de almacenamiento de datos.
Al ser muy simple, es relativamente intuitivo de aprender, aunque la documentación se vuelve algo técnica en algunos puntos.
También se usa comúnmente para otras aplicaciones que no necesariamente necesitan una base de datos, gestión de usuarios, o cualquiera de las muchas funcionalidades que vienen preconstruidas en Django. Aunque muchas de estas funcionalidades se pueden añadir con plug-ins.
Este desacoplamiento de partes, y ser un "microframework" que podía extenderse para cubrir exactamente lo necesario fue una característica clave que quise conservar.
Dada la simplicidad de Flask, parecía una buena opción para construir APIs. Lo siguiente que había que encontrar era un "Django REST Framework" para Flask.
Inspiró a FastAPI a
Ser un micro-framework. Facilitar mezclar y combinar las herramientas y partes necesarias.
Tener un sistema de enrutamiento simple y fácil de usar.
FastAPI no es realmente una alternativa a Requests. Su alcance es muy diferente.
De hecho, sería común usar Requests dentro de una aplicación FastAPI.
Pero aún así, FastAPI obtuvo bastante inspiración de Requests.
Requests es una librería para interactuar con APIs (como cliente), mientras que FastAPI es una librería para construir APIs (como servidor).
Están, más o menos, en extremos opuestos, complementándose entre sí.
Requests tiene un diseño muy simple e intuitivo, es muy fácil de usar, con valores por defecto sensatos. Pero al mismo tiempo, es muy poderoso y personalizable.
Por eso, como dice en el sitio web oficial:
Requests es uno de los paquetes de Python más descargados de todos los tiempos
La forma de usarlo es muy simple. Por ejemplo, para hacer una petición GET, escribirías:
La principal funcionalidad que quería de Django REST Framework era la documentación automática de la API.
Luego descubrí que había un estándar para documentar APIs, usando JSON (o YAML, una extensión de JSON) llamado Swagger.
Y ya había una interfaz de usuario web para APIs de Swagger creada. Así que, poder generar documentación Swagger para una API permitiría usar esta interfaz de usuario web automáticamente.
En cierto punto, Swagger fue cedido a la Linux Foundation, para ser renombrado como OpenAPI.
Por eso, cuando se habla de la versión 2.0 es común decir "Swagger", y para la versión 3+ "OpenAPI".
Inspiró a FastAPI a
Adoptar y usar un estándar abierto para especificaciones de API, en lugar de un schema personalizado.
E integrar herramientas de interfaz de usuario basadas en estándares:
Estos dos fueron elegidos por ser bastante populares y estables, pero haciendo una búsqueda rápida, podrías encontrar docenas de interfaces de usuario alternativas para OpenAPI (que puedes usar con FastAPI).
Hay varios frameworks REST de Flask, pero después de invertir el tiempo y trabajo en investigarlos, descubrí que muchos están descontinuados o abandonados, con varios problemas pendientes que los hacían inadecuados.
Una de las principales funcionalidades necesarias para los sistemas de API es la "serialización" de datos, que consiste en tomar datos del código (Python) y convertirlos en algo que pueda enviarse a través de la red. Por ejemplo, convertir un objeto que contiene datos de una base de datos en un objeto JSON. Convertir objetos datetime a strings, etc.
Otra gran funcionalidad necesaria para las APIs es la validación de datos, asegurar que los datos sean válidos, dados ciertos parámetros. Por ejemplo, que algún campo sea un int, y no un string cualquiera. Esto es especialmente útil para los datos entrantes.
Sin un sistema de validación de datos, tendrías que hacer todas las comprobaciones a mano, en código.
Estas funcionalidades son para lo que Marshmallow fue creado para proveer. Es una gran librería, y la he usado mucho antes.
Pero fue creado antes de que existieran los Type hints de Python. Así que, para definir cada schema necesitas usar utils y clases específicas proporcionadas por Marshmallow.
Inspiró a FastAPI a
Usar código para definir "schemas" que proporcionen tipos de datos y validación, automáticamente.
Marshmallow y Webargs proporcionan validación, parsing y serialización como plug-ins.
Pero la documentación sigue faltando. Entonces se creó APISpec.
Es un plug-in para muchos frameworks (y hay un plug-in para Starlette también).
La forma en que funciona es que escribes la definición del schema usando formato YAML dentro del docstring de cada función que maneja una ruta.
Y genera schemas OpenAPI.
Así funciona en Flask, Starlette, Responder, etc.
Pero entonces, tenemos de nuevo el problema de tener una micro-sintaxis, dentro de un string de Python (un YAML grande).
El editor no puede ayudar mucho con eso. Y si modificamos parámetros o schemas de Marshmallow y olvidamos modificar también ese docstring YAML, el schema generado sería obsoleto.
Nota
APISpec fue creado por los mismos desarrolladores de Marshmallow.
Es un plug-in de Flask, que une Webargs, Marshmallow y APISpec.
Usa la información de Webargs y Marshmallow para generar automáticamente schemas OpenAPI, usando APISpec.
Es una gran herramienta, muy subestimada. Debería ser mucho más popular que muchos de los plug-ins de Flask que existen. Puede ser debido a que su documentación es demasiado concisa y abstracta.
Esto resolvió tener que escribir YAML (otra sintaxis) dentro de docstrings de Python.
Esta combinación de Flask, Flask-apispec con Marshmallow y Webargs fue mi stack de backend favorito hasta construir FastAPI.
Usarlo llevó a la creación de varios generadores full-stack de Flask. Estos son los principales stacks que yo (y varios equipos externos) he estado usando hasta ahora:
Esto ni siquiera es Python, NestJS es un framework de JavaScript (TypeScript) NodeJS inspirado en Angular.
Logra algo algo similar a lo que se puede hacer con Flask-apispec.
Tiene un sistema de Dependency Injection integrado, inspirado en Angular 2. Requiere pre-registrar los "inyectables" (como todos los demás sistemas de Dependency Injection que conozco), así que, añade verbosidad y repetición de código.
Como los parámetros se describen con tipos TypeScript (similar a los Type hints de Python), el soporte del editor es bastante bueno.
Pero como los datos de TypeScript no se conservan después de la compilación a JavaScript, no puede confiar en los tipos para definir validación, serialización y documentación al mismo tiempo. Debido a esto y algunas decisiones de diseño, para obtener validación, serialización y generación automática de schema, se necesita añadir decoradores en muchos lugares. Así que, se vuelve bastante verboso.
No puede manejar modelos anidados muy bien. Así que, si el body JSON en la petición es un objeto JSON que tiene campos internos que a su vez son objetos JSON anidados, no puede ser documentado y validado adecuadamente.
Inspiró a FastAPI a
Usar tipos de Python para tener gran soporte del editor.
Tener un poderoso sistema de Dependency Injection. Encontrar una manera de minimizar la repetición de código.
Falcon es otro framework de Python de alto rendimiento, está diseñado para ser minimalista, y funcionar como la fundación de otros frameworks como Hug.
Está diseñado para tener funciones que reciben dos parámetros, uno "request" y uno "response". Luego "lees" partes del request, y "escribes" partes al response. Debido a este diseño, no es posible declarar parámetros de petición y bodies con Type hints estándar de Python como parámetros de función.
Así que, la validación de datos, serialización y documentación, tienen que hacerse en código, no automáticamente. O tienen que implementarse como un framework sobre Falcon, como Hug. Esta misma distinción ocurre en otros frameworks que están inspirados en el diseño de Falcon, de tener un objeto request y un objeto response como parámetros.
Inspiró a FastAPI a
Encontrar maneras de obtener gran rendimiento.
Junto con Hug (ya que Hug está basado en Falcon) inspiró a FastAPI a declarar un parámetro response en las funciones.
Aunque en FastAPI es opcional, y se usa principalmente para establecer headers, cookies, y códigos de estado alternativos.
Descubrí Molten en las primeras etapas de construcción de FastAPI. Y tiene ideas bastante similares:
Basado en Type hints de Python.
Validación y documentación a partir de estos tipos.
Sistema de Dependency Injection.
No usa una librería de terceros de validación de datos, serialización y documentación como Pydantic, tiene la suya propia. Así que, estas definiciones de tipos de datos no serían reutilizables tan fácilmente.
Requiere configuraciones un poco más verbosas. Y como está basado en WSGI (en lugar de ASGI), no está diseñado para aprovechar el alto rendimiento proporcionado por herramientas como Uvicorn, Starlette y Sanic.
El sistema de Dependency Injection requiere pre-registro de las dependencias y las dependencias se resuelven basándose en los tipos declarados. Así que, no es posible declarar más de un "componente" que proporcione un tipo cierto.
Las rutas se declaran en un solo lugar, usando funciones declaradas en otros lugares (en lugar de usar decoradores que se pueden colocar justo encima de la función que maneja el endpoint). Esto está más cerca de cómo lo hace Django que de cómo lo hace Flask (y Starlette). Separa en el código cosas que están relativamente acopladas.
Inspiró a FastAPI a
Definir validaciones extra para tipos de datos usando el valor "default" de los atributos del modelo. Esto mejora el soporte del editor, y no estaba disponible en Pydantic antes.
Esto de hecho inspiró la actualización de partes de Pydantic, para soportar el mismo estilo de declaración de validación (toda esta funcionalidad ya está disponible en Pydantic).
Hug fue uno de los primeros frameworks en implementar la declaración de tipos de parámetros de API usando Type hints de Python. Esta fue una gran idea que inspiró a otras herramientas a hacer lo mismo.
Usaba tipos personalizados en sus declaraciones en lugar de tipos estándar de Python, pero aún así fue un gran paso adelante.
También fue uno de los primeros frameworks en generar un schema personalizado declarando toda la API en JSON.
No estaba basado en un estándar como OpenAPI y JSON Schema. Así que no sería directo integrarlo con otras herramientas, como Swagger UI. Pero de nuevo, fue una idea muy innovadora.
Tiene una funcionalidad interesante y poco común: usando el mismo framework, es posible crear APIs y también CLIs.
Como está basado en el estándar anterior para frameworks web síncronos de Python (WSGI), no puede manejar Websockets y otras cosas, aunque también tiene alto rendimiento.
Nota
Hug fue creado por Timothy Crosley, el mismo creador de isort, una gran herramienta para ordenar automáticamente los imports en archivos de Python.
Ideas que inspiraron a FastAPI
Hug inspiró partes de APIStar, y fue una de las herramientas que encontré más prometedoras, junto con APIStar.
Hug ayudó a inspirar a FastAPI a usar Type hints de Python para declarar parámetros, y para generar un schema que defina la API automáticamente.
Hug inspiró a FastAPI a declarar un parámetro response en las funciones para establecer headers y cookies.
Justo antes de decidir construir FastAPI encontré el servidor APIStar. Tenía casi todo lo que buscaba y tenía un gran diseño.
Fue una de las primeras implementaciones de un framework usando Type hints de Python para declarar parámetros y peticiones que vi (antes de NestJS y Molten). La encontré más o menos al mismo tiempo que Hug. Pero APIStar usaba el estándar OpenAPI.
Tenía validación automática de datos, serialización de datos y generación de schema OpenAPI basándose en los mismos Type hints en varios lugares.
Las definiciones de schema del body no usaban los mismos Type hints de Python como Pydantic, era un poco más similar a Marshmallow, así que, el soporte del editor no sería tan bueno, pero aún así, APIStar era la mejor opción disponible.
Tenía los mejores benchmarks de rendimiento en ese momento (solo superado por Starlette).
Al principio, no tenía una interfaz web de documentación automática de la API, pero sabía que podía añadirle Swagger UI.
Tenía un sistema de Dependency Injection. Requería pre-registro de componentes, como otras herramientas discutidas arriba. Pero aún así, era una gran funcionalidad.
Nunca pude usarlo en un proyecto completo, ya que no tenía integración de seguridad, así que, no pude reemplazar todas las funcionalidades que tenía con los generadores full-stack basados en Flask-apispec. Tenía en mi backlog de proyectos crear un pull request añadiendo esa funcionalidad.
Pero entonces, el enfoque del proyecto cambió.
Ya no era un framework web de API, ya que el creador necesitaba enfocarse en Starlette.
Ahora APIStar es un conjunto de herramientas para validar especificaciones OpenAPI, no un framework web.
Nota
APIStar fue creado por Tom Christie. El mismo tipo que creó:
Django REST Framework
Starlette (en el que se basa FastAPI)
Uvicorn (usado por Starlette y FastAPI)
Inspiró a FastAPI a
Existir.
La idea de declarar múltiples cosas (validación de datos, serialización y documentación) con los mismos tipos de Python, que al mismo tiempo proporcionaran gran soporte del editor, fue algo que consideré una idea brillante.
Y después de buscar durante mucho tiempo un framework similar y probar muchas alternativas diferentes, APIStar era la mejor opción disponible.
Luego APIStar dejó de existir como servidor y se creó Starlette, que fue una nueva y mejor fundación para tal sistema. Esa fue la inspiración final para construir FastAPI.
Considero a FastAPI un "sucesor espiritual" de APIStar, mejorando y ampliando las funcionalidades, el sistema de tipos y otras partes, basándome en lo aprendido de todas estas herramientas anteriores.
Pydantic es una librería para definir validación de datos, serialización y documentación (usando JSON Schema) basada en Type hints de Python.
Eso la hace extremadamente intuitiva.
Es comparable a Marshmallow. Aunque es más rápida que Marshmallow en benchmarks. Y como está basada en los mismos Type hints de Python, el soporte del editor es excelente.
FastAPI lo usa para
Manejar toda la validación de datos, serialización de datos y documentación automática de modelos (basada en JSON Schema).
FastAPI luego toma esos datos de JSON Schema y los pone en OpenAPI, aparte de todas las otras cosas que hace.
Starlette es un framework/toolkit ligero ASGI, que es ideal para construir servicios asyncio de alto rendimiento.
Es muy simple e intuitiva. Está diseñada para ser fácilmente extensible, y tener componentes modulares.
Tiene:
Rendimiento seriamente impresionante.
Soporte para WebSocket.
Tareas en segundo plano dentro del proceso.
Eventos de startup y shutdown.
Cliente de pruebas construido sobre HTTPX.
CORS, GZip, Static Files, Streaming responses.
Soporte de Session y Cookie.
100% de cobertura de tests.
100% del código base anotado con tipos.
Pocas dependencias estrictas.
Starlette es actualmente el framework de Python más rápido probado. Solo superado por Uvicorn, que no es un framework, sino un servidor.
Starlette proporciona toda la funcionalidad básica de un microframework web.
Pero no proporciona validación automática de datos, serialización ni documentación.
Esa es una de las principales cosas que FastAPI añade por encima, todo basado en Type hints de Python (usando Pydantic). Eso, más el sistema de Dependency Injection, utilidades de seguridad, generación de schema OpenAPI, etc.
Detalles Técnicos
ASGI es un nuevo "estándar" que está siendo desarrollado por miembros del core team de Django. Aún no es un "estándar de Python" (un PEP), aunque están en proceso de hacerlo.
Sin embargo, ya está siendo usado como un "estándar" por varias herramientas. Esto mejora enormemente la interoperabilidad, ya que podrías cambiar Uvicorn por cualquier otro servidor ASGI (como Daphne o Hypercorn), o podrías añadir herramientas compatibles con ASGI, como python-socketio.
FastAPI lo usa para
Manejar todas las partes centrales web. Añadiendo funcionalidades por encima.
La clase FastAPI misma hereda directamente de la clase Starlette.
Así que, cualquier cosa que puedas hacer con Starlette, puedes hacerla directamente con FastAPI, ya que es básicamente Starlette con esteroides.
Uvicorn es un servidor ASGI extremadamente rápido, construido sobre uvloop y httptools.
No es un framework web, sino un servidor. Por ejemplo, no proporciona herramientas para enrutamiento por paths. Eso es algo que un framework como Starlette (o FastAPI) proporcionaría por encima.
Es el servidor recomendado para Starlette y FastAPI.
FastAPI lo recomienda como
El servidor web principal para ejecutar aplicaciones FastAPI.
También puedes usar la opción de línea de comandos --workers para tener un servidor asíncrono multi-proceso.
Consulta más detalles en la sección de Deployment.