Cree una aplicación con FastAPI para Python

Publicado: 2022-11-29

FastAPI es un marco web rápido y liviano para crear interfaces de programación de aplicaciones modernas con Python 3.6 y superior. En este tutorial, repasaremos los aspectos básicos de la creación de una aplicación con FastAPI y obtendrá una idea de por qué fue nominado como uno de los mejores marcos de código abierto de 2021.

Una vez que esté listo para desarrollar sus propias aplicaciones FastAPI, no tendrá que buscar muy lejos para encontrar un lugar para alojarlas. Los servicios de alojamiento de aplicaciones y alojamiento de bases de datos de Kinsta proporcionan una plataforma como servicio que es fuerte en Python.

Primero aprendamos lo básico.


Ventajas de FastAPI

A continuación se presentan algunas de las ventajas que aporta el marco FastAPI a un proyecto.

  • Velocidad: como su nombre lo indica, FastAPI es un marco muy rápido. Su velocidad es comparable a la de Go y Node.js, que generalmente se consideran entre las opciones más rápidas para crear API.
  • Fácil de aprender y codificar: FastAPI ya ha descubierto casi todo lo que necesitará para crear una API lista para producción. Como desarrollador que usa FastAPI, no necesita codificar todo desde cero. Con solo unas pocas líneas de código, puede tener una API RESTful lista para su implementación.
  • Documentación completa: FastAPI utiliza los estándares de documentación de OpenAPI, por lo que la documentación se puede generar dinámicamente. Esta documentación proporciona información detallada sobre los puntos finales, las respuestas, los parámetros y los códigos de retorno de FastAPI.
  • API con menos errores: FastAPI admite la validación de datos personalizados, lo que permite a los desarrolladores crear API con menos errores. Los desarrolladores de FastAPI se jactan de que el marco da como resultado menos errores inducidos por humanos, hasta un 40% menos.
  • Sugerencias de tipo: el módulo de tipos se introdujo en Python 3.5. Esto le permite declarar el type de una variable. Cuando se declara el tipo de una variable, los IDE pueden brindar un mejor soporte y predecir errores con mayor precisión.
¿Está considerando FastAPI para su próximo proyecto? Mira sus ventajas en esta guía: Click to Tweet

Cómo comenzar con FastAPI

Para seguir este tutorial y comenzar con FastAPI, primero deberá hacer algunas cosas.

Asegúrese de tener un editor de texto/IDE de programador, como Visual Studio Code. Otras opciones incluyen Sublime Text y Espresso.

Es una práctica común que sus aplicaciones de Python y sus instancias se ejecuten en entornos virtuales. Los entornos virtuales permiten que diferentes conjuntos de paquetes y configuraciones se ejecuten simultáneamente y evitan conflictos debido a versiones de paquetes incompatibles.

Para crear un entorno virtual, abra su terminal y ejecute este comando:

 $ python3 -m venv env

También deberá activar el entorno virtual. El comando para hacerlo variará según el sistema operativo y el shell que esté utilizando. Estos son algunos ejemplos de activación de la CLI para varios entornos:

 # On Unix or MacOS (bash shell): /path/to/venv/bin/activate # On Unix or MacOS (csh shell): /path/to/venv/bin/activate.csh # On Unix or MacOS (fish shell): /path/to/venv/bin/activate.fish # On Windows (command prompt): \path\to\venv\Scripts\activate.bat # On Windows (PowerShell): \path\to\venv\Scripts\Activate.ps1

(Algunos IDE compatibles con Python también se pueden configurar para activar el entorno virtual actual).

Ahora, instale FastAPI:

 $ pip3 install fastapi

FastAPI es un marco para crear API, pero para probar sus API necesitará un servidor web local. Uvicorn es un servidor web de interfaz de puerta de enlace de servidor asíncrono (ASGI) ultrarrápido para Python que es excelente para el desarrollo. Para instalar Uvicorn, ejecute este comando:

 $ pip3 install "uvicorn[standard]"

Luego de una instalación exitosa, cree un archivo llamado main.py dentro del directorio de trabajo de su proyecto. Este archivo será el punto de entrada de su aplicación.

El diseño de un proyecto FastAPI dentro de un IDE.
Vista de un proyecto FastAPI básico dentro de un IDE.

Un ejemplo rápido de FastAPI

Probará su instalación de FastAPI configurando rápidamente un punto final de ejemplo. En su archivo main.py , pegue el siguiente código y luego guarde el archivo:

 # main.py from fastapi import FastAPI app = FastAPI() @app.get("/") async def root(): return {"greeting":"Hello world"}

