posit-dev / posit-dev/py-shiny
Accessing an empty reactive Value raises a SilentException
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 1.8k
- Forks
- 135
- Avg merge
- 2d 18h
- Merged PRs (30d)
- 21
Description
Hi,
I was trying to implement a lazy loading mechanism.
The data is defined as a reactive.Value, but is initially not initialized.
The data is loaded in a reactive Effect, that is fired when some other event is occurring (e.g. a button click, a nav item becoming active). The reactive Effect needs to check if the reactive Value is empty, and if so, it loads the required data and sets the reactive Value. Otherwise, it does nothing.
To get the current value of the reactive Value, I'm using a with isolate block. However, this block is raising a SilentException, and the next steps (the data load) never happens.
This is not limited to an isolate block. When used in an output function, the function stops when the empty reactive value is encountered.
Here's a simple example :
from shiny import *
app_ui = ui.page_fluid(
ui.h2("Lazy Load Demo"),
ui.input_action_button("in_load", "Load Data"),
ui.output_text_verbatim("out_data", placeholder=True),
ui.input_text("in_text", "Some text"),
ui.output_text_verbatim("out_text", placeholder=True),
)
def server(input, output, session):
data = reactive.Value()
# workaround:
# data = reactive.Value(False) or reactive.Value(pd.DataFrame())
@reactive.Effect
def load_data():
"""
Load data on demand. But only load it once.
If the data has been loaded before, do not reload
"""
req(input.in_load())
with reactive.isolate():
# check if data is loaded. Avoid dependency with the reactive value
# if using an initialized reactive.Value, the check may be different, e.g.
# loaded = data()
loaded = data() is not None
# This is never executed:
if loaded:
print("data already loaded, skipping")
else:
print("loading data, skipping")
data.set("Simulate")
@output
@render.text
def out_data():
"""
Also in the output function, calling the non-initialized reactive Value results in a SilentException.
"""
# req(data())
print("Rendering output")
# This is never executed:
print(data())
print("data printed")
return data()
@output
@render.text
def out_text():
return input.in_text()
app = App(app_ui, server)
I would expect that an empty reactive Value would simply return None, instead of raising a SilentException.
My workaround for the moment is to initialize the reactive Value with a value, such as False, or pd.DataFrame().
Shiny version : 0.2.9
Kind Regards,
Bart
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by running the minimal server example from the issue with Shiny for Python 0.2.9, focusing on the reactive.Value() calls inside load_data and out_data. Trace how an uninitialized value is handled and add or update a regression test for the expected None result without a SilentException. Done means the lazy-loading check and output rendering can safely read an empty reactive value.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- backend
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100