shiny.reactive.Calc#

shiny.reactive.Calc(fn: Callable[[], Awaitable[shiny.reactive._reactives.T]]) shiny.reactive._reactives.CalcAsync_[shiny.reactive._reactives.T]#
shiny.reactive.Calc(fn: Callable[[], shiny.reactive._reactives.T]) shiny.reactive._reactives.Calc_[shiny.reactive._reactives.T]
shiny.reactive.Calc(*, session: Optional[Union[shiny.types.MISSING_TYPE, shiny.session._session.Session]] = 'MISSING') Callable[[Callable[[], shiny.reactive._reactives.T]], shiny.reactive._reactives.Calc_[shiny.reactive._reactives.T]]

Mark a function as a reactive calculation.

A reactive calculation is a function whose return value depends solely on other reactive value(s) (i.e., Inputs, Value, and other reactive calculations). Whenever a reactive value changes, any reactive calculations that depend on it are “invalidated” and automatically re-execute when necessary. If a reactive calculation is marked as invalidated, any other reactive calculations that recently called it are also marked as invalidated. In this way, invalidations ripple through reactive calculations that depend on each other.

Parameters

session (Union[MISSING_TYPE, Session, None]) – A Session instance. If not provided, it is inferred via get_current_session().

Return type

A decorator that marks a function as a reactive calculation.

Tip

Reactive calculations should not produce any side effects; to reactively produce side effects, use Effect() instead.

Example

#| standalone: true
#| components: [editor, viewer]
#| layout: vertical
#| viewerHeight: 400
from shiny import *
import time
import random

app_ui = ui.page_fluid(
    ui.input_action_button("first", "Invalidate first (slow) computation"),
    ui.input_action_button("second", "Invalidate second (fast) computation"),
    ui.br(),
    ui.output_ui("result"),
)

def server(input: Inputs, output: Outputs, session: Session):
    @reactive.Calc
    def first():
        input.first()
        p = ui.Progress()
        for i in range(30):
            p.set(i / 30, message="Computing, please wait...")
            time.sleep(0.1)
        p.close()
        return random.randint(1, 1000)

    @reactive.Calc
    def second():
        input.second()
        return random.randint(1, 1000)

    @output
    @render.ui
    def result():
        return first() + second()


app = App(app_ui, server)