Cree una aplicación con FastAPI para Python
Publicado: 2022-11-29FastAPI 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.
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.
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étodoGET
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.
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.
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.
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.
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 deadmin
yuser
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
extiendeBaseModel
, que luego se importa desdepydantic
. - 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 deList
y pasaste el modeloUser
- Creó una base de datos en memoria con cuatro usuarios, cada uno con los atributos necesarios, como
first_name
,last_name
,gender
yroles
. Al usuarioEunit
se le asignan los roles deadmin
yuser
, mientras que a los otros tres usuarios se les asigna solo el rol deuser
.
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
:
# 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:
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.
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 laid
, que es una variable de ruta que corresponde a la id del usuario. -
async def delete_user(id: UUID):
: crea la funcióndelete_user
, que recupera laid
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 laid
pasada coincide con un usuario en la base de datos. -
db.remove(user)
: si laid
coincide con un usuario, el usuario será eliminado; de lo contrario, se generará unaHTTPException
con un código de estado de 404.
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 unid
de parámetro variable que corresponde al id del usuario. - Creó un método llamado
update_user
, que toma la clase y laid
UpdateUser
. - Usó un bucle
for
para verificar si el usuario asociado con laid
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, comofirst_name
,last_name
oroles
, 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 deCould 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.
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.