Imported from nicomaure/API-Model-Checker (
AGENTS.md). Install upstream withnpx skills add nicomaure/API-Model-Checker. Copyright stays with the author.
AGENTS.md - Instrucciones para Agentes de IA
Instrucciones para agentes de IA (Claude, Copilot, Cursor, etc.) trabajando en este repositorio.
Descripción del Proyecto
API Model Checker - Aplicación web para consultar los modelos disponibles en diferentes APIs de IA.
- Framework: Flask (Python)
- Frontend: HTML5, CSS3 (diseño oscuro minimalista), JavaScript vanilla
- Lenguaje: Python 3.8+
- Dependencias: Flask
Proveedores soportados
Anthropic, OpenAI, Google Gemini, Mistral AI, Groq, OpenRouter, Cohere, Together AI, Perplexity
Comandos de Build / Run / Test
Instalación
# Crear entorno virtual (recomendado)
python -m venv venv
source venv/bin/activate # Linux/Mac
# venv\Scripts\activate # Windows
# Instalar dependencias
pip install -r requirements.txt
Ejecutar la Aplicación
# Modo desarrollo
python app.py
# La app estará en http://localhost:5000
Testing
# Ejecutar todos los tests
pytest
# Ejecutar un archivo de test específico
pytest tests/test_app.py
# Ejecutar un test específico
pytest tests/test_app.py::test_check_models -v
# Tests con patrón
pytest -k "test_api" -v
# Con cobertura
pytest --cov=. --cov-report=term-missing
Linting y Formateo
# Formatear con black
black .
# Verificar formato
black --check .
# Lint con ruff
ruff check .
# Auto-fix
ruff check --fix .
# Type checking
mypy app.py
Estructura del Proyecto
modelosapi/
├── app.py # Backend Flask - endpoints y lógica de APIs
├── requirements.txt # Dependencias Python
├── AGENTS.md # Este archivo
├── templates/
│ └── index.html # Template principal
├── static/
│ ├── css/
│ │ └── styles.css # Estilos (tema oscuro)
│ └── js/
│ └── app.js # JavaScript del frontend
└── tests/ # Tests (a crear)
Guías de Estilo de Código
Idioma
- Comentarios de código: Español
- Mensajes al usuario: Español
- Variables/funciones: snake_case (inglés o español, consistente por archivo)
- Documentación: Español
Imports (Python)
# 1. Standard library (alfabéticamente)
import json
import os
import urllib.request
# 2. Third-party (después de línea en blanco)
from flask import Flask, jsonify, request
# 3. Local imports (después de línea en blanco)
from .utils import helper
Formato
- Línea máxima: 88 caracteres
- Indentación: 4 espacios
- Líneas en blanco: 2 entre funciones/clases top-level
- Newline final: Siempre
Convenciones de Nombres
| Elemento | Convención | Ejemplo |
|---|---|---|
| Funciones | snake_case |
get_anthropic_models() |
| Variables | snake_case |
api_key |
| Constantes | UPPER_SNAKE_CASE |
PROVIDERS |
| Clases | PascalCase |
ModelChecker |
| Archivos Python | snake_case.py |
app.py |
| CSS classes | kebab-case |
.provider-card |
| JS funciones | camelCase |
checkModels() |
Type Hints
def get_models(api_key: str) -> list[dict]:
"""Obtiene la lista de modelos."""
models: list[dict] = []
return models
Manejo de Errores
# Excepciones específicas primero
try:
response = make_request(url, headers)
except urllib.error.HTTPError as e:
if e.code == 401:
return jsonify({"error": "API Key inválida"}), 401
return jsonify({"error": f"Error HTTP {e.code}"}), e.code
except urllib.error.URLError as e:
return jsonify({"error": f"Error de conexión: {e.reason}"}), 500
except Exception as e:
return jsonify({"error": f"Error inesperado: {str(e)}"}), 500
Patrones Comunes
Agregar Nuevo Proveedor de IA
- Crear función en
app.py:
def get_nuevo_provider_models(api_key: str) -> list[dict]:
"""Obtiene modelos de NuevoProvider."""
url = "https://api.nuevo.com/v1/models"
headers = {"Authorization": f"Bearer {api_key}"}
data = make_request(url, headers)
models = []
for model in data.get("data", []):
models.append({
"id": model.get("id", ""),
"name": model.get("name", model.get("id", "")),
})
return models
- Agregar al diccionario
PROVIDERS:
"nuevo_provider": {
"name": "Nuevo Provider",
"function": get_nuevo_provider_models,
"url": "https://console.nuevo.com/",
"docs": "https://docs.nuevo.com/",
"icon": "nuevo_provider"
},
- Agregar color en
styles.css:
.provider-icon.nuevo_provider {
background: linear-gradient(135deg, #color1, #color2);
}
Peticiones HTTP (Backend)
def make_request(url: str, headers: dict = None, method: str = "GET") -> dict:
"""Realiza petición HTTP y retorna JSON."""
req = urllib.request.Request(url, method=method)
if headers:
for key, value in headers.items():
req.add_header(key, value)
with urllib.request.urlopen(req, timeout=15) as response:
return json.loads(response.read().decode())
Respuestas de API (Backend)
# Éxito
return jsonify({
"success": True,
"models": models,
"count": len(models)
})
# Error
return jsonify({"error": "Mensaje descriptivo"}), 400
Frontend (JavaScript)
Fetch API Pattern
async function checkModels() {
try {
const response = await fetch('/api/check-models', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ provider, api_key })
});
const data = await response.json();
if (!response.ok) throw new Error(data.error);
displayResults(data);
} catch (error) {
showError(error.message);
}
}
CSS / Diseño
- Tema: Oscuro minimalista
- Variables CSS: Usar las definidas en
:root - Animaciones: Sutiles, con
transitiono@keyframes - Responsive: Mobile-first, breakpoints en 768px y 480px
Seguridad
- API Keys: Nunca guardar permanentemente, solo en sesión
- CORS: Configurar si se expone públicamente
- Input validation: Sanitizar inputs del usuario
- HTTPS: Usar en producción
Git Commits
- Mensajes en español
- Modo imperativo: "Agrega soporte para X"
- Primera línea < 50 caracteres
- Referencia a issues: "Arregla #123"
Troubleshooting
| Problema | Solución |
|---|---|
| Flask no encontrado | pip install -r requirements.txt |
| Puerto 5000 ocupado | Cambiar puerto en app.run(port=5001) |
| API Key inválida | Verificar key en consola del proveedor |
| CORS error | Agregar flask-cors si es necesario |