SMV / test_api.py
Tyan1988's picture
Subo modelo SMV completo
9885230
"""
test_api.py
===========
Script de prueba para verificar todos los endpoints de la API.
Requiere que la API estΓ© corriendo:
python app.py
Ejecutar:
python test_api.py
"""
import json
import random
import numpy as np
import requests
BASE_URL = "http://127.0.0.1:5000"
CLASS_NAMES = [
"T-shirt/top", "Trouser", "Pullover", "Dress", "Coat",
"Sandal", "Shirt", "Sneaker", "Bag", "Ankle boot",
]
def separator(title: str):
print(f"\n{'─'*60}")
print(f" {title}")
print(f"{'─'*60}")
# ── 1. /health ────────────────────────────────────────────────────────────────
separator("GET /health")
try:
r = requests.get(f"{BASE_URL}/health", timeout=5)
print(f"Status HTTP: {r.status_code}")
print(json.dumps(r.json(), indent=2, ensure_ascii=False))
except Exception as e:
print(f"❌ Error: {e}")
# ── 2. /model/info ────────────────────────────────────────────────────────────
separator("GET /model/info")
try:
r = requests.get(f"{BASE_URL}/model/info", timeout=5)
print(f"Status HTTP: {r.status_code}")
print(json.dumps(r.json(), indent=2, ensure_ascii=False))
except Exception as e:
print(f"❌ Error: {e}")
# ── 3. /predict β€” imagen aleatoria ────────────────────────────────────────────
separator("POST /predict (imagen aleatoria 784 pΓ­xeles)")
try:
pixels = [random.randint(0, 255) for _ in range(784)]
payload = {"pixels": pixels}
r = requests.post(f"{BASE_URL}/predict", json=payload, timeout=10)
print(f"Status HTTP: {r.status_code}")
resp = r.json()
# Mostrar solo top-3 probabilidades para no saturar la consola
top3 = sorted(resp.get("probabilities", {}).items(), key=lambda x: -x[1])[:3]
print(f" PredicciΓ³n : {resp.get('class_name')} (id={resp.get('class_id')})")
print(f" Confianza : {resp.get('confidence'):.2%}")
print(f" Top-3 probs: {dict(top3)}")
print(f" Inferencia : {resp.get('inference_ms')} ms")
except Exception as e:
print(f"❌ Error: {e}")
# ── 4. /predict β€” payload invΓ‘lido (menos de 784) ─────────────────────────────
separator("POST /predict (validaciΓ³n: 100 pΓ­xeles β†’ debe fallar)")
try:
pixels = [128] * 100
r = requests.post(f"{BASE_URL}/predict", json={"pixels": pixels}, timeout=5)
print(f"Status HTTP: {r.status_code} (esperado 400)")
print(json.dumps(r.json(), indent=2, ensure_ascii=False))
except Exception as e:
print(f"❌ Error: {e}")
# ── 5. /predict/batch ─────────────────────────────────────────────────────────
separator("POST /predict/batch (3 imΓ‘genes aleatorias)")
try:
batch = [[random.randint(0, 255) for _ in range(784)] for _ in range(3)]
r = requests.post(f"{BASE_URL}/predict/batch", json={"images": batch}, timeout=30)
print(f"Status HTTP: {r.status_code}")
resp = r.json()
print(f" Total imΓ‘genes : {resp.get('count')}")
print(f" Inferencia : {resp.get('inference_ms')} ms")
for i, result in enumerate(resp.get("results", [])):
print(f" [{i}] {result['class_name']:15s} confianza={result['confidence']:.2%}")
except Exception as e:
print(f"❌ Error: {e}")
# ── 6. /predict con datos reales de Fashion-MNIST ─────────────────────────────
separator("POST /predict (imagen real de Fashion-MNIST via sklearn)")
try:
from sklearn.datasets import fetch_openml
print(" Cargando 5 muestras de Fashion-MNIST para verificaciΓ³n real...")
X_real, y_real = fetch_openml(
"Fashion-MNIST", version=1, return_X_y=True, as_frame=False
)
sample_idx = [0, 1000, 5000, 10000, 20000]
correct = 0
for idx in sample_idx:
pixels = X_real[idx].tolist()
true_lbl = int(y_real[idx])
r = requests.post(f"{BASE_URL}/predict", json={"pixels": pixels}, timeout=10)
pred_id = r.json().get("class_id")
match = "βœ…" if pred_id == true_lbl else "❌"
if pred_id == true_lbl:
correct += 1
print(f" [{idx:>6}] Real: {CLASS_NAMES[true_lbl]:15s} | "
f"Pred: {CLASS_NAMES[pred_id]:15s} {match}")
print(f"\n Correctas: {correct}/{len(sample_idx)}")
except ImportError:
print(" sklearn no disponible en este entorno para la prueba real.")
except Exception as e:
print(f"❌ Error: {e}")
print(f"\n{'═'*60}")
print(" Pruebas finalizadas")
print(f"{'═'*60}\n")