POST se usa para crear o procesar recursos, enviando datos en el cuerpo de la petición (request body). En FastAPI, el body se modela con Pydantic, que valida tipos automáticamente y genera documentación en /docs
.
@app.post("/ruta")
201 Created
from fastapi import FastAPI, HTTPException, status
from pydantic import BaseModel, Field
from typing import List
app = FastAPI(
title="API de Productos",
version="1.0.0",
description="Ejemplo de creación de recursos con POST"
)
# --------- Modelos ---------
class Producto(BaseModel):
codigo: int = Field(gt=0, description="Identificador positivo y único")
descripcion: str = Field(min_length=1, max_length=100)
precio: float = Field(gt=0, description="Precio mayor que 0")
# Modelo de salida (opcional, aquí igual al de entrada)
ProductoOut = Producto
# --------- "Base de datos" simulada ---------
productos_db: List[Producto] = [
Producto(codigo=1, descripcion="Teclado", precio=50.0),
Producto(codigo=2, descripcion="Mouse", precio=30.0),
]
# --------- Endpoints ---------
@app.get("/productos", response_model=List[ProductoOut], tags=["productos"])
def listar_productos():
return productos_db
@app.post(
"/productos",
response_model=ProductoOut,
status_code=status.HTTP_201_CREATED,
tags=["productos"]
)
def crear_producto(producto: Producto):
# Verificar si ya existe un producto con el mismo código
for p in productos_db:
if p.codigo == producto.codigo:
raise HTTPException(
status_code=status.HTTP_409_CONFLICT,
detail="Ya existe un producto con ese código"
)
# Agregar a la "base de datos"
productos_db.append(producto)
return producto
Producto
modela lo que el cliente envía (codigo
, descripcion
, precio
).Field
: gt=0
, min_length
, etc.@app.post("/productos")
recibe un Producto
en el body, lo valida y lo guarda en la base simulada.409 Conflict
.201 Created
y el producto creado.Ejecutar:
uvicorn main:app --reload --host 0.0.0.0 --port 8000
Abrir Swagger UI: http://127.0.0.1:8000/docs
Probar POST /productos con un JSON como:
{
"codigo": 3,
"descripcion": "Monitor",
"precio": 200.0
}
Respuesta:
{"codigo":3,"descripcion":"Monitor","precio":200.0}
Luego probar GET /productos para confirmar que se agregó.
Cambiá el modelo de entrada a:
class ProductoCrear(BaseModel):
descripcion: str
precio: float
Y en el endpoint generá el nuevo código automáticamente:
nuevo_codigo = max([p.codigo for p in productos_db] or [0]) + 1
codigo
ya existe.precio <= 0
).response_model
para no exponer campos internos y mantener respuestas consistentes.Extender el problema del traductor del tema anterior para poder enviar una palabra nueva, su traducción y el idioma utilizando POST.
POST /traducir
{
"palabra": "hola",
"traduccion": "hello",
"idioma": "en"
}
idioma
sea uno de: en
, fr
, it
. Si no, responder 400
.