El fragmento de código anterior crea un punto final básico de FastAPI. A continuación se muestra un resumen de lo que hace cada línea:

  • from fastapi import FastAPI : la clase FastAPI Python proporciona la funcionalidad para su API.
  • app = FastAPI() : Esto crea una instancia de FastAPI.
  • @app.get("/") : Este es un decorador de python que especifica a FastAPI que la función debajo está a cargo del manejo de solicitudes.
  • @app.get("/") : Este es un decorador que especifica la ruta. Esto crea un método GET en la ruta del sitio. Luego, el resultado es devuelto por la función envuelta.
  • Otras posibles operaciones que se utilizan para comunicarse incluyen @app.post() , @app.put() , @app.delete() , @app.options() , @app.head() , @app.patch() y @app.trace() .

En el directorio de archivos, ejecute el siguiente comando en su terminal para iniciar el servidor API:

 $ uvicorn main:app --reload

En este comando, main es el nombre de su módulo. El objeto de la app es una instancia de su aplicación y se importa al servidor ASGI. El indicador --reload le dice al servidor que se recargue automáticamente cuando realice algún cambio.

Debería ver algo como esto en su terminal:

 $ uvicorn main:app --reload INFO: Will watch for changes in these directories: ['D:\\WEB DEV\\Eunit\\Tests\\fast-api'] INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) INFO: Started reloader process [26888] using WatchFiles INFO: Started server process [14956] INFO: Waiting for application startup. INFO: Application startup complete.

En su navegador, navegue a http://localhost:8000 para confirmar que su API está funcionando. Debería ver "Hola": "Mundo" como un objeto JSON en la página. Esto ilustra lo fácil que es crear una API con FastAPI. Todo lo que tenía que hacer era definir una ruta y devolver su diccionario de Python, como se ve en la línea seis del fragmento anterior.

Una aplicación FastAPI Hello World que se ejecuta en un navegador web.
Aplicación FastAPI Hello World en un navegador web.

Uso de sugerencias de tipo

Si usa Python, está acostumbrado a anotar variables con tipos de datos básicos como int , str , float y bool . Sin embargo, a partir de la versión 3.9 de Python, se introdujeron estructuras de datos avanzadas. Esto le permite trabajar con estructuras de datos como dictionaries , tuples y lists . Con las sugerencias de tipo de FastAPI, puede estructurar el esquema de sus datos usando modelos pydantic y luego, usar los modelos pydantic para escribir sugerencias y beneficiarse de la validación de datos que se proporciona.

En el siguiente ejemplo, se demuestra el uso de sugerencias de tipo en Python con una calculadora de precio de comida simple, calculate_meal_fee :

 def calculate_meal_fee(beef_price: int, meal_price: int) -> int: total_price: int = beef_price + meal_price return total_price print("Calculated meal fee", calculate_meal_fee(75, 19))

Tenga en cuenta que las sugerencias de tipo no cambian la forma en que se ejecuta su código.

Documentación de la API interactiva de FastAPI

FastAPI utiliza la interfaz de usuario de Swagger para proporcionar documentación API interactiva automática. Para acceder a él, vaya a http://localhost:8000/docs y verá una pantalla con todos sus puntos finales, métodos y esquemas.

Captura de pantalla de la interfaz de usuario de Swagger para documentación.
Documentación de Swagger UI para FastAPI.

FastAPI proporciona esta documentación API automática basada en navegador y no necesita hacer nada más para aprovecharla.

Una documentación alternativa de API basada en navegador, también proporcionada por FastAPI, es Redoc. Para acceder a Redoc, vaya a http://localhost:8000/redoc , donde se le presentará una lista de sus puntos finales, los métodos y sus respectivas respuestas.

Captura de pantalla de la interfaz Redoc para documentación.
Documentación de Redoc para FastAPI.

Configuración de rutas en FastAPI

El decorador @app le permite especificar el método de la ruta, como @app.get o @app.post , y admite GET , POST , PUT y DELETE , así como las opciones menos comunes, HEAD , PATCH y TRACE .

Creación de su aplicación con FastAPI

En este tutorial, se le guiará a través de la creación de una aplicación CRUD con FastAPI. La aplicación podrá:

  • crear un usuario
  • Leer el registro de la base de datos de un usuario
  • Actualizar un usuario existente
  • Eliminar un usuario en particular

Para ejecutar estas operaciones CRUD, creará métodos que expongan los puntos finales de la API. El resultado será una base de datos en memoria que puede almacenar una lista de usuarios.

Diagrama de la estructura de la tabla de la base de datos para ejemplos CRUD.
Estructura de tabla de base de datos para ejemplos CRUD.

Utilizará la biblioteca pydantic para realizar la validación de datos y la gestión de la configuración mediante anotaciones de tipo Python. A los efectos de este tutorial, declarará la forma de sus datos como clases con atributos.

Este tutorial utilizará la base de datos en memoria. Esto es para que pueda comenzar rápidamente a usar FastAPI para crear sus API. Sin embargo, para la producción, puede utilizar cualquier base de datos de su elección, como PostgreSQL, MySQL, SQLite o incluso Oracle.

