flowchart TD S[Input] --> Sc((Output))
with gr.Blocks() as demo:
sampled_data = gr.State(None)
...
def plot_metrics(data, metric):
if metric == "ROC Curve":
return plot_auc_curve(data, "is_electronics", "training_score")
else:
return plot_precision_recall_curve(
data, "is_electronics", "training_score"
)
account.select(sample_data, [slider], [sampled_data]).then(
dist_plot, [sampled_data, log_scale], [tip_plot]
).then(plot_metrics, [sampled_data], [hist_plot])
metric.select(plot_tips, [sampled_data, log_scale], [tip_plot])
with gr.Blocks#| () as demo:
sampled_data = gr.State(None)
...
def plot_metrics(data, metric):
if input.metric() == "ROC Curve":
return plot_auc_curve(data, "is_electronics", "training_score")
else:rn plot_precision_recall_curve( data, "is_electronics", "training_score"
)
account.select(sample_data, [slider], [sampled_data]).then(
dist_plot, [sampled_data, log_scale], [tip_plot]
).then(plot_metrics, [sampled_data], [hist_plot])
metric.select(plot_tips, [sampled_data, log_scale], [tip_plot])
with gr.Blocks() as demo:
sampled_data = gr.State(None)
...
def plot_metrics(data, metric):
if input.metric() == "ROC Curve":
return plot_auc_curve(data, "is_electronics", "training_score")
else:
return plot_precision_recall_curve(
data, "is_electronics", "training_score"
)
account.select(sample_data, [slider], [sampled_data]).then(
dist_plot, [sampled_data, log_scale], [tip_plot]
).then(plot_metrics, [sampled_data], [hist_plot])
metric.select(plot_metrics, [sampled_data, log_scale], [tip_plot])
@render.plot
def score_dist():
df_filtered = df[df["account"] == input.account()]
return dist_plot(df_filtered)
@render.plot
def metric():
df_filtered = df[df["account"] == input.account()]
if input.metric() == "ROC Curve":
return plot_auc_curve(df_filtered, "is_electronics", "training_score")
else:
return plot_precision_recall_curve(
df_filtered, "is_electronics", "training_score"
)
Generic DAG
@render.plot
def score_dist():
df_filtered = df[df["account"] == input.account()]
return dist_plot(df_filtered)
@render.plot
def metric():
df_filtered = df[df["account"] == input.account()]
if input.metric() == "ROC Curve":
return plot_auc_curve(df_filtered, "is_electronics", "training_score")
else:
return plot_precision_recall_curve(
df_filtered, "is_electronics", "training_score"
)
#| standalone: true
#| components: [viewer]
#| layout: horizontal
#| viewerHeight: 500
import shinyswatch
from htmltools import css
from shiny import App, module, reactive, render, ui
app_ui = ui.page_fixed(
{"class": "my-5"},
shinyswatch.theme.minty(),
ui.panel_title("Shiny TodoMVC"),
ui.layout_sidebar(
ui.panel_sidebar(
ui.input_text("todo_input_text", "", placeholder="Todo text"),
ui.input_action_button("add", "Add to-do"),
),
ui.panel_main(
ui.output_text("cleared_tasks"),
ui.div(id="tasks", style="margin-top: 0.5em"),
),
),
)
def server(input, output, session):
finished_tasks = reactive.Value(0)
task_counter = reactive.Value(0)
@output
@render.text
def cleared_tasks():
return f"Finished tasks: {finished_tasks()}"
@reactive.Effect
@reactive.event(input.add)
def add():
counter = task_counter.get() + 1
task_counter.set(counter)
id = "task_" + str(counter)
ui.insert_ui(
selector="#tasks",
where="beforeEnd",
ui=task_ui(id),
)
finish = task_server(id, text=input.todo_input_text())
# Defining a nested reactive effect like this might feel a bit funny but it's the
# correct pattern in this case. We are reacting to the `finish`
# event within the `add` closure, so nesting the reactive effects
# means that we don't have to worry about conflicting with
# finish events from other task elements.
@reactive.Effect
@reactive.event(finish)
def iterate_counter():
finished_tasks.set(finished_tasks.get() + 1)
ui.update_text("todo_input_text", value="")
# Modules to define the rows
@module.ui
def task_ui():
return ui.output_ui("button_row")
@module.server
def task_server(input, output, session, text):
finished = reactive.Value(False)
@output
@render.ui
def button_row():
button = None
if finished():
button = ui.input_action_button("clear", "Clear", class_="btn-warning")
else:
button = ui.input_action_button("finish", "Finish", class_="btn-default")
return ui.row(
ui.column(4, button),
ui.column(8, text),
class_="mt-3 p-3 border align-items-center",
style=css(text_decoration="line-through" if finished() else None),
)
@reactive.Effect
@reactive.event(input.finish)
def finish_task():
finished.set(True)
@reactive.Effect
@reactive.event(input.clear)
def clear_task():
ui.remove_ui(selector=f"div#{session.ns('button_row')}")
# Since remove_ui only removes the HTML the reactive effects will be held
# in memory unless they're explicitly destroyed. This isn't a big
# deal because they're very small, but it's good to clean them up.
finish_task.destroy()
clear_task.destroy()
# Returning the input.finish button to the parent scope allows us
# to react to it in the parent context to keep track of the number of
# completed tasks.
#
# This is a good pattern because it makes the module more general.
# The same module can be used by different applications which may
# do different things when the task is completed.
return input.finish
app = App(app_ui, server)
## file: requirements.txt
shinyswatch
from shiny import Inputs, Outputs, Session, App, render, ui
app_ui = ui.page_fluid(
ui.input_slider("n", "N", 0, 100, 20),
ui.output_text_verbatim("txt"),
)
def server(input: Inputs, output: Outputs, session: Session):
@render.text
def txt():
return f"n*2 is {input.n() * 2}"
app = App(app_ui, server)
from shiny import Inputs, Outputs, Session, App, render, ui
app_ui = ui.page_fluid(
ui.input_slider("n", "N", 0, 100, 20),
ui.output_text_verbatim("txt"),
)
def server(input: Inputs, output: Outputs, session: Session):
@render.text
def txt():
return f"n*2 is {input.n() * 2}"
app = App(app_ui, server)
from shiny import Inputs, Outputs, Session, App, render, ui
app_ui = ui.page_fluid(
ui.input_slider("n", "N", 0, 100, 20),
ui.output_text_verbatim("txt"),
)
def server(input: Inputs, output: Outputs, session: Session):
@render.text
def txt():
return f"n*2 is {input.n() * 2}"
app = App(app_ui, server)
from shiny import Inputs, Outputs, Session, App, render, ui
app_ui = ui.page_fluid(
ui.input_slider("n", "N", 0, 100, 20),
ui.output_text_verbatim("txt"),
)
def server(input: Inputs, output: Outputs, session: Session):
@render.text
def txt():
return f"n*2 is {input.n() * 2}"
app = App(app_ui, server)
flowchart TD S[Input] --> Sc((Output))
flowchart TD C[Metric\nSelector] --> Sc((Metric\nPlot)) Sl[Account\nSelector] --> Sc Sl --> M((Dist Plot)) linkStyle 0 display:none linkStyle 1 display:none linkStyle 2 display:none
flowchart TD C[Metric\nSelector] --> Sc((Metric\nPlot)):::changed Sl[Account\nSelector] --> Sc Sl --> M((Dist Plot)) linkStyle 0 display:none linkStyle 1 display:none linkStyle 2 display:none classDef changed fill:#f96
flowchart TD C[Metric\nSelector] --> Sc((Metric\nPlot)):::changed Sl[Account\nSelector] --> Sc Sl --> M((Dist Plot)) linkStyle 2 display:none classDef changed fill:#f96
flowchart TD C[Metric\nSelector] --> Sc((Metric\nPlot)) Sl[Account\nSelector] --> Sc Sl --> M((Dist Plot)):::changed linkStyle 2 display:none classDef changed fill:#f96
flowchart TD C[Metric\nSelector] --> Sc((Metric\nPlot)) Sl[Account\nSelector] --> Sc Sl --> M((Dist Plot)):::changed classDef changed fill:#f96
flowchart TD C[Metric\nSelector] --> Sc((Metric\nPlot)) Sl[Account\nSelector] --> Sc Sl --> M((Dist Plot))
flowchart TD C[Metric\nSelector] --> Sc((Metric\nPlot)) Sl[Account\nSelector]:::changed --> Sc Sl --> M((Dist Plot)) classDef changed fill:#f96
flowchart TD C[Metric\nSelector] --> Sc((Metric\nPlot)):::changed Sl[Account\nSelector]:::changed --> Sc Sl --> M((Dist Plot)):::changed classDef changed fill:#f96
flowchart TD C[Metric\nSelector] --> Sc((Metric\nPlot)) Sl[Account\nSelector] --> Sc Sl --> M((Dist Plot)) classDef changed fill:#f96 linkStyle 0 display:none linkStyle 1 display:none linkStyle 2 display:none
flowchart TD C[Metric\nSelector] --> Sc((Metric\nPlot)):::changed Sl[Account\nSelector] --> Sc Sl --> M((Dist Plot)) classDef changed fill:#f96 linkStyle 0 display:none linkStyle 1 display:none linkStyle 2 display:none
flowchart TD C[Metric\nSelector] --> Sc((Metric\nPlot)):::changed Sl[Account\nSelector] --> Sc Sl --> M((Dist Plot)) classDef changed fill:#f96 linkStyle 2 display:none
flowchart TD C[Metric\nSelector] --> Sc((Metric\nPlot)) Sl[Account\nSelector] --> Sc Sl --> M((Dist Plot)):::changed classDef changed fill:#f96 linkStyle 2 display:none
flowchart TD C[Metric\nSelector] --> Sc((Metric\nPlot)) Sl[Account\nSelector] --> Sc Sl --> M((Dist Plot)):::changed classDef changed fill:#f96
flowchart TD C[Metric\nSelector] --> Sc((Metric\nPlot)) Sl[Account\nSelector] --> Sc Sl --> M((Dist Plot)) classDef changed fill:#f96
flowchart TD C[Metric\nSelector]:::changed --> Sc((Metric\nPlot)) Sl[Account\nSelector] --> Sc Sl --> M((Dist Plot)) classDef changed fill:#f96
flowchart TD C[Metric\nSelector]:::changed --> Sc((Metric\nPlot)):::changed Sl[Account\nSelector] --> Sc Sl --> M((Dist Plot)) classDef changed fill:#f96
flowchart TD C[Metric\nSelector] --> Sc((Metric\nPlot)):::changed Sl[Account\nSelector] --> Sc Sl --> M((Dist Plot)) classDef changed fill:#f96 linkStyle 0 display:none linkStyle 1 display:none
flowchart TD C[Metric\nSelector] --> Sc((Metric\nPlot)):::changed Sl[Account\nSelector] --> Sc Sl --> M((Dist Plot)) classDef changed fill:#f96 linkStyle 0 display:none linkStyle 1 display:none
flowchart TD C[Metric\nSelector] --> Sc((Metric\nPlot)):::changed Sl[Account\nSelector] --> Sc Sl --> M((Dist Plot)) classDef changed fill:#f96
flowchart TD C[Metric\nSelector] --> Sc((Metric\nPlot)) Sl[Account\nSelector] --> Sc Sl --> M((Dist Plot)) classDef changed fill:#f96
#| standalone: true
#| components: [viewer]
#| layout: horizontal
#| viewerHeight: 500
from shiny import Inputs, Outputs, Session, App, reactive, render, req, ui
import random
app_ui = ui.page_sidebar(
ui.sidebar(
ui.input_radio_buttons(
"choice", "Which slider?", choices=["Slider 1", "Slider 2"]
),
ui.input_slider("slider_1", "Slider 1", 0, 100, 15),
ui.input_slider("slider_2", "Slider 2", 0, 100, 45),
),
ui.card({"style": "font-size: larger"}, ui.output_text("txt")),
)
def server(input: Inputs, output: Outputs, session: Session):
@render.text
def txt():
random_number = random.randint(0, 100)
if input.choice() == "Slider 1":
return f"Slider 1 is {input.slider_1()}, a random number is {random_number}"
else:
return f"Slider 2 is {input.slider_2()}, a random number is {random_number}"
app = App(app_ui, server)
flowchart TD C[Buttons] --> T((Text Output)) S1[Slider 1] --> T S2[Slider 2] --> T linkStyle 0 display:none linkStyle 1 display:none linkStyle 2 display:none classDef changed fill:#f96
flowchart TD C[Buttons] --> T((Text Output)):::changed S1[Slider 1] --> T S2[Slider 2] --> T linkStyle 0 display:none linkStyle 1 display:none linkStyle 2 display:none classDef changed fill:#f96
flowchart TD C[Buttons]:::changed --> T((Text Output)):::changed S1[Slider 1] --> T S2[Slider 2] --> T linkStyle 1 display:none linkStyle 2 display:none classDef changed fill:#f96
flowchart TD C[Buttons] --> T((Text Output)):::changed S1[Slider 1]:::changed --> T S2[Slider 2] --> T linkStyle 2 display:none classDef changed fill:#f96
flowchart TD C[Buttons] --> T((Text Output)) S1[Slider 1] --> T S2[Slider 2] --> T linkStyle 2 display:none classDef changed fill:#f96
flowchart TD C[Buttons] --> T((Text Output)) S1[Slider 1] --> T S2[Slider 2]:::changed --> T linkStyle 2 display:none classDef changed fill:#f96
flowchart TD C[Buttons] --> T((Text Output)) S1[Slider 1] --> T S2[Slider 2] --> T linkStyle 2 display:none classDef changed fill:#f96
flowchart TD C[Buttons] --> T((Text Output)) S1[Slider 1]:::changed --> T S2[Slider 2] --> T linkStyle 2 display:none classDef changed fill:#f96
flowchart TD C[Buttons] --> T((Text Output)):::changed S1[Slider 1]:::changed --> T S2[Slider 2] --> T linkStyle 0 display:none linkStyle 1 display:none linkStyle 2 display:none classDef changed fill:#f96
flowchart TD C[Buttons] --> T((Text Output)):::changed S1[Slider 1] --> T S2[Slider 2] --> T linkStyle 0 display:none linkStyle 1 display:none linkStyle 2 display:none classDef changed fill:#f96
flowchart TD C[Buttons]:::changed --> T((Text Output)):::changed S1[Slider 1] --> T S2[Slider 2] --> T linkStyle 1 display:none linkStyle 2 display:none classDef changed fill:#f96
flowchart TD C[Buttons] --> T((Text Output)):::changed S1[Slider 1]:::changed --> T S2[Slider 2] --> T linkStyle 2 display:none classDef changed fill:#f96
flowchart TD C[Buttons] --> T((Text Output)) S1[Slider 1] --> T S2[Slider 2] --> T linkStyle 2 display:none classDef changed fill:#f96
flowchart TD C[Buttons]:::changed --> T((Text Output)) S1[Slider 1] --> T S2[Slider 2] --> T linkStyle 2 display:none classDef changed fill:#f96
flowchart TD C[Buttons]:::changed --> T((Text Output)):::changed S1[Slider 1] --> T S2[Slider 2] --> T linkStyle 2 display:none classDef changed fill:#f96
flowchart TD C[Buttons] --> T((Text Output)):::changed S1[Slider 1] --> T S2[Slider 2] --> T linkStyle 0 display:none linkStyle 1 display:none linkStyle 2 display:none classDef changed fill:#f96
flowchart TD C[Buttons]:::changed --> T((Text Output)):::changed S1[Slider 1] --> T S2[Slider 2] --> T linkStyle 1 display:none linkStyle 2 display:none classDef changed fill:#f96
flowchart TD C[Buttons] --> T((Text Output)):::changed S1[Slider 1] --> T S2[Slider 2]:::changed --> T linkStyle 1 display:none classDef changed fill:#f96
flowchart TD C[Buttons] --> T((Text Output)) S1[Slider 1] --> T S2[Slider 2] --> T linkStyle 1 display:none classDef changed fill:#f96
@reactive.Calc
creates calculations whose results are used by other functions@reactive.Calc
decorator @reactive.Calc
def sampled_data():
start_date, end_date = input.dates()
start_date = pd.to_datetime(start_date)
end_date = pd.to_datetime(end_date)
return query_db(start_date, end_date, input.sample_size())
@reactive.Calc()
def filtered_data():
filtered = sampled_data()
filtered = filtered.loc[filtered["account"] == input.account()]
return filtered
@render.plot():
def scores():
return plot_scores(filtered_data())
@reactive.Calc
def sampled_data():
start_date, end_date = input.dates()
start_date = pd.to_datetime(start_date)
end_date = pd.to_datetime(end_date)
return query_db(start_date, end_date, input.sample_size())
@reactive.Calc()
def filtered_data():
filtered = sampled_data()
filtered = filtered.loc[filtered["account"] == input.account()]
return filtered
@render.plot():
def scores():
return plot_scores(filtered_data())
flowchart TD D[Dates] --> Sa{{Sample}} S[Sample Size] --> Sa A[Account] --> F Sa --> F{{Filtered}} F --> P2((Model\nScores)) F --> P1((API\nResponse)) classDef changed fill:#f96 linkStyle 0,1,2,3,4,5 display:none
flowchart TD D[Dates] --> Sa{{Sample}} S[Sample Size] --> Sa A[Account] --> F Sa --> F{{Filtered}} F --> P2((Model\nScores)):::changed F --> P1((API\nResponse)) classDef changed fill:#f96 linkStyle 0,1,2,3,4,5 display:none
flowchart TD D[Dates] --> Sa{{Sample}} S[Sample Size] --> Sa A[Account] --> F Sa --> F{{Filtered}}:::changed F --> P2((Model\nScores)) F --> P1((API\nResponse)) classDef changed fill:#f96 linkStyle 0,1,2,3,5 display:none
flowchart TD D[Dates] --> Sa{{Sample}} S[Sample Size] --> Sa A[Account]:::changed --> F Sa --> F{{Filtered}} F --> P2((Model\nScores)) F --> P1((API\nResponse)) classDef changed fill:#f96 linkStyle 0,1,3,5 display:none
flowchart TD D[Dates] --> Sa{{Sample}}:::changed S[Sample Size] --> Sa A[Account] --> F Sa --> F{{Filtered}} F --> P2((Model\nScores)) F --> P1((API\nResponse)) classDef changed fill:#f96 linkStyle 0,1,5 display:none
flowchart TD D[Dates]:::changed --> Sa{{Sample}} S[Sample Size]:::changed --> Sa A[Account] --> F Sa --> F{{Filtered}} F --> P2((Model\nScores)) F --> P1((API\nResponse)) classDef changed fill:#f96 linkStyle 5 display:none
flowchart TD D[Dates] --> Sa{{Sample}} S[Sample Size] --> Sa A[Account] --> F Sa --> F{{Filtered}} F --> P2((Model\nScores)) F --> P1((API\nResponse)):::changed classDef changed fill:#f96 linkStyle 5 display:none
flowchart TD D[Dates] --> Sa{{Sample}} S[Sample Size] --> Sa A[Account] --> F Sa --> F{{Filtered}} F --> P2((Model\nScores)) F --> P1((API\nResponse)) classDef changed fill:#f96
flowchart TD D[Dates] --> Sa{{Sample}} S[Sample Size] --> Sa A[Account]:::changed --> F Sa --> F{{Filtered}} F --> P2((Model\nScores)) F --> P1((API\nResponse)) classDef changed fill:#f96
flowchart TD D[Dates] --> Sa{{Sample}} S[Sample Size] --> Sa A[Account] --> F Sa --> F{{Filtered}}:::changed F --> P2((Model\nScores)) F --> P1((API\nResponse)) classDef changed fill:#f96 linkStyle 2,3 display:none
flowchart TD D[Dates] --> Sa{{Sample}} S[Sample Size] --> Sa A[Account] --> F Sa --> F{{Filtered}} F --> P2((Model\nScores)):::changed F --> P1((API\nResponse)):::changed classDef changed fill:#f96 linkStyle 2,3,4,5 display:none
flowchart TD D[Dates] --> Sa{{Sample}} S[Sample Size] --> Sa A[Account] --> F Sa --> F{{Filtered}} F --> P2((Model\nScores)):::changed F --> P1((API\nResponse)) classDef changed fill:#f96 linkStyle 2,3,4,5 display:none
flowchart TD D[Dates] --> Sa{{Sample}} S[Sample Size] --> Sa A[Account] --> F Sa --> F{{Filtered}}:::changed F --> P2((Model\nScores)) F --> P1((API\nResponse)) classDef changed fill:#f96 linkStyle 2,3,5 display:none
flowchart TD D[Dates] --> Sa{{Sample}} S[Sample Size] --> Sa A[Account]:::changed --> F Sa --> F{{Filtered}} F --> P2((Model\nScores)) F --> P1((API\nResponse)) classDef changed fill:#f96 linkStyle 5 display:none
flowchart TD D[Dates] --> Sa{{Sample}} S[Sample Size] --> Sa A[Account] --> F Sa --> F{{Filtered}} F --> P2((Model\nScores)) F --> P1((API\nResponse)):::changed classDef changed fill:#f96 linkStyle 5 display:none
flowchart TD D[Dates] --> Sa{{Sample}} S[Sample Size] --> Sa A[Account] --> F Sa --> F{{Filtered}} F --> P2((Model\nScores)) F --> P1((API\nResponse)) classDef changed fill:#f96
flowchart TD D[Dates] --> Sa{{Sample}} S[Sample Size]:::changed --> Sa A[Account] --> F Sa --> F{{Filtered}} F --> P2((Model\nScores)) F --> P1((API\nResponse)) classDef changed fill:#f96
flowchart TD D[Dates] --> Sa{{Sample}}:::changed S[Sample Size] --> Sa A[Account] --> F Sa --> F{{Filtered}} F --> P2((Model\nScores)) F --> P1((API\nResponse)) classDef changed fill:#f96 linkStyle 0,1 display:none
flowchart TD D[Dates] --> Sa{{Sample}} S[Sample Size] --> Sa A[Account] --> F Sa --> F{{Filtered}}:::changed F --> P2((Model\nScores)) F --> P1((API\nResponse)) classDef changed fill:#f96 linkStyle 0,1,2,3 display:none
flowchart TD D[Dates] --> Sa{{Sample}} S[Sample Size] --> Sa A[Account] --> F Sa --> F{{Filtered}} F --> P2((Model\nScores)):::changed F --> P1((API\nResponse)):::changed classDef changed fill:#f96 linkStyle 0,1,2,3,4,5 display:none
flowchart TD D[Dates] --> Sa{{Sample}} S[Sample Size] --> Sa A[Account] --> F Sa --> F{{Filtered}} F --> P2((Model\nScores)) F --> P1((API\nResponse)) classDef changed fill:#f96 linkStyle 0,1,2,3,4,5 display:none
flowchart TD D[Dates] --> Sa{{Sample}} S[Sample Size] --> Sa A[Account] --> F Sa --> F{{Filtered}} F --> P2((Model\nScores)):::changed F --> P1((API\nResponse)) classDef changed fill:#f96 linkStyle 0,1,2,3,4,5 display:none
flowchart TD D[Dates] --> Sa{{Sample}} S[Sample Size] --> Sa A[Account] --> F Sa --> F{{Filtered}}:::changed F --> P2((Model\nScores)) F --> P1((API\nResponse)) classDef changed fill:#f96 linkStyle 0,1,2,3,5 display:none
flowchart TD D[Dates] --> Sa{{Sample}} S[Sample Size] --> Sa A[Account]:::changed --> F Sa --> F{{Filtered}} F --> P2((Model\nScores)) F --> P1((API\nResponse)) classDef changed fill:#f96 linkStyle 0,1,3,5 display:none
flowchart TD D[Dates] --> Sa{{Sample}}:::changed S[Sample Size] --> Sa A[Account] --> F Sa --> F{{Filtered}} F --> P2((Model\nScores)) F --> P1((API\nResponse)) classDef changed fill:#f96 linkStyle 0,1,5 display:none
flowchart TD D[Dates]:::changed --> Sa{{Sample}} S[Sample Size]:::changed --> Sa A[Account] --> F Sa --> F{{Filtered}} F --> P2((Model\nScores)) F --> P1((API\nResponse)) classDef changed fill:#f96 linkStyle 5 display:none
flowchart TD D[Dates] --> Sa{{Sample}} S[Sample Size] --> Sa A[Account] --> F Sa --> F{{Filtered}} F --> P2((Model\nScores)) F --> P1((API\nResponse)):::changed classDef changed fill:#f96 linkStyle 5 display:none
flowchart TD D[Dates] --> Sa{{Sample}} S[Sample Size] --> Sa A[Account] --> F Sa --> F{{Filtered}} F --> P2((Model\nScores)) F --> P1((API\nResponse)) classDef changed fill:#f96
@reactive.event
can be paired with rendering functions and reactive.Calc
@reactive.Effect
is for side effects:
@reactive.Calc
is for values
reactive.isolate
to prevent cyclesreactive.poll
reactive.invalidate_later
reactive.Value