Skip to content

Commit 2cb238a

Browse files
authored
Merge branch 'main' into feat/custom-features-and-user-feedback
2 parents 1a54f9e + 0f393b6 commit 2cb238a

5 files changed

Lines changed: 21013 additions & 20843 deletions

File tree

content/workspace/developers/json-specs/widgets-json-reference.md

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -205,13 +205,13 @@ A `Widgets.json` table is a configuration structure with any of the named attrib
205205
The array structure is: `[category, series1, series2, ...]` where:
206206
- First element: The category column (x-axis)
207207
- Remaining elements: The series columns (y-axis data)
208-
_Example:_
209-
```json
208+
_Example:_
209+
```json
210210
"cellRangeCols": {
211211
"line": ["ticker", "weight", "weight2"],
212212
"column": ["date", "price", "volume"]
213213
}
214-
```
214+
```
215215

216216
- **ignoreCellRange**
217217
_Type:_ `boolean`
@@ -711,10 +711,15 @@ A `Widgets.json` table is a configuration structure with any of the named attrib
711711
_Example:_ `"get_company_revenue_data"`
712712

713713
- **refetchInterval**
714-
_Type:_ `number` or `false`
715-
Time in milliseconds before the widget's data will refresh if on the page. Minimum value is `1000`.
714+
_Type:_ `number`, `false`, or `string` (cron expression)
715+
Time in milliseconds before the widget's data will refresh if on the page. Minimum value is `1000` when using a number. Alternatively, accepts a cron expression string (e.g., `"0 10 * * 1-5"`) to schedule refetches at specific times.
716716
_Default:_ `900000` (15m)
717717

718+
- **dataUpdateDisplay**
719+
_Type:_ `string` (cron expression)
720+
A cron expression that controls the "Data update" tooltip shown on the widget's refresh button. Displays the schedule in human-readable format and calculates the previous and next scheduled data update timestamps. These timestamps are based on the cron expression, not on the widget's last refresh time.
721+
_Example:_ `"0 10 * * 1-5"` (weekdays at 10:00AM)
722+
718723
- **staleTime**
719724
_Type:_ `number`
720725
Time in milliseconds before the widget's data is considered stale and will refresh on the next visit to the dashboard.
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
---
2+
title: Data Update Display
3+
sidebar_position: 21
4+
description: Learn about configuring data update display for widgets in OpenBB Workspace.
5+
keywords:
6+
- data update
7+
- cron schedule
8+
- displayed schedule
9+
- update display
10+
- widget updates
11+
---
12+
13+
import HeadTitle from '@site/src/components/General/HeadTitle.tsx';
14+
15+
<HeadTitle title="Data Update Display | OpenBB Workspace Docs" />
16+
17+
The data update display allows you to show users when a widget's data is expected to update. It renders an informational tooltip on the widget's refresh button showing the configured schedule, the previous scheduled data update time, and the next scheduled update time.
18+
19+
- Accepts a cron expression string (e.g., `"0 8 * * 1-5"` for weekdays at 8:00AM)
20+
- Displays the schedule in human-readable format (e.g., "At 8:00AM, Monday through Friday")
21+
- Shows the previous update timestamp calculated from the cron expression
22+
- Shows the next update timestamp calculated from the cron expression
23+
- Appears as a "Data update" section in the widget's refresh tooltip
24+
25+
`dataUpdateDisplay` is display-only. It does not trigger data fetching by itself, and the "Last update" value is calculated from the cron expression. It represents the last expected data update time, not the widget's last refresh time.
26+
27+
<img className="pro-border-gradient" width="400" alt="data update display hover" src="https://openbb-cms.directus.app/assets/2acdfbcf-13a5-4c9e-84e7-94c100a6a464.png" />
28+
29+
<img className="pro-border-gradient" width="600" alt="data update display widget" src="https://openbb-cms.directus.app/assets/c2001272-20e3-4183-a7ee-60c2618e8914.png" />
30+
31+
```python
32+
@register_widget({
33+
"name": "Markdown Widget with Data Update Display Only",
34+
"description": "A markdown widget that displays a data update schedule without configuring automatic refresh.",
35+
"type": "markdown",
36+
"endpoint": "markdown_widget_with_data_update_display_only",
37+
"dataUpdateDisplay": "0 10 * * *", # Displays as updated every day at 10:00 without driving refetches
38+
"gridData": {"w": 20, "h": 6},
39+
})
40+
@router.get("/markdown_widget_with_data_update_display_only")
41+
def markdown_widget_with_data_update_display_only():
42+
"""Returns a markdown widget with display-only data update metadata"""
43+
updated_at = last_daily_data_update(hour=10, minute=0)
44+
return (
45+
"# Data Update Display Only\n\n"
46+
f"Data updated at: {updated_at}\n\n"
47+
"Backend data schedule: Every day at 10:00\n\n"
48+
"This timestamp is controlled by the backend data schedule, not request time."
49+
)
50+
```
51+
52+
## Combined with Cron Refetch Interval
53+
54+
You can use `dataUpdateDisplay` together with a cron-based `refetchInterval` to both schedule the actual widget refresh and display the schedule to users. When both use the same cron expression, the widget will refetch at the scheduled time while it is active on the page, and the tooltip will show the previous and next expected update times.
55+
56+
The displayed "Last update" value follows the cron schedule. Manual refreshes can still update the widget data, but they do not change the scheduled data update timestamp shown in this section.
57+
58+
59+
<img className="pro-border-gradient" width="400" alt="Refetch interval hover" src="https://openbb-cms.directus.app/assets/d2b3ebb5-3d52-4e42-b3f8-33c245e59c90.png" />
60+
61+
<img className="pro-border-gradient" width="600" alt="Refetch interval widget" src="https://openbb-cms.directus.app/assets/cdb5993d-eb0d-4d93-bbb7-6bb59ce6fbbb.png" />
62+
63+
```python
64+
@register_widget({
65+
"name": "Markdown Widget with Cron Refetch Interval",
66+
"description": "A markdown widget that auto-refreshes on cron schedule boundaries and displays its data update schedule in widget metadata.",
67+
"type": "markdown",
68+
"endpoint": "markdown_widget_with_cron_refetch_interval",
69+
"refetchInterval": "*/1 * * * *", # Every minute, using standard 5-field cron syntax
70+
"dataUpdateDisplay": "*/1 * * * *", # Shows the data update schedule in the refresh indicator tooltip
71+
"gridData": {"w": 20, "h": 6},
72+
})
73+
@router.get("/markdown_widget_with_cron_refetch_interval")
74+
def markdown_widget_with_cron_refetch_interval():
75+
"""Returns a markdown widget that auto-refreshes every minute via cron"""
76+
updated_at = last_minute_data_update()
77+
return (
78+
"# Cron Refetch Interval\n\n"
79+
f"Data updated at: {updated_at}\n\n"
80+
"Backend data schedule: Every minute\n\n"
81+
"This timestamp is controlled by the backend data schedule, not request time."
82+
)
83+
```
84+
85+
## Common Cron Expressions
86+
87+
| Expression | Description |
88+
|---|---|
89+
| `* * * * *` | Every minute |
90+
| `*/5 * * * *` | Every 5 minutes |
91+
| `0 * * * *` | Every hour |
92+
| `0 8 * * 1-5` | At 8:00AM, Monday through Friday |
93+
| `0 10 * * *` | Daily at 10:00AM |
94+
| `0 0 * * 0` | Weekly on Sunday at midnight |

