| """ |
| 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}") |
|
|
|
|
| |
| 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}") |
|
|
| |
| 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}") |
|
|
| |
| 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() |
| |
| 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}") |
|
|
| |
| 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}") |
|
|
| |
| 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}") |
|
|
| |
| 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") |
|
|