Spaces:
Sleeping
Sleeping
File size: 4,636 Bytes
e410613 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 |
# main.py
from fastapi import FastAPI, HTTPException, status
from pydantic import BaseModel
from typing import Optional, List
# --- Modelos de Datos con Pydantic ---
# Pydantic se encarga de la validación y serialización de datos
class Item(BaseModel):
"""Modelo base para un ítem. Todos los campos son requeridos."""
id: int
name: str
description: Optional[str] = None
price: float
class UpdateItem(BaseModel):
"""Modelo para actualizar un ítem. Todos los campos son opcionales."""
name: Optional[str] = None
description: Optional[str] = None
price: Optional[float] = None
# --- Instancia de la Aplicación FastAPI ---
app = FastAPI(
title="API de Ejemplo Completa",
description="Una API de ejemplo con todos los métodos HTTP para demostrar FastAPI, Docker y Hugging Face Spaces.",
version="1.0.0",
)
# --- "Base de Datos" en Memoria ---
# Un diccionario simple para simular una base de datos.
db = {
1: Item(id=1, name="Laptop", description="Un potente portátil para desarrollo", price=1200.50),
2: Item(id=2, name="Teclado Mecánico", description="Un teclado con switches Cherry MX Blue", price=150.75),
}
# --- Endpoints de la API ---
@app.get("/", tags=["Root"])
def read_root():
"""Endpoint principal de bienvenida."""
return {"message": "¡Bienvenido a la API de ejemplo con FastAPI!"}
# --- Métodos para la colección de ítems ---
@app.get("/items", response_model=List[Item], tags=["Items"])
def get_all_items():
"""
GET: Obtiene una lista de todos los ítems en la base de datos.
"""
return list(db.values())
@app.post("/items", response_model=Item, status_code=status.HTTP_201_CREATED, tags=["Items"])
def create_item(item: Item):
"""
POST: Crea un nuevo ítem.
El ID del ítem en el cuerpo de la petición debe ser único.
"""
if item.id in db:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail=f"El ítem con ID {item.id} ya existe."
)
db[item.id] = item
return item
# --- Métodos para un ítem específico ---
@app.get("/items/{item_id}", response_model=Item, tags=["Items"])
def get_item_by_id(item_id: int):
"""
GET: Obtiene un ítem específico por su ID.
"""
if item_id not in db:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"El ítem con ID {item_id} no fue encontrado."
)
return db[item_id]
@app.put("/items/{item_id}", response_model=Item, tags=["Items"])
def update_item_completely(item_id: int, item: Item):
"""
PUT: Actualiza un ítem completamente.
Reemplaza toda la información del ítem existente con la nueva.
"""
if item_id not in db:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"El ítem con ID {item_id} no fue encontrado."
)
# El ID no debe cambiar en una operación PUT
if item_id != item.id:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="El ID del ítem en la URL no coincide con el ID en el cuerpo de la petición."
)
db[item_id] = item
return db[item_id]
@app.patch("/items/{item_id}", response_model=Item, tags=["Items"])
def update_item_partially(item_id: int, item_update: UpdateItem):
"""
PATCH: Actualiza un ítem parcialmente.
Solo actualiza los campos proporcionados en el cuerpo de la petición.
"""
if item_id not in db:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"El ítem con ID {item_id} no fue encontrado."
)
stored_item_data = db[item_id].dict()
update_data = item_update.dict(exclude_unset=True) # Obtiene solo los campos que se enviaron
updated_item_data = stored_item_data.copy()
updated_item_data.update(update_data)
db[item_id] = Item(**updated_item_data)
return db[item_id]
@app.delete("/items/{item_id}", status_code=status.HTTP_204_NO_CONTENT, tags=["Items"])
def delete_item(item_id: int):
"""
DELETE: Elimina un ítem por su ID.
Devuelve un código 204 sin contenido si tiene éxito.
"""
if item_id not in db:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"El ítem con ID {item_id} no fue encontrado."
)
del db[item_id]
# No se devuelve contenido, solo el código de estado 204
return |