Lección 14 · 10 min · Gratis

Herramienta de línea de comandos para graficar el historial de precios de acciones

Una herramienta de línea de comandos que grafica el historial de precios de cierre de una acción usando la Agent API de Perplexity y la herramienta sandbox.

Todo se ejecuta dentro de una única solicitud de Agent API en segundo plano:

  1. El modelo recibe la herramienta sandbox — un entorno Python con urllib/pandas/matplotlib y un directorio de trabajo escribible.
  2. Dentro del sandbox, obtiene los precios de cierre diarios del ticker de una fuente de datos anclada (el endpoint JSON del gráfico v8 de Yahoo Finance), escribe prices.csv y renderiza chart.png. El sandbox expone ambos archivos como artefactos descargables.

El script sondea la solicitud hasta su finalización y descarga ambos archivos — no hay renderizado local, por lo que no tiene dependencias de terceros.

AAPL closing price chart, last month

Cómo difiere de la documentación (importante)

Esta receta fue construida y verificada contra la Agent API en vivo. Algunas realidades dan forma al diseño:

  • La herramienta sandbox requiere una tarea en segundo plano. En la ruta síncrona/de streaming, la solicitud es rechazada con streaming failed: ... unknown tool "sandbox". Debes enviarla con background: true y sondear la respuesta por ID. Este script siempre hace eso.
  • El sandbox devuelve archivos. Cualquier cosa que el sandbox escriba en su directorio de trabajo regresa como un elemento de salida share_file que contiene un file_id, filename y una URL /v1/responses/{id}/files/{file_id}/content lista para descargar — también puedes listarlos con GET /v1/responses/{id}/files. El script descarga los artefactos prices.csv y chart.png directamente, en lugar de extraer nada de stdout.
  • Ancla la fuente de datos para reducir la latencia. La parte lenta de una ejecución de sandbox sin restricciones es el modelo buscando una fuente de precios (páginas públicas 429 o protegidas por captchas — fácilmente 3-7 llamadas al sandbox). Indicarle que acceda directamente al endpoint JSON del gráfico v8 de Yahoo lo convierte en una única obtención, y deja presupuesto de tokens para renderizar el gráfico en la misma sesión. Una ejecución típica ahora es una invocación de sandbox.
  • Dale al sandbox margen de tokens de salida. El sandbox gasta max_output_tokens escribiendo el código que obtiene los datos y renderiza el gráfico. Un límite estricto puede agotar el paso de escritura de archivos (los datos se obtienen pero los archivos nunca se escriben). Esta receta usa 8192.
  • finance_search no tiene historial (implementación actual). La herramienta de nivel superior finance_search devuelve solo la última cotización — una sola fila — por lo que no puede producir una serie de precios. El historial se obtiene dentro del sandbox.
  • La obtención de datos del sandbox es de mejor esfuerzo. Incluso una fuente anclada puede aplicar límites de tasa; el prompt recurre a una segunda fuente (Stooq), y el script reintenta toda la llamada varias veces (--attempts).

La Agent API se llama a través de HTTP puro (stdlib urllib, sin SDK) para que el cuerpo exacto de la solicitud sea visible y el endpoint sea configurable.

Características

  • Una solicitud en segundo plano orquesta el sandbox; el script la sondea hasta su finalización (resistente a 5xx transitorios)
  • El sandbox obtiene los precios y renderiza el gráfico por sí mismo, escribiendo un CSV date,close y un PNG; el script lee los artefactos share_file de la respuesta y los descarga (recurriendo al endpoint /files)
  • Fuente de datos anclada (Yahoo v8 chart JSON, Stooq como respaldo) lo mantiene en ~1 llamada al sandbox
  • Reintentos automáticos hasta que ambos archivos regresen y el CSV se analice correctamente
  • Sin dependencias de terceros — el gráfico se renderiza en el servidor, en el sandbox
  • --base-url / PERPLEXITY_BASE_URL configurables; informa el recuento de invocaciones del sandbox y el costo de la solicitud

Requisitos previos

  • Python 3.9+
  • Una clave de API de Perplexity con acceso a la Agent API. La herramienta sandbox está en vista previa — consulta la documentación del sandbox para conocer la disponibilidad.

Instalación

cd docs/examples/finance-chart-sandbox
# No dependencies to install — the API is called over raw HTTP and the chart is
# rendered inside the sandbox. (requirements.txt is intentionally empty.)
chmod +x finance_chart_sandbox.py

Configuración de la clave de API

export PERPLEXITY_API_KEY="your-api-key-here"

También puedes pasar --api-key, colocar la clave en un archivo .pplx_api_key, o añadir una línea PERPLEXITY_API_KEY= / PPLX_API_KEY= a un .env local.

