Capítulo 3.4: Operaciones CRUD para naves espaciales
Tiempo de estudio: 1 hora
1. CRUD: Ciclo completo de gestión de misiones espaciales
Hasta ahora, solo hemos leído datos (Read
). Pero un verdadero Centro de Control de Misiones debe ser capaz de todo:
- Create (Crear): Lanzar un nuevo satélite a órbita.
- Read (Leer): Solicitar el estado de una nave existente.
- Update (Actualizar): Corregir la órbita o actualizar el software.
- Delete (Eliminar): Retirar un satélite antiguo de órbita.
Estas cuatro operaciones — CRUD — constituyen la base de la mayoría de las API. En este capítulo, implementaremos el ciclo completo para gestionar nuestra flota.
2. Create: Lanzamiento de una nueva nave (POST)
Para crear una nueva nave espacial, utilizaremos el método POST
. Los datos para la nueva nave se enviarán en el cuerpo de la solicitud en formato JSON.
Paso 1: Creamos un nuevo modelo Pydantic para los datos entrantes
¿Por qué se necesita un nuevo modelo? Porque al crear una nave, no conocemos su id
— este debe ser asignado por el servidor.
Añada este modelo a main.py
:
# main.py
from pydantic import BaseModel, Field
class SpaceshipCreate(BaseModel):
"""Modelo para crear una nueva nave (sin ID)."""
name: str = Field(..., min_length=3, max_length=50)
type: str
launch_year: int = Field(..., gt=1950)
status: str
Spaceship
, pero se utilizará para la validación de datos entrantes.
Paso 2: Implementamos el endpoint POST /spaceships
# main.py
import random # Añada esta importación al principio del archivo
# ... resto del código ...
@app.post("/spaceships", response_model=Spaceship, status_code=201)
def create_spaceship(ship: SpaceshipCreate):
"""
Añade una nueva nave espacial al registro.
"""
# Generamos un nuevo ID único para la nave
new_id = max(db_spaceships.keys() or [0]) + 1
# Creamos un objeto de nave que corresponde al modelo completo Spaceship
new_ship = Spaceship(id=new_id, **ship.dict())
# Guardamos en nuestra "base de datos"
db_spaceships[new_id] = new_ship.dict()
return new_ship
@app.post(...)
: Usamos el decorador para solicitudesPOST
.status_code=201
: Indicamos que, en caso de creación exitosa, se debe devolver el estado201 Created
.ship: SpaceshipCreate
: ¡Aquí está la magia! FastAPI tomará automáticamente el cuerpo de la solicitud (JSON), lo validará según el modeloSpaceshipCreate
y lo pasará a la función como un objetoship
.new_id = ...
: Lógica simple para generar un nuevo ID.**ship.dict()
: "Desempaquetamos" los datos del modeloship
recibido en nuestro modelo completo.response_model=Spaceship
: La respuesta corresponderá al modelo completo, incluyendo elid
.
3. Update: Corrección de rumbo (PUT)
Para la actualización completa de un recurso existente, se utiliza el método PUT
.
Implementamos el endpoint PUT /spaceships/{ship_id}
:
# main.py
from fastapi import FastAPI, HTTPException # Actualice la importación
# ... resto del código ...
@app.put("/spaceships/{ship_id}", response_model=Spaceship)
def update_spaceship(ship_id: int, ship_update: SpaceshipCreate):
"""
Actualiza completamente los datos de una nave espacial.
"""
if ship_id not in db_spaceships:
raise HTTPException(status_code=404, detail="Nave espacial no encontrada")
updated_ship = Spaceship(id=ship_id, **ship_update.dict())
db_spaceships[ship_id] = updated_ship.dict()
return updated_ship
ship_update: SpaceshipCreate
: Volvemos a usar nuestro modelo para la validación de los datos entrantes.HTTPException
: Si no se encuentra una nave con eseid
, "lanzamos" una excepción estándar de FastAPI que se convertirá en una bonita respuesta JSON con el código404
.
4. Delete: Salida de órbita (DELETE)
Para eliminar un recurso, se utiliza el método DELETE
. Normalmente, este tipo de endpoint no devuelve un cuerpo de respuesta.
Implementamos el endpoint DELETE /spaceships/{ship_id}
:
# main.py
from fastapi import FastAPI, HTTPException, Response, status # Actualice la importación
# ... resto del código ...
@app.delete("/spaceships/{ship_id}", status_code=status.HTTP_204_NO_CONTENT)
def delete_spaceship(ship_id: int):
"""
Elimina una nave espacial del registro.
"""
if ship_id not in db_spaceships:
raise HTTPException(status_code=404, detail="Nave espacial no encontrada")
del db_spaceships[ship_id]
# Devolvemos una respuesta vacía con el estado 204
return Response(status_code=status.HTTP_204_NO_CONTENT)
status_code=status.HTTP_204_NO_CONTENT
: Indicamos explícitamente el estado204 No Content
.del db_spaceships[ship_id]
: Eliminamos la entrada de nuestro diccionario.return Response(...)
: Devolvemos una respuesta vacía, ya que el cliente no necesita datos sobre el objeto eliminado.
5. Pruebas del ciclo completo en /docs
Su uvicorn
debería haberse recargado.
- Abra
http://127.0.0.1:8000/docs
. ¡Ahora tiene un conjunto completo de operaciones CRUD! - POST: Expanda el endpoint
POST /spaceships
, haga clic en "Try it out", rellene el cuerpo JSON (por ejemplo, cree "James Webb Telescope") y haga clic en "Execute". Debería recibir una respuesta201
con los datos del nuevo telescopio. - GET: Ahora ejecute
GET /spaceships
. Su nuevo telescopio debería aparecer en la lista. - PUT: Use el ID del nuevo telescopio para actualizar sus datos a través de
PUT /spaceships/{ship_id}
. Por ejemplo, cambie su estado. - DELETE: Use el mismo ID para eliminar el telescopio a través de
DELETE /spaceships/{ship_id}
. Debería recibir una respuesta vacía con el estado204
. - Verificación: Ejecute
GET /spaceships
de nuevo para asegurarse de que el telescopio ha sido eliminado de la lista.
Cuestionario de repaso
🚀 Resumen del capítulo:
¡Has implementado un ciclo CRUD completo y has transformado tu API de un simple "tablero informativo" en un completo Centro de Control de Flota!
- ✅ Create:
POST /spaceships
para lanzar nuevas naves. - ✅ Read:
GET /spaceships
yGET /spaceships/{id}
para obtener datos. - ✅ Update:
PUT /spaceships/{id}
para actualizar misiones. - ✅ Delete:
DELETE /spaceships/{id}
para dar de baja naves.
¡Tu flota bajo control total! En el siguiente capítulo veremos cómo FastAPI creó automáticamente para nosotros una detallada "guía de operación": la documentación interactiva de Swagger.
📌 Verificación:
- Todos los 5 endpoints (
GET
(2),POST
,PUT
,DELETE
) son visibles y funcionan en/docs
.- Puedes crear, leer, actualizar y eliminar un recurso con éxito.
- Al solicitar un ID inexistente, se devuelve un error
404
.⚠️ Si hay errores:
NameError
: Verifica que has importadoHTTPException
,Response
,status
.KeyError
: Probablemente estás intentando acceder a un ID que ya ha sido eliminado.- Funcionamiento incorrecto de
PUT
oPOST
: Asegúrate de que estás utilizando el modelo Pydantic correcto en el argumento de la función (SpaceshipCreate
). ```