Ejemplos rápidos para probar la API de ModelRouter con curl y fetch (browser / Node).
Sustituye tu_api_key por el valor en tu .env.
Ejemplo en una sola línea (Bash/PowerShell):
curl -X POST http://localhost:8000/chat \
-H "Authorization: Bearer tu_api_key" \
-H "Content-Type: application/json" \
-d '{"messages": [{"role": "user", "content": "¿Cuál es la capital de Francia?"}], "max_tokens": 50}'Usando archivo body.json (recomendado para payloads complejos):
body.json
{
"messages": [{"role": "user", "content": "¿Cuál es la capital de Francia?"}],
"max_tokens": 50,
"provider": "ollama"
}curl -X POST http://localhost:8000/chat \
-H "Authorization: Bearer tu_api_key" \
-H "Content-Type: application/json" \
-d @body.jsonRecibe chunks en tiempo real con -N:
curl -N -X POST http://localhost:8000/stream \
-H "Authorization: Bearer tu_api_key" \
-H "Content-Type: application/json" \
-d '{"messages":[{"role":"user","content":"Cuenta un cuento corto"}], "max_tokens":150}'Verás líneas data: <chunk> hasta data: [DONE].
// Browser (fetch)
async function chat() {
const resp = await fetch('http://localhost:8000/chat', {
method: 'POST',
headers: {
'Authorization': 'Bearer tu_api_key',
'Content-Type': 'application/json'
},
body: JSON.stringify({
messages: [{ role: 'user', content: '¿Qué es FastAPI?' }],
max_tokens: 100
})
});
const data = await resp.json();
console.log(data);
}
chat();El estándar EventSource en navegadores no soporta nativamente POST ni el envío de cabeceras personalizadas (por ejemplo Authorization). Para recibir streaming SSE/NDJSON desde el navegador usa fetch y consume la ReadableStream de la respuesta — es equivalente al Ejemplo 6 (Node).
// Browser — streaming con fetch y ReadableStream
async function streamChat() {
const res = await fetch('http://localhost:8000/stream', {
method: 'POST',
headers: {
'Authorization': 'Bearer tu_api_key',
'Content-Type': 'application/json'
},
body: JSON.stringify({ messages: [{ role: 'user', content: 'Cuenta un cuento corto' }], max_tokens: 150 })
});
const reader = res.body.getReader();
const decoder = new TextDecoder();
let done = false;
while (!done) {
const { value, done: d } = await reader.read();
done = d;
if (value) {
const text = decoder.decode(value, { stream: true });
console.log('chunk:', text);
if (text.includes('[DONE]')) break;
}
}
}
streamChat().catch(console.error);Nota: cuando uses
fetchdesde el navegador asegúrate de que el backend tenga CORS habilitado para aceptarAuthorizationyContent-Typedesde el origen del cliente, o utiliza un proxy que agregue las cabeceras necesarias.
// Node 18+ (global fetch) o con node-fetch
import fetch from 'node-fetch'; // si tu Node no tiene fetch
async function chatNode() {
const res = await fetch('http://localhost:8000/chat', {
method: 'POST',
headers: {
'Authorization': 'Bearer tu_api_key',
'Content-Type': 'application/json'
},
body: JSON.stringify({ messages: [{ role: 'user', content: 'Hola' }], max_tokens: 80 })
});
console.log(await res.json());
}
chatNode();// Node 18+ ejemplo de streaming con fetch y ReadableStream
const res = await fetch('http://localhost:8000/stream', {
method: 'POST',
headers: {
'Authorization': 'Bearer tu_api_key',
'Content-Type': 'application/json'
},
body: JSON.stringify({ messages: [{ role: 'user', content: 'Cuenta un chiste' }], max_tokens: 150 })
});
const reader = res.body.getReader();
const decoder = new TextDecoder();
let done = false;
while (!done) {
const { value, done: d } = await reader.read();
done = d;
if (value) {
const text = decoder.decode(value);
process.stdout.write(text);
}
}-
La API acepta el campo
provideren el cuerpo de la petición (opcional). Si se especifica, ModelRouter intentará usar únicamente ese proveedor; si no, aplicará la lógica de rotación y fallback. -
Para pruebas locales con Docker, si
ModelRoutercorre dentro de un contenedor yOllamaen el host, configuraOLLAMA_BASE_URL=http://host.docker.internal:11434. -
Usa
body.jsonpara payloads largos o que contengan saltos de línea para evitar problemas de escape en shells. -
Reemplaza
tu_api_keypor el valor real en.envo usa el header correcto según tu entorno.