Inicio rápido

Grafica los precios de cierre de Apple de los últimos 6 meses:

./finance_chart_sandbox.py AAPL

Esto escribe AAPL_6mo.csv y AAPL_6mo.png en el directorio actual.

Uso

./finance_chart_sandbox.py TICKER [--period 6mo] [--start YYYY-MM-DD --end YYYY-MM-DD] \
    [--model MODEL] [--attempts 3] [--max-steps 15] [--poll-timeout 300] \
    [--out-dir DIR] [--base-url URL] [--api-key KEY] [--keep-json]

Un gráfico de un mes

./finance_chart_sandbox.py AAPL --period 1mo

Un rango de fechas explícito, más reintentos

./finance_chart_sandbox.py MSFT --start 2025-01-01 --end 2025-06-30 --attempts 5

Apuntar a un endpoint diferente

PERPLEXITY_BASE_URL=https://api.perplexity.ai ./finance_chart_sandbox.py NVDA

Ejemplo de salida

[attempt 1/3] Asking the sandbox to fetch AAPL closing prices over the past 1 month and plot them...

Data points: 21 (2026-05-08 → 2026-06-08)
CSV:   AAPL_1mo.csv
Chart: AAPL_1mo.png  (fetched and rendered in the sandbox)
Sandbox invocations: 1
Cost: 0.1003 USD

El CSV (AAPL_1mo.csv):

date,close
2026-05-08,293.32
2026-05-11,292.68
2026-05-12,294.80
...

…y AAPL_1mo.png es un gráfico de líneas de close sobre date.

Interfaz de usuario web (FastAPI + JS)

Una pequeña aplicación web en webapp/ pone una puerta de entrada en lenguaje natural al ciclo del agente: pregunta "¿Cuál fue el precio de las acciones de Apple durante los últimos 6 meses?" y el modelo resuelve el ticker y el período por sí mismo, obtiene los precios y renderiza el gráfico en el sandbox, y la página muestra el resultado.

A diferencia de la CLI (que llama a la API a través de HTTP puro), el backend web utiliza el SDK de Python de Perplexity y reutiliza el análisis del módulo CLI y los ayudantes de archivos compartidos. Ejecuta un flujo de dos fases, porque la herramienta sandbox solo se ejecuta como una tarea en segundo plano (no transmitible):

  1. Datos — una llamada en segundo plano (client.responses.create(..., background=True) luego client.responses.retrieve(id)) donde el sandbox resuelve el ticker + período, obtiene los precios, escribe prices.csv y renderiza chart.png (ambos descargados por el backend), e imprime un pequeño bloque META para el enrutamiento (ticker + etiqueta).
  2. Respuesta — una llamada de streaming separada (stream=True) que escribe un breve análisis en lenguaje natural de la serie, token por token.
Endpoint Propósito
POST /api/charts Envía una pregunta ({query, attempts?}) → devuelve un job_id
GET /api/charts/{job_id}/events Eventos enviados por el servidor: progress → chart → tokens transmitidos → done
GET /api/charts/{job_id}/chart.png El PNG del gráfico que el sandbox renderizó
GET /api/charts/{job_id}/response.json La respuesta cruda de la Agent API de la fase 1 (código del sandbox, stdout, uso)
GET /api/charts/{job_id}/csv Descarga el CSV date,close

El trabajo se ejecuta en un hilo de trabajador y escribe el estado incremental en el trabajo; el endpoint SSE simplemente sigue ese estado, por lo que las reconexiones nunca vuelven a ejecutar el trabajo. El frontend es JS puro sin paso de compilación ni biblioteca de gráficos — en el evento chart simplemente apunta un <img> al PNG renderizado por el sandbox, añade el análisis transmitido en vivo y enlaza al JSON y CSV sin procesar.

Finance Chart sandbox web UI

Ejecútalo

cd docs/examples/finance-chart-sandbox/webapp
pip install -r requirements.txt   # perplexityai + fastapi + uvicorn
export PERPLEXITY_API_KEY="your-api-key-here"   # or a .env in this dir
python app.py                     # serves http://127.0.0.1:8000
# PORT=8060 python app.py         # if 8000 is taken

Abre la página, escribe una pregunta (o haz clic en un ejemplo) y pulsa Preguntar. La línea de estado se actualiza por intento mientras el sandbox en segundo plano se ejecuta (~20–40s).

Recorrido del código

1. Envía una solicitud en segundo plano con la herramienta sandbox (HTTP puro).

