Skip to content

Commit

Permalink
Add docs for Express modules (#1535)
Browse files Browse the repository at this point in the history
  • Loading branch information
wch authored Jul 17, 2024
1 parent da6e957 commit a1f0997
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 23 deletions.
31 changes: 17 additions & 14 deletions shiny/api-examples/render_express/app-core.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
import datetime
from shiny import App, render, ui

from shiny.express import input, render, ui
app_ui = ui.page_fluid(
ui.input_text("name", "Name", "Socrates"),
ui.input_text("years", "Years", "470-399 BC"),
ui.output_ui("person"),
)

with ui.card(id="card"):
ui.input_slider("val", "slider", 0, 100, 50)
"Text outside of render express call"
ui.tags.br()
f"Rendered time: {str(datetime.datetime.now())}"

def server(input, output, session):

@render.express
def render_express():
"Text inside of render express call"
ui.tags.br()
"Dynamic slider value: "
input.val()
ui.tags.br()
f"Rendered time: {str(datetime.datetime.now())}"
def person():
from shiny.express import ui

with ui.card(class_="mt-3"):
ui.h3(input.name())
input.years()


app = App(app_ui, server)
11 changes: 11 additions & 0 deletions shiny/api-examples/render_express/app-express.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from shiny.express import input, render, ui

ui.input_text("name", "Name", "Socrates")
ui.input_text("years", "Years", "470-399 BC")


@render.express
def person():
with ui.card(class_="mt-3"):
ui.h3(input.name())
input.years()
21 changes: 21 additions & 0 deletions shiny/express/_module.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,27 @@
def module(
fn: Callable[Concatenate[Inputs, Outputs, Session, P], R]
) -> Callable[Concatenate[Id, P], R]:
"""
Create a Shiny module using Shiny Express syntax
This function is used to create a Shiny module, where the code inside the function
uses Shiny Express syntax. This is in contrast to the pair of functions
:func:`~shiny.module.ui()` and :func:`~shiny.module.server()`, which are used to
create Shiny modules with Core syntax.
Parameters
----------
fn
The function that defines the module. The first three parameters of this
function must be `input`, `output`, and `session`. Any additional parameters can
used to pass information to the module.
See Also
--------
* ~shiny.module.ui
* ~shiny.module.server
* ~shiny.express.expressify
"""
fn = expressify(fn)

@functools.wraps(fn)
Expand Down
6 changes: 6 additions & 0 deletions shiny/render/_express.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@
from htmltools import Tag, TagAttrValue, TagFunction, TagList, wrap_displayhook_handler

from .. import ui as _ui
from .._docstring import add_example
from .._typing_extensions import Self
from ..session._utils import require_active_session
from ..types import MISSING, MISSING_TYPE, JsonifiableDict
from .renderer import AsyncValueFn, Renderer, ValueFn
from .renderer._utils import rendered_deps_to_jsonifiable, set_kwargs_value


@add_example(ex_dir="../api-examples/render_express")
class express(Renderer[None]):
"""
Reactively render HTML content with output captured as in Shiny Express
Expand All @@ -23,6 +25,10 @@ class express(Renderer[None]):
:func:`~sys.displayhook()` on the result. This has the effect of "capturing" the
output of each line.
This decorator can be thought of as a combination of :class:`~shiny.render.ui` (for
rendering and sending the dynamic UI to the client), and `~shiny.express.expressify`
(for capturing the output of each line).
Returns
-------
:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,5 @@

def test_render_express(page: Page, app: ShinyAppProc) -> None:
page.goto(app.url)
expect(page.get_by_text("Text outside of render express call")).to_have_count(
1, timeout=EXPECT_TIMEOUT
)
expect(page.get_by_text("Text inside of render express call")).to_have_count(
1, timeout=EXPECT_TIMEOUT
)
expect(page.get_by_text("Dynamic slider value: 50")).to_have_count(
1, timeout=EXPECT_TIMEOUT
)
expect(page.get_by_text("Name")).to_have_count(1, timeout=EXPECT_TIMEOUT)
expect(page.get_by_text("Socrates")).to_have_count(1, timeout=EXPECT_TIMEOUT)

0 comments on commit a1f0997

Please sign in to comment.