content/workspace/developers/widget-configuration/refetch-interval.md

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ keywords:
88
- data updates
99
- refresh rate
1010
- widget updates
11+
- cron
12+
- cron expression
13+
- scheduled refresh
1114
---
1215

1316
import HeadTitle from '@site/src/components/General/HeadTitle.tsx';
@@ -17,6 +20,7 @@ import HeadTitle from '@site/src/components/General/HeadTitle.tsx';
1720
The refetch interval is the interval at which the widget will be refreshed. Use lower values for real-time data (e.g., 60000 for 1-minute updates). Higher values are recommended for static or slowly changing data.
1821

1922
- Default: 900000 (15 minutes) (minimum 1000)
23+
- Accepts a number (milliseconds), `false`, or a cron expression string
2024
- Set to `false` to disable automatic refreshing
2125
- Use lower values for real-time data (e.g., 60000 for 1-minute updates)
2226
- Higher values recommended for static or slowly changing data
@@ -67,7 +71,6 @@ def markdown_widget_with_refetch_interval_and_shorter_stale_time():
6771

6872
## Refetch interval with Run Button
6973

70-
7174
The refresh interval is set to 10000ms (10 seconds) but the run button is enabled, which means that the user can refresh the widget manually.
7275

7376
<img className="pro-border-gradient" width="800" alt="Markdown Widget with Short Refetch Interval and Run Button Example" src="https://openbb-cms.directus.app/assets/24d777ae-d455-412d-9832-255e28eea11e.png" />
@@ -87,4 +90,43 @@ def markdown_widget_with_short_refetch_interval_and_run_button():
8790
"""Returns a markdown widget with current time"""
8891
current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
8992
return f"### Current time: {current_time}"
90-
```
93+
```
94+
95+
## Refetch Interval with Cron Expression
96+
97+
Instead of a fixed interval in milliseconds, you can use a cron expression to schedule refetches at specific times. The widget will calculate the time until the next cron boundary and schedule the refetch accordingly.
98+
99+
Cron-based `refetchInterval` controls when the widget refetches while it is active on the page. To show users the same schedule in the refresh tooltip, configure `dataUpdateDisplay` with the same cron expression. The tooltip's "Last update" value is calculated from the cron expression and represents the previous scheduled data update time, not the widget's last refresh time.
100+
101+
<img className="pro-border-gradient" width="800" alt="Markdown Widget with Short Refetch Interval and Run Button Example" src="https://openbb-cms.directus.app/assets/97764965-85ea-49c2-82a0-d7122605da4a.png" />
102+
103+
```python
104+
@register_widget({
105+
"name": "Markdown Widget with Cron Refetch Only",
106+
"description": "A markdown widget that auto-refreshes on cron schedule boundaries without displaying a separate data update schedule.",
107+
"type": "markdown",
108+
"endpoint": "markdown_widget_with_cron_refetch_only",
109+
"refetchInterval": "*/1 * * * *", # Every minute, using standard 5-field cron syntax
110+
"gridData": {"w": 20, "h": 6},
111+
})
112+
@router.get("/markdown_widget_with_cron_refetch_only")
113+
def markdown_widget_with_cron_refetch_only():
114+
"""Returns a markdown widget that auto-refreshes every minute via cron without display metadata"""
115+
updated_at = last_minute_data_update()
116+
return (
117+
"# Cron Refetch Only\n\n"
118+
f"Data updated at: {updated_at}\n\n"
119+
"Backend data schedule: Every minute\n\n"
120+
"This timestamp is controlled by the backend data schedule, not request time."
121+
)
122+
```
123+
124+
Common cron expressions:
125+
126+
| Expression | Description |
127+
|---|---|
128+
| `* * * * *` | Every minute |
129+
| `*/5 * * * *` | Every 5 minutes |
130+
| `0 * * * *` | Every hour |
131+
| `0 8 * * 1-5` | At 8:00AM, Monday through Friday |
132+
| `0 10 * * *` | Daily at 10:00AM |

0 commit comments

Comments
 (0)