Construyendo la aplicación

Comenzará por crear su modelo de usuario. El modelo de usuario tendrá los siguientes atributos:

  • id : un identificador único universal (UUID)
  • first_name : El primer nombre del usuario
  • last_name : El apellido del usuario
  • gender : el género del usuario
  • roles , que es una lista que contiene roles de admin y user

Comience creando un nuevo archivo llamado models.py en su directorio de trabajo, luego pegue el siguiente código en models.py para crear su modelo:

 # models.py from typing import List, Optional from uuid import UUID, uuid4 from pydantic import BaseModel from enum import Enum from pydantic import BaseModel class Gender(str, Enum): male = "male" female = "female" class Role(str, Enum): admin = "admin" user = "user" class User(BaseModel): id: Optional[UUID] = uuid4() first_name: str last_name: str gender: Gender roles: List[Role]

En el código de arriba:

  • Su clase User extiende BaseModel , que luego se importa desde pydantic .
  • Usted definió los atributos del usuario, como se discutió anteriormente.

El siguiente paso es crear su base de datos. Reemplace el contenido de su archivo main.py con el siguiente código:

 # main.py from typing import List from uuid import uuid4 from fastapi import FastAPI from models import Gender, Role, User app = FastAPI() db: List[User] = [ User( id=uuid4(), first_name="John", last_name="Doe", gender=Gender.male, roles=[Role.user], ), User( id=uuid4(), first_name="Jane", last_name="Doe", gender=Gender.female, roles=[Role.user], ), User( id=uuid4(), first_name="James", last_name="Gabriel", gender=Gender.male, roles=[Role.user], ), User( id=uuid4(), first_name="Eunit", last_name="Eunit", gender=Gender.male, roles=[Role.admin, Role.user], ), ]

En main.py :

  • Inicializaste db con un tipo de List y pasaste el modelo User
  • Creó una base de datos en memoria con cuatro usuarios, cada uno con los atributos necesarios, como first_name , last_name , gender y roles . Al usuario Eunit se le asignan los roles de admin y user , mientras que a los otros tres usuarios se les asigna solo el rol de user .

Leer registros de base de datos

Configuró con éxito su base de datos en memoria y la completó con usuarios, por lo que el siguiente paso es configurar un punto final que devolverá una lista de todos los usuarios. Aquí es donde entra FastAPI.

En su archivo main.py , pegue el siguiente código justo debajo de su terminal Hello World :

¿Luchando con el tiempo de inactividad y los problemas de WordPress? ¡Kinsta es la solución de hospedaje diseñada para ahorrarle tiempo! Echa un vistazo a nuestras características
 # main.py @app.get("/api/v1/users") async def get_users(): return db

Este código define el punto final /api/v1/users y crea una función asíncrona, get_users , que devuelve todo el contenido de la base de datos, db .

Guarde su archivo y podrá probar su punto final de usuario. Ejecute el siguiente comando en su terminal para iniciar el servidor API:

 $ uvicorn main:app --reload

En su navegador, vaya a http://localhost:8000/api/v1/users . Esto debería devolver una lista de todos sus usuarios, como se ve a continuación:

Captura de pantalla de los datos de usuario devueltos por la solicitud FastAPI GET.
Datos de usuario recuperados por la solicitud de lectura de la base de datos FastAPI.

En esta etapa, su archivo main.py se verá así:

 # main.py from typing import List from uuid import uuid4 from fastapi import FastAPI from models import Gender, Role, User app = FastAPI() db: List[User] = [ User( id=uuid4(), first_name="John", last_name="Doe", gender=Gender.male, roles=[Role.user], ), User( id=uuid4(), first_name="Jane", last_name="Doe", gender=Gender.female, roles=[Role.user], ), User( id=uuid4(), first_name="James", last_name="Gabriel", gender=Gender.male, roles=[Role.user], ), User( id=uuid4(), first_name="Eunit", last_name="Eunit", gender=Gender.male, roles=[Role.admin, Role.user], ), ] @app.get("/") async def root(): return {"Hello": "World",} @app.get("/api/v1/users") async def get_users(): return db

Crear registros de base de datos

El siguiente paso es crear un punto final para crear un nuevo usuario en su base de datos. Pegue el siguiente fragmento en su archivo main.py :

 # main.py @app.post("/api/v1/users") async def create_user(user: User): db.append(user) return {"id": user.id}

En este fragmento, definió el punto final para enviar un nuevo usuario e hizo uso del decorador @app.post para crear un método POST .

También creó la función create_user , que acepta el user del modelo User , y agregó (agregó) el user recién creado a la base de datos, db . Finalmente, el punto final devuelve un objeto JSON de la id del usuario recién creado.

