    view_csv = b"".join(view_item.csv).decode("utf-8")
    return workbooks_names, views_names, view_name, view_image, view_csv
workbooks_names, views_names, view_name, view_image, view_csv = run_query()
Print results.
st.subheader("📓 Workbooks")
st.write("Found the following workbooks:", ", ".join(workbooks_names))
st.subheader("👁️ Views")
st.write(
    f"Workbook {workbooks_names[0]} has the following views:",
    ", ".join(views_names),
)
st.subheader("🖼️ Image")
st.write(f"Here's what view {view_name} looks like:")
st.image(view_image, width=300)
st.subheader("📊 Data")
st.write(f"And here's the data for view {view_name}:")
st.write(pd.read_csv(StringIO(view_csv)))
```
See st.cache above? Without it, Streamlit would run the query every time the app reruns (e.g. on a widget interaction). With st.cache, it only runs when the query changes or after 10 minutes (that's what ttl is for). Watch out: If your database updates more frequently, you should adapt ttl or remove caching so viewers always see the latest data. Read more about caching here.