payload = {
    "model": "openai/gpt-5.5",
    "instructions": SYSTEM_PROMPT,           # "fetch from Yahoo v8, write CSV + render PNG"
    "input": "Fetch this exact URL ... Write prices.csv and render chart.png for AAPL ...",
    "tools": [{"type": "sandbox"}],
    "background": True,                       # required for the sandbox tool
    "max_output_tokens": 8192,                # headroom for the in-sandbox code
    "max_steps": 15,
}
# POST https://api.perplexity.ai/v1/responses  (Authorization: Bearer <key>)

El prompt ancla la fuente de datos (https://query1.finance.yahoo.com/v8/finance/chart/<TICKER>?range=<RANGE>&interval=1d, Stooq como respaldo) para que el sandbox obtenga los datos de una sola vez en lugar de buscar en páginas con límites de tasa.

2. Sondea la respuesta por ID hasta que se complete.

# GET https://api.perplexity.ai/v1/responses/{id}
while body["status"] in ("queued", "in_progress"):
    time.sleep(3)
    body = get(f"/v1/responses/{body['id']}")   # tolerate transient 5xx

3. Encuentra los archivos compartidos por el sandbox y descárgalos.

for item in body["output"]:
    if item["type"] == "share_file":
        url = item["url"]   # /v1/responses/{id}/files/{file_id}/content
        # item["filename"] is "prices.csv" or "chart.png"
data = get_raw(url)         # Authorization: Bearer <key>

El script lee los elementos share_file de la respuesta (recurriendo a GET /v1/responses/{id}/files si no hay ninguno en línea), descarga tanto el .csv como el .png, valida que el CSV se analice en ≥2 filas date,close, y reintenta toda la llamada si no es así.

4. Guarda los archivos. El CSV y el PNG renderizado por el sandbox se escriben en el disco — no hay nada que renderizar en el cliente, por lo que la CLI no tiene dependencias de terceros. (El CSV se analiza solo para informar la longitud de la serie).

Guía de prompting

  • Haz que los archivos sean el entregable. Indica claramente que la tarea solo se completa una vez que prices.csv y chart.png existen en el directorio de trabajo — de lo contrario, el modelo puede responder con los precios en prosa y nunca escribir los archivos.
  • Ancla la fuente de datos. Entregar al sandbox la URL de obtención exacta (JSON del gráfico v8 de Yahoo) colapsa una búsqueda de fuente de múltiples llamadas en una sola obtención — la mayor ganancia de latencia — y libera presupuesto para renderizar el gráfico en la misma sesión.
  • Dale margen de tokens de salida. El sandbox gasta max_output_tokens escribiendo el código que obtiene los datos y renderiza el gráfico; con un límite demasiado pequeño, se agota antes del paso de escritura. 8192 es cómodo.
  • Nombra una fuente de respaldo. Incluso un endpoint anclado puede 429; indicarle al modelo que recurra a una segunda fuente (Stooq) mejora la tasa de aciertos.
  • Prohíbe la fabricación. El prompt del sistema instruye al modelo a usar solo los precios que realmente recuperó — nunca a interpolar o estimar.

Precios

  • sandbox: $0.03 por sesión de contenedor
  • Tokens del modelo: se facturan por separado según los precios de los tokens de la Agent API

Las invocaciones al sandbox se cuentan bajo usage.tool_calls_details.sandbox.invocation, y el intercambio de archivos bajo usage.tool_calls_details.share_file.invocation. Con una fuente de datos anclada, una ejecución típica es una invocación al sandbox (sin búsquedas web dentro del contenedor), lo que mantiene el costo bajo (~$0.10 en nuestras ejecuciones). Consulta Precios de Perplexity para conocer las tarifas actuales.

Limitaciones

  • sandbox está en vista previa y debe ejecutarse como una tarea en segundo plano
  • El historial de precios proviene de fuentes de terceros (JSON del gráfico v8 de Yahoo, Stooq como respaldo) obtenidas dentro del sandbox, por lo que la precisión y disponibilidad de los datos dependen de esas fuentes — los valores deben ser verificados, y los tickers oscuros/no estadounidenses pueden fallar (Stooq espera un sufijo .us)
  • La obtención es de mejor esfuerzo: los límites de tasa pueden hacer que un intento no devuelva archivos; el script reintenta, pero una ejecución aún puede fallar (lanzar --attempts)
  • Cada intento es una sesión de sandbox facturada por separado
  • Esto no es asesoramiento de inversión

Recursos

Lección del curso «Perplexity API Cookbook» de Perplexity, publicado con licencia MIT. Traducción y adaptación al español de IA con Clase. IA con Clase no está afiliado a Perplexity. Ver el original · Licencia
Esta lección es gratuita. El resto del curso se abre con la Membresía de IA con Clase, que incluye todos los cursos del catálogo. Ver precios