[Preview Endpoints]

Pro chart and indicator thumbnail routes under /preview with usage tracking.

Preview Endpoints

Abstract

Preview routes render PNG thumbnails (base64) for desk UIs and docs. They require an API key via @track_usage, accept OHLCV-shaped objects (column arrays), and do not run the full Runtime bar loop for /preview/chart (data is plotted directly). /preview/indicator evaluates a small set of closed-form ta.* expressions in pure Python for the series, then plots.

Conceptual model

Blueprint: preview_bp with url_prefix="/preview" in backend/api/preview.py.

Interface surface

Auth

Both routes: @track_usage → must pass require_api_key and consume one call on success.

POST /preview/chart

Body (documented; schemas exist as PREVIEW_CHART_SCHEMA)

{
  "script": "optional string",
  "data": {
    "open": [], "high": [], "low": [], "close": [], "volume": []
  },
  "options": {
    "type": "line",
    "color": "#2196F3",
    "show_volume": false,
    "width": 600,
    "height": 300
  }
}
OptionDefaultClamp
type"line""ohlcv" selects candlestick renderer
color#2196F3line chart only
width600max 1200
height300max 600
show_volumefalsetwin-axis volume on line chart

Success

{
  "status": "success",
  "chart": "<base64 png>",
  "meta": {
    "type": "line",
    "bars": 252,
    "last_value": 0,
    "first_value": 0,
    "change": 0,
    "change_pct": 0,
    "rendered_at": 0
  },
  "tier_info": {}
}

Errors

codeWhen
NO_DATAMissing data
NO_CLOSE_DATAEmpty close array
RENDER_ERRORmatplotlib / renderer exception

Note: script is accepted for API symmetry but not executed on this path today — the chart is pure data visualization.

POST /preview/indicator

Body

{
  "expression": "ta.sma(close, 14)",
  "data": { "close": [/* … */] },
  "options": { "color": "#FF9800", "width": 600, "height": 300 }
}

Supported expression prefixes in _compute_indicator:

ExpressionSeries
ta.sma(…, period)SMA of close
ta.ema(…, period)EMA
ta.rsi(…, period)RSI
ta.macd(…)MACD histogram (12/26/9)
otherfalls back to raw close

Parse failures in the helper fall back to plotting close.

Internals

PathRole
backend/api/preview.pyRoute handlers + indicator math
backend/services/chart_renderer.pyPNG encode
backend/middleware/auth.pytrack_usage

Schemas PREVIEW_* in schemas.py document intended validation; current handlers use request.get_json() or {} directly.

Invariants and edge cases

  1. Data shape differs from /run: preview uses columnar dicts; /run uses list of bar dicts.
  2. Not a full Pine interpreter for indicator expressions — string prefix parsing only.
  3. Width/height clamps protect worker memory/CPU.
  4. Successful responses include tier_info from the authenticated key.

Worked example

curl -s http://127.0.0.1:5002/preview/chart \
  -H "Authorization: Bearer $API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{
    "data": {"close": [1,2,3,4,5], "volume": [10,10,10,10,10]},
    "options": {"type": "line", "show_volume": true}
  }' | jq '.meta'

Failure modes

SymptomCause
401Missing key
429Tier limit
Empty-looking PNGRenderer empty-chart path when all values null

See also