# Crea una pequeña aplicación de chat con streaming

Consulta tus modelos, envía un mensaje, recibe una respuesta en streaming y conserva una conversación local con MandAPI.

## Qué vas a crear

Esta receta crea un chat de terminal en Python con cuatro modos: consultar modelos, enviar un mensaje, recibir una respuesta en streaming y continuar una conversación. Las solicitudes llegan a MandAPI mediante el cliente Python de OpenAI. Utilizas tu propia cuenta y saldo de API; instalar el cliente no incluye créditos.

Crea una clave desde tu [panel de MandAPI](https://app.mandapi.com/console). Consulta el [catálogo actual](https://mandapi.com/es/pricing) y elige un modelo disponible para tu clave que admita Chat Completions y streaming. Que un modelo aparezca en la lista no garantiza todas las funciones.

## Prepara Python y las variables

Usa Python 3.10 o posterior. Estos comandos son para PowerShell. La clave se introduce mediante una pregunta de la terminal, sin escribirla dentro del comando. Después de consultar los modelos, sustituye el identificador de ejemplo por uno real.

```powershell
py -m venv .venv
.\.venv\Scripts\python -m pip install openai
$secret = Read-Host "MandAPI API key" -AsSecureString
$env:MANDAPI_API_KEY = [System.Net.NetworkCredential]::new("", $secret).Password
$env:MANDAPI_MODEL_ID = "MODEL_ID_FROM_YOUR_CATALOG"
```

Mantén abierta esta terminal durante las pruebas. En producción, guarda la clave en las opciones de secretos de tu despliegue.

En macOS o Linux, usa Bash:

```bash
python3 -m venv .venv
source .venv/bin/activate
python -m pip install openai
read -rsp "Clave de MandAPI: " MANDAPI_API_KEY
printf '\n'
export MANDAPI_API_KEY
export MANDAPI_MODEL_ID="MODEL_ID_FROM_YOUR_CATALOG"
```

## Guarda la aplicación completa

Crea un archivo llamado `chat.py` con este código:

```python
# chat.py
import argparse
import os
from openai import OpenAI

parser = argparse.ArgumentParser()
parser.add_argument("mode", choices=["models", "once", "stream", "chat"])
args = parser.parse_args()

client = OpenAI(
    api_key=os.environ["MANDAPI_API_KEY"],
    base_url="https://api.mandapi.com/v1",
    timeout=30.0,
    max_retries=0,
)

def answer(messages, stream=False):
    result = client.chat.completions.create(
        model=os.environ["MANDAPI_MODEL_ID"],
        messages=messages,
        stream=stream,
    )
    if not stream:
        text = result.choices[0].message.content or ""
        print(text)
        if result.usage is not None:
            print("Tokens:", result.usage.prompt_tokens,
                  result.usage.completion_tokens)
        return text

    parts = []
    try:
        for chunk in result:
            if not chunk.choices:
                continue
            text = chunk.choices[0].delta.content or ""
            parts.append(text)
            print(text, end="", flush=True)
    finally:
        result.close()
    print()
    return "".join(parts)

try:
    if args.mode == "models":
        for model in client.models.list().data:
            print(model.id)
    elif args.mode in ("once", "stream"):
        answer([{"role": "user", "content": "Say hello in Spanish."}],
               stream=args.mode == "stream")
    else:
        history = []
        while True:
            try:
                text = input("You (exit to quit): ").strip()
            except EOFError:
                break
            if text.lower() == "exit":
                break
            if not text:
                continue
            messages = history + [{"role": "user", "content": text}]
            reply = answer(messages, stream=True)
            history = messages + [{"role": "assistant", "content": reply}]
except KeyboardInterrupt:
    print()
finally:
    client.close()
```

## Ejecuta los cuatro modos

Empieza con `.\.venv\Scripts\python chat.py models`. Copia un identificador apropiado del resultado a `MANDAPI_MODEL_ID`.

Ejecuta `chat.py once` para obtener una respuesta completa y los tokens devueltos. Usa `chat.py stream` para imprimir el texto a medida que llega. Por último, ejecuta `chat.py chat`, di tu nombre y haz una pregunta que lo mencione. La aplicación reenvía el historial local, por lo que los siguientes mensajes pueden consumir más tokens de entrada. Escribe `exit` para terminar.

Con el entorno virtual de macOS/Linux activo, usa `python chat.py models`, `python chat.py once`, `python chat.py stream` o `python chat.py chat`.

## Comprueba el resultado

La respuesta completa debe contener texto; el modo streaming debe mostrar fragmentos; la siguiente pregunta debe utilizar el contexto anterior. Revisa el consumo real en tu panel. Si hay un problema de clave, saldo, acceso al modelo u opción no admitida, corrige ese ajuste antes de repetir. Descargar esta receta no realiza pagos ni solicitudes reales.

## Referencias

- [https://mandapi.com/en/docs/quickstart](https://mandapi.com/en/docs/quickstart)
- [https://mandapi.com/es/docs/quickstart](https://mandapi.com/es/docs/quickstart)
- [https://github.com/openai/openai-python](https://github.com/openai/openai-python)
