Skip to main content

Rich Display Rendering

The result renderer in Windmill supports rich display rendering, allowing you to customize the display format of your results. By leveraging specific formats, you can display images, files, tables, HTML, JSON, and more.

Rich display formats

This feature is useful if you want to display an image, a GIF, a file, or specify the filename for a rich result.

If the result is an object/dict with a single key (except for approval, which needs 3), you can leverage the following rich results:

jsonRender the value as a JSONreturn { "json": { "a": 1 } }
table-colRender the value as a column in a tablereturn { "table-col": { "foo": [42, 8], "bar": [38, 12] }}
table-rowRender the value as a row in a tablereturn { "table-row": [ "foo", "bar" ]}
htmlRender the value as HTMLreturn { "html": "<div>...</div>" }
pngRender the value as a PNG imagereturn { "png": { "content": encode(image) } } or return { "png": encode(image) }
fileRender an option to download the filereturn { "file": { "content": encode(file), "filename": "data.txt" } }
jpegRender the value as a JPEG imagereturn { "jpeg": { "content": encode(image) } } or return { "jpeg": encode(image) }
gifRender the value as a GIF imagereturn { "gif": { "content": encode(image) } } or return { "gif": encode(image) }
errorRender the value as an error messagereturn { "error": { "name": "418", "message": "I'm a teapot" }}
approvalRender an approval and buttons to Resume or Cancel the stepreturn { "resume": "", "cancel": "", "approvalPage": "" }
svgRender the value as an SVG imagereturn { "svg": "<svg>...</svg>" }
markdownRender the value as Markdownreturn { "markdown": "## Hello World" } or return { "md": "## Hello World" }
render_allRender all the resultsreturn { "render_all": [ { "json": { "a": 1 } }, { "table-col": { "foo": [42, 8], "bar": [38, 12] }} ] }
mapRender a map with a given locationreturn { "map": { lat: 40, lon: 0, zoom: 3, markers: [{lat: 50.6, lon: 3.1, title: "Home", radius: 5, color: "yellow", strokeWidth: 3, strokeColor: "Black"}]}}

Rich display HTML

Rich display map

Regarding the tables: If the result is a list whose first element is also a list, it will display the result as a table. If the result is a dict/object where every value is an array, it will also be displayed as a table, with the key as the column name.

For example:

import { encode } from '[email protected]/encoding/base64.ts';

export async function main() {
const url = '';
const resp = await fetch(url);
const buff = await resp.arrayBuffer();
const data = encode(buff);
return {
png: {
content: data

Rich table display

The rich table display will be enabled for scripts or flows when:

  • The result is an array of objects.
  • The result has a 'table-col' key.



The rich display renderer also supports interactions. Interactions are a way to display a result and allow the user to interact with it. For example, you can display a table and allow the user to sort it by clicking on the column headers.

The features are:

  • Search.
  • Hide/show columns.
  • Sort by column (ascending/descending): Only enabled if the column is sortable, i.e. if the column is a number or a string.
  • Pagination.
  • Download as CSV. If the user selected rows, it will download the selected rows as CSV. If no rows are selected, it will download the entire table as CSV.
  • Download as JSON.


Try with this Python:

import requests
from typing import Any, Dict

def main() -> Dict[str, Any]:

url = ""
response = requests.get(url)
data = response.json()
return data