Tendrá que usar la documentación API automática proporcionada por FastAPI para probar su punto final, como se ve arriba. Esto se debe a que no puede realizar una solicitud de publicación utilizando el navegador web. Navegue a http://localhost:8000/docs para probar usando la documentación proporcionada por SwaggerUI.

Captura de pantalla que muestra los parámetros para la solicitud POST de FastAPI.
Parámetros para una solicitud POST de FastAPI.

Eliminar registros de la base de datos

Dado que está creando una aplicación CRUD, su aplicación deberá tener la capacidad de eliminar un recurso específico. Para este tutorial, creará un punto final para eliminar un usuario.

Pegue el siguiente código en su archivo main.py :

 # main.py from uuid import UUID from fastapi HTTPException @app.delete("/api/v1/users/{id}") async def delete_user(id: UUID): for user in db: if user.id == id: db.remove(user) return raise HTTPException( status_code=404, detail=f"Delete user failed, id {id} not found." )

Aquí hay un desglose línea por línea de cómo funciona ese código:

  • @app.delete("/api/v1/users/{id}") : creó el extremo de eliminación con el @app.delete() . La ruta sigue siendo /api/v1/users/{id} , pero luego recupera la id , que es una variable de ruta que corresponde a la id del usuario.
  • async def delete_user(id: UUID): : crea la función delete_user , que recupera la id de la URL.
  • for user in db: : Esto le dice a la aplicación que recorra los usuarios en la base de datos y verifique si la id pasada coincide con un usuario en la base de datos.
  • db.remove(user) : si la id coincide con un usuario, el usuario será eliminado; de lo contrario, se generará una HTTPException con un código de estado de 404.
Captura de pantalla que muestra los parámetros para la solicitud FastAPI DELETE.
Parámetros para una solicitud FastAPI DELETE.

Actualizar registros de base de datos

Va a crear un punto final para actualizar los detalles de un usuario. Los detalles que se pueden actualizar incluyen los siguientes parámetros: first_name , last_name y roles .

En su archivo models.py , pegue el siguiente código debajo de su modelo User , es decir, después de la clase User(BaseModel): :

 # models.py class UpdateUser(BaseModel): first_name: Optional[str] last_name: Optional[str] roles: Optional[List[Role]]

En este fragmento, la clase UpdateUser extiende BaseModel . Luego configura los parámetros de usuario actualizables, como first_name , last_name y roles , para que sean opcionales.

Ahora creará un punto final para actualizar los detalles de un usuario en particular. En su archivo main.py , pegue el siguiente código después de @app.delete decorador:

 # main.py @app.put("/api/v1/users/{id}") async def update_user(user_update: UpdateUser, id: UUID): for user in db: if user.id == id: if user_update.first_name is not None: user.first_name = user_update.first_name if user_update.last_name is not None: user.last_name = user_update.last_name if user_update.roles is not None: user.roles = user_update.roles return user.id raise HTTPException(status_code=404, detail=f"Could not find user with id: {id}")

En el código anterior, ha hecho lo siguiente:

  • Creado @app.put("/api/v1/users/{id}") , el punto final de actualización. Tiene un id de parámetro variable que corresponde al id del usuario.
  • Creó un método llamado update_user , que toma la clase y la id UpdateUser .
  • Usó un bucle for para verificar si el usuario asociado con la id pasada está en la base de datos.
  • Marcado si alguno de los parámetros del usuario is not None (no es nulo). Si algún parámetro, como first_name , last_name o roles , no es nulo, entonces se actualiza.
  • Si la operación tiene éxito, se devuelve el ID de usuario.
  • Si no se encuentra el usuario, se genera una excepción HTTPException con un código de estado de 404 y un mensaje de Could not find user with id: {id} .

Para probar este punto final, asegúrese de que su servidor Uvicorn se esté ejecutando. Si no se está ejecutando, ingrese este comando:

 uvicorn main:app --reload

A continuación se muestra una captura de pantalla de la prueba.

Captura de pantalla que muestra los parámetros para una solicitud de ACTUALIZACIÓN.
Parámetros para una solicitud de ACTUALIZACIÓN de FastAPI.

Vea cómo FastAPI podría reducir los errores inducidos por humanos hasta en un 40 % Comience aquí mismo: haga clic para twittear

Resumen

En este tutorial, aprendió sobre el marco FastAPI para Python y vio por sí mismo lo rápido que puede poner en marcha una aplicación impulsada por FastAPI. Aprendió a crear puntos finales de la API CRUD utilizando el marco: crear, leer, actualizar y eliminar registros de la base de datos.

Ahora, si desea llevar el desarrollo de su aplicación web al siguiente nivel, asegúrese de consultar la plataforma de Kinsta para alojamiento de aplicaciones y alojamiento de bases de datos. Al igual que FastAPI, es poderosamente simple.