From 00c0ab955ea3258a32c68631e5fe764d5139075f Mon Sep 17 00:00:00 2001 From: Garrett Grolemund Date: Thu, 7 Dec 2023 12:59:43 -0600 Subject: [PATCH 01/13] Proofreads experimental section --- shiny/experimental/ui/_card.py | 174 +++++++++++++++++---------------- 1 file changed, 89 insertions(+), 85 deletions(-) diff --git a/shiny/experimental/ui/_card.py b/shiny/experimental/ui/_card.py index 6acd6b641..12f795af7 100644 --- a/shiny/experimental/ui/_card.py +++ b/shiny/experimental/ui/_card.py @@ -7,14 +7,14 @@ from typing import Literal, Optional, Protocol from htmltools import ( - Tag, - TagAttrs, - TagAttrValue, - TagChild, - TagFunction, - Tagifiable, - css, - tags, + Tag, + TagAttrs, + TagAttrValue, + TagChild, + TagFunction, + Tagifiable, + css, + tags, ) from ...types import MISSING, MISSING_TYPE @@ -23,55 +23,55 @@ from ...ui.fill import as_fill_item, as_fillable_container __all__ = ( - # Worried about `wrapper` - "card", - # Do not want to expose card_body yet - "card_body", - # Questioning: - "card_title", - "card_image", + # Worried about `wrapper` + "card", + # Do not want to expose card_body yet + "card_body", + # Questioning: + "card_title", + "card_image", ) # TODO-maindocs; @add_example() def card( - *args: TagChild | TagAttrs | CardItem, - full_screen: bool = False, - height: Optional[CssUnit] = None, - max_height: Optional[CssUnit] = None, - min_height: Optional[CssUnit] = None, - fill: bool = True, - class_: Optional[str] = None, - wrapper: WrapperCallable | None | MISSING_TYPE = MISSING, - **kwargs: TagAttrValue, + *args: TagChild | TagAttrs | CardItem, + full_screen: bool = False, + height: Optional[CssUnit] = None, + max_height: Optional[CssUnit] = None, + min_height: Optional[CssUnit] = None, + fill: bool = True, + class_: Optional[str] = None, + wrapper: WrapperCallable | None | MISSING_TYPE = MISSING, + **kwargs: TagAttrValue, ) -> Tag: """ A Bootstrap card component - A general purpose container for grouping related UI elements together with a border - and optional padding. To learn more about `card()`s, see [this + A card is a general purpose container that groups related UI elements together with a border + and optional padding. To learn more about `card()`s, see [the bslib card article](https://rstudio.github.io/bslib/articles/cards.html). Parameters ---------- *args - Unnamed arguments can be any valid child of an :class:`~htmltools.Tag` (which - includes card items such as :func:`~shiny.experimental.ui.card_body`. + Unnamed arguments can be any valid child of an :class:`~htmltools.Tag` (This + includes card items such as :func:`~shiny.experimental.ui.card_body`). full_screen - If `True`, an icon will appear when hovering over the card body. Clicking the + If `True`, an icon will appear when the user's pointer hovers over the card body. Clicking the icon expands the card to fit viewport size. - height,max_height,min_height - Any valid CSS unit (e.g., `height="200px"`). Doesn't apply when a card is made - `full_screen` (in this case, consider setting a `height` in - :func:`~shiny.experimental.ui.card_body`). + height, max_height, min_height + Any valid CSS unit (e.g., `height="200px"`). These will not apply when a card is made + `full_screen`. In this case, consider setting a `height` in + :func:`~shiny.experimental.ui.card_body`. fill Whether or not to allow the card to grow/shrink to fit a fillable container with an opinionated height (e.g., :func:`~shiny.ui.page_fillable`). class_ Additional CSS classes for the returned Tag. wrapper - A function (which returns a UI element) to call on unnamed arguments in `*args` - which are not already card item(s) (like + A function that returns a UI element to call on any unnamed arguments in `*args` + that are not already card item(s) (like :func:`~shiny.ui.card_header`, :func:`~shiny.experimental.ui.card_body`, etc.). Note that non-card items are grouped together into one `wrapper` call (e.g. given `card("a", "b", @@ -83,29 +83,29 @@ def card( Returns ------- : - An :func:`~shiny.ui.tags.div` tag. + A :func:`~shiny.ui.tags.div` tag. See Also -------- - * :func:`~shiny.ui.layout_column_wrap` for laying out multiple cards - (or multiple columns inside a card). - * :func:`~shiny.ui.card_header` for creating a header within the card. - * :func:`~shiny.experimental.ui.card_title` for creating a title within the card body. - * :func:`~shiny.experimental.ui.card_body` for putting content inside the card. - * :func:`~shiny.ui.card_footer` for creating a footer within the card. - * :func:`~shiny.experimental.ui.card_image` for adding an image to the card. + * :func:`~shiny.ui.layout_column_wrap` for laying out multiple cards + or multiple columns inside a card. + * :func:`~shiny.ui.card_header` for creating a header within a card. + * :func:`~shiny.experimental.ui.card_title` for creating a title within a card body. + * :func:`~shiny.experimental.ui.card_body` for putting content inside a card. + * :func:`~shiny.ui.card_footer` for creating a footer within a card. + * :func:`~shiny.experimental.ui.card_image` for adding an image to a card. """ - return _card_impl( - *args, - full_screen=full_screen, - height=height, - max_height=max_height, - min_height=min_height, - fill=fill, - class_=class_, - wrapper=wrapper, - **kwargs, - ) +return _card_impl( + *args, + full_screen=full_screen, + height=height, + max_height=max_height, + min_height=min_height, + fill=fill, + class_=class_, + wrapper=wrapper, + **kwargs, +) ############################################################################ @@ -113,38 +113,40 @@ def card( # TODO-maindocs; @add_example() def card_title( - *args: TagChild | TagAttrs, - container: TagFunction = tags.h5, - **kwargs: TagAttrValue, + *args: TagChild | TagAttrs, + container: TagFunction = tags.h5, + **kwargs: TagAttrValue, ) -> Tagifiable: """ - Card title container + A card title container - A general container for the "title" of a :func:`~shiny.ui.card`. This component is designed + :func:`~shiny.experimental.ui.card_title` creates a general container for the "title" of + a :func:`~shiny.ui.card`. This component is designed to be provided as a direct child to :func:`~shiny.ui.card`. Parameters ---------- *args - Contents to the card's title. Or tag attributes that are supplied to the + Contents to appear in the card's title, or tag attributes to pass to the resolved :class:`~htmltools.Tag` object. container - Method for the returned Tag object. Defaults to :func:`shiny.ui.tags.h5`. + Method for the returned :class:`~htmltools.Tag` object. Defaults to + :func:`~shiny.ui.tags`.h5. **kwargs - Additional HTML attributes for the returned Tag. + Additional HTML attributes for the returned :class:`~htmltools.Tag` object. Returns ------- : - A Tag object. + An :class:`~htmltools.Tag` object. See Also -------- * :func:`~shiny.ui.card` for creating a card component. - * :func:`~shiny.ui.card_header` for creating a header within the card. - * :func:`~shiny.experimental.ui.card_body` for putting content inside the card. - * :func:`~shiny.ui.card_footer` for creating a footer within the card. - * :func:`~shiny.experimental.ui.card_image` for adding an image to the card. + * :func:`~shiny.ui.card_header` for creating a header within a card. + * :func:`~shiny.experimental.ui.card_body` for putting content inside a card. + * :func:`~shiny.ui.card_footer` for creating a footer within a card. + * :func:`~shiny.experimental.ui.card_image` for adding an image to a card. """ return container(*args, **kwargs) @@ -188,21 +190,22 @@ def card_image( **kwargs: TagAttrValue, ) -> Tagifiable: """ - Card image container + A card image container - A general container for an image within a :func:`~shiny.ui.card`. This component is designed to be + :func:`~shiny.experimental.ui.card_image` creates a general container for an image within a + :func:`~shiny.ui.card`. This component is designed to be provided as a direct child to :func:`~shiny.ui.card`. Parameters ---------- file - A file path pointing an image. The image will be base64 encoded and provided to - the `src` attribute of the ``. Alternatively, you may set this value to + A file path pointing to an image. The image will be base64 encoded and provided to + the `src` attribute of the `` tag. Alternatively, you may set this value to `None` and provide the `src` yourself via `*args:TagAttrs` or - `**kwargs:TagAttrValue` (e.g. `{"src": "HOSTED_PATH_TO_IMAGE"}` or + `**kwargs:TagAttrValue` (e.g., `{"src": "HOSTED_PATH_TO_IMAGE"}` or `src="HOSTED_PATH_TO_IMAGE"`). *args - Dictionary of tag attributes that are supplied to the resolved + A dictionary of tag attributes that are supplied to the resolved :class:`~htmltools.Tag` object. href An optional URL to link to. @@ -211,23 +214,24 @@ def card_image( mime_type The mime type of the `file`. class_ - Additional CSS classes for the resolved Tag. + Additional CSS classes for the resolved :class:`~htmltools.Tag` object. height - Any valid CSS unit (e.g., `height="200px"`). Doesn't apply when a card is made - `full_screen` (in this case, consider setting a `height` in - :func:`~shiny.experimental.ui.card_body`). + Any valid CSS unit (e.g., `height="200px"`). `height` will not apply when a card is made + `full_screen`. In this case, consider setting a `height` in + :func:`~shiny.experimental.ui.card_body`. fill Whether to allow this element to grow/shrink to fit its `card` container. width Any valid CSS unit (e.g., `width="100%"`). container - Method to wrap the returned Tag object. Defaults to :func:`~shiny.experimental.ui.card_body`. + Method to wrap the returned :class:`~htmltools.Tag` object. Defaults to + :func:`~shiny.experimental.ui.card_body`. If :func:`~shiny.experimental.ui.card_body` is used, each image will be in separate cards. If the `container` method does not return a :class:`~shiny.ui.CardItem`, it allows for consecutive non-`CardItem` objects to be bundled into a single :func:`~shiny.experimental.ui.card_body` within :func:`~shiny.ui.card`. **kwargs - Additional HTML attributes for the resolved Tag. + Additional HTML attributes for the resolved :class:`~htmltools.Tag`. """ src = None if file is not None: @@ -238,20 +242,20 @@ def card_image( "`mime_type` must be provided when passing an in-memory buffer" ) src = f"data:{mime_type};base64,{b64_str}" - + elif isinstance(file, (str, Path, PurePath)): with open(file, "rb") as img_file: b64_str = base64.b64encode(img_file.read()).decode("utf-8") if mime_type is None: mime_type = mimetypes.guess_type(file)[0] src = f"data:{mime_type};base64,{b64_str}" - + card_class_map = { "all": "card-img", "top": "card-img-top", "bottom": "card-img-bottom", } - + image = tags.img( { "src": src, @@ -266,10 +270,10 @@ def card_image( class_=class_, **kwargs, ) - + if fill: image = as_fill_item(image) - + if href is not None: image = as_fillable_container( as_fill_item( @@ -279,7 +283,7 @@ def card_image( ) ) ) - + if container: return container(image) else: From 4cb8dac51181325bd7d91e2c3b2e8cc59332c3b4 Mon Sep 17 00:00:00 2001 From: Garrett Grolemund Date: Thu, 7 Dec 2023 14:48:26 -0600 Subject: [PATCH 02/13] Proofreads the deprecated section. --- shiny/experimental/ui/_deprecated.py | 92 ++++++++++++++-------------- shiny/ui/_sidebar.py | 5 +- 2 files changed, 48 insertions(+), 49 deletions(-) diff --git a/shiny/experimental/ui/_deprecated.py b/shiny/experimental/ui/_deprecated.py index 9fb3f1601..74421816d 100644 --- a/shiny/experimental/ui/_deprecated.py +++ b/shiny/experimental/ui/_deprecated.py @@ -212,7 +212,7 @@ def input_text_area( autocomplete: Optional[str] = None, spellcheck: Optional[Literal["true", "false"]] = None, ) -> Tag: - """Deprecated. Please use `shiny.ui.input_text_area()` instead.""" + """Deprecated. Please use :func:`~shiny.ui.input_text_area()` instead.""" warn_deprecated( "`shiny.experimental.ui.input_text_area()` is deprecated. " "This method will be removed in a future version, " @@ -249,7 +249,7 @@ def navset_pill_card( footer: TagChild = None, placement: Literal["above", "below"] = "above", ) -> MainNavSetCard: - """Deprecated. Please use `navset_card_pill()` instead of `navset_pill_card()`.""" + """Deprecated. Please use :func:`~navset_card_pill()` instead of `navset_pill_card()`.""" warn_deprecated( "`shiny.experimental.ui.navset_pill_card()` is deprecated. " "This method will be removed in a future version, " @@ -275,7 +275,7 @@ def navset_tab_card( header: TagChild = None, footer: TagChild = None, ) -> MainNavSetCard: - """Deprecated. Please use `navset_card_tab()` instead of `navset_tab_card()`.""" + """Deprecated. Please use :func:`~navset_card_tab()` instead of `navset_tab_card()`.""" warn_deprecated( "`shiny.experimental.ui.navset_tab_card()` is deprecated. " "This method will be removed in a future version, " @@ -304,7 +304,7 @@ def tooltip( options: Optional[dict[str, object]] = None, **kwargs: TagAttrValue, ) -> Tag: - """Deprecated. Please use `shiny.ui.tooltip()` instead.""" + """Deprecated. Please use :func:`~shiny.ui.tooltip()` instead.""" warn_deprecated( "`shiny.experimental.ui.tooltip()` is deprecated. " "This method will be removed in a future version, " @@ -322,7 +322,7 @@ def tooltip( # Deprecated 2023-08-23 def tooltip_update(id: str, *args: TagChild, session: Optional[Session] = None) -> None: - """Deprecated. Please use `shiny.ui.update_tooltip()` instead.""" + """Deprecated. Please use :func:`~shiny.ui.update_tooltip()` instead.""" warn_deprecated( "`shiny.experimental.ui.tooltip_update()` is deprecated. " "This method will be removed in a future version, " @@ -337,7 +337,7 @@ def tooltip_update(id: str, *args: TagChild, session: Optional[Session] = None) # Deprecated 2023-09-12 def update_tooltip(id: str, *args: TagChild, session: Optional[Session] = None) -> None: - """Deprecated. Please use `shiny.ui.update_tooltip()` instead.""" + """Deprecated. Please use :func:`~shiny.ui.update_tooltip()` instead.""" warn_deprecated( "`shiny.experimental.ui.update_tooltip()` is deprecated. " "This method will be removed in a future version, " @@ -356,7 +356,7 @@ def tooltip_toggle( show: Optional[bool] = None, session: Optional[Session] = None, ) -> None: - """Deprecated. Please use `shiny.ui.update_tooltip()`.""" + """Deprecated. Please use :func:`~shiny.ui.update_tooltip()`.""" warn_deprecated( "`shiny.experimental.ui.tooltip_toggle()` is deprecated. " "This method will be removed in a future version, " @@ -375,7 +375,7 @@ def toggle_tooltip( show: Optional[bool] = None, session: Optional[Session] = None, ) -> None: - """Deprecated. Please use `shiny.ui.update_tooltip()` instead.""" + """Deprecated. Please use :func:`~shiny.ui.update_tooltip()` instead.""" warn_deprecated( "`shiny.experimental.ui.tooltip_toggle()` is deprecated. " "This method will be removed in a future version, " @@ -438,7 +438,7 @@ def sidebar( gap: Optional[CssUnit] = None, padding: Optional[CssUnit | list[CssUnit]] = None, ) -> MainSidebar: - """Deprecated. Please use `shiny.ui.sidebar()` instead.""" + """Deprecated. Please use :func:`~shiny.ui.sidebar()` instead.""" warn_deprecated( "`shiny.experimental.ui.sidebar()` is deprecated. " "This method will be removed in a future version, " @@ -475,7 +475,7 @@ def layout_sidebar( height: Optional[CssUnit] = None, **kwargs: TagAttrValue, ) -> MainCardItem: - """Deprecated. Please use `shiny.ui.layout_sidebar()` instead.""" + """Deprecated. Please use :func:`~shiny.ui.layout_sidebar()` instead.""" warn_deprecated( "`shiny.experimental.ui.layout_sidebar()` is deprecated. " "This method will be removed in a future version, " @@ -505,7 +505,7 @@ def toggle_sidebar( open: Literal["toggle", "open", "closed", "always"] | bool | None = None, session: Session | None = None, ) -> None: - """Deprecated. Please use `shiny.ui.update_sidebar()` instead.""" + """Deprecated. Please use :func:`~shiny.ui.update_sidebar()` instead.""" warn_deprecated( "`shiny.experimental.ui.toggle_sidebar()` is deprecated. " "This method will be removed in a future version, " @@ -531,7 +531,7 @@ def sidebar_toggle( open: Literal["toggle", "open", "closed", "always"] | bool | None = None, session: Session | None = None, ) -> None: - """Deprecated. Please use `shiny.ui.update_sidebar()` instead of + """Deprecated. Please use :func:`~shiny.ui.update_sidebar()` instead of `shiny.experimental.ui.sidebar_toggle()`.""" warn_deprecated( "`shiny.experimental.ui.sidebar_toggle()` is deprecated. " @@ -553,7 +553,7 @@ def panel_sidebar( width: int = 4, **kwargs: TagAttrValue, ) -> DeprecatedPanelSidebar: - """Deprecated. Please use `shiny.ui.sidebar()` instead of + """Deprecated. Please use :func:`~shiny.ui.sidebar()` instead of `shiny.experimental.ui.panel_sidebar()`.""" warn_deprecated( "`shiny.experimental.ui.panel_sidebar()` is deprecated. " @@ -574,7 +574,7 @@ def panel_main( width: int = 8, **kwargs: TagAttrValue, ) -> DeprecatedPanelMain: - """Deprecated. Please use `shiny.ui.layout_sidebar()` instead of + """Deprecated. Please use :func:`~shiny.ui.layout_sidebar()` instead of `shiny.experimental.ui.panel_main()`.""" warn_deprecated( "`shiny.experimental.ui.panel_main()` is deprecated. " @@ -612,7 +612,7 @@ def as_css_unit(value: CssUnit) -> str: # Deprecated 2023-09-12 def as_css_unit(value: None | CssUnit) -> None | str: """ - Deprecated. Please use `shiny.ui.css_unit.as_css_unit()` instead. + Deprecated. Please use :func:`~shiny.ui.css_unit.as_css_unit()` instead. """ warn_deprecated( "`shiny.experimental.ui.as_css_unit()` is deprecated. " @@ -635,7 +635,7 @@ def as_css_padding(padding: None) -> None: # Deprecated 2023-09-12 def as_css_padding(padding: CssUnit | list[CssUnit] | None) -> str | None: """ - Deprecated. Please use `shiny.ui.css_unit.as_css_padding()` instead. + Deprecated. Please use :func:`~shiny.ui.css_unit.as_css_padding()` instead. """ warn_deprecated( "`shiny.experimental.ui.as_css_padding()` is deprecated. " @@ -660,7 +660,7 @@ def popover( options: Optional[dict[str, Any]] = None, **kwargs: TagAttrValue, ) -> Tag: - """Deprecated. Please use `shiny.ui.popover()` instead.""" + """Deprecated. Please use :func:`~shiny.ui.popover()` instead.""" warn_deprecated( "`shiny.experimental.ui.popover()` is deprecated. " "This method will be removed in a future version, " @@ -683,7 +683,7 @@ def toggle_popover( show: Optional[bool] = None, session: Optional[Session] = None, ) -> None: - """Deprecated. Please use `shiny.ui.update_popover()` instead.""" + """Deprecated. Please use :func:`~shiny.ui.update_popover()` instead.""" warn_deprecated( "`shiny.experimental.ui.update_popover()` is deprecated. " "This method will be removed in a future version, " @@ -699,7 +699,7 @@ def update_popover( title: Optional[TagChild] = None, session: Optional[Session] = None, ) -> None: - """Deprecated. Please use `shiny.ui.update_popover()` instead.""" + """Deprecated. Please use :func:`~shiny.ui.update_popover()` instead.""" warn_deprecated( "`shiny.experimental.ui.update_popover()` is deprecated. " "This method will be removed in a future version, " @@ -733,7 +733,7 @@ def accordion( height: Optional[CssUnit] = None, **kwargs: TagAttrValue, ) -> Tag: - """Deprecated. Please use `shiny.ui.accordion()` instead.""" + """Deprecated. Please use :func:`~shiny.ui.accordion()` instead.""" warn_deprecated( "`shiny.experimental.ui.accordion()` is deprecated. " "This method will be removed in a future version, " @@ -759,7 +759,7 @@ def accordion_panel( icon: Optional[TagChild] = None, **kwargs: TagAttrValue, ) -> MainAccordionPanel: - """Deprecated. Please use `shiny.ui.accordion_panel()` instead.""" + """Deprecated. Please use :func:`~shiny.ui.accordion_panel()` instead.""" warn_deprecated( "`shiny.experimental.ui.accordion_panel()` is deprecated. " "This method will be removed in a future version, " @@ -780,7 +780,7 @@ def accordion_panel_set( values: bool | str | list[str], session: Optional[Session] = None, ) -> None: - """Deprecated. Please use `shiny.ui.update_accordion()` instead.""" + """Deprecated. Please use :func:`~shiny.ui.update_accordion()` instead.""" warn_deprecated( "`shiny.experimental.ui.accordion_panel_set()` is deprecated. " "This method will be removed in a future version, " @@ -795,7 +795,7 @@ def accordion_panel_open( values: bool | str | list[str], session: Optional[Session] = None, ) -> None: - """Deprecated. Please use `shiny.ui.update_accordion_panel(id, value, show=True)` or `shiny.ui.update_accordion(id, show = True)` instead.""" + """Deprecated. Please use :func:`~shiny.ui.update_accordion_panel(id, value, show=True)` or :func:`~shiny.ui.update_accordion(id, show = True)` instead.""" warn_deprecated( "`shiny.experimental.ui.accordion_panel_open()` is deprecated. " "This method will be removed in a future version, " @@ -819,7 +819,7 @@ def accordion_panel_close( values: bool | str | list[str], session: Optional[Session] = None, ) -> None: - """Deprecated. Please use `shiny.ui.update_accordion_panel(id, value, show=False)` or `shiny.ui.update_accordion(id, show = False)` instead.""" + """Deprecated. Please use :func:`~shiny.ui.update_accordion_panel(id, value, show=False)` or :func:`~shiny.ui.update_accordion(id, show = False)` instead.""" warn_deprecated( "`shiny.experimental.ui.accordion_panel_close()` is deprecated. " "This method will be removed in a future version, " @@ -844,7 +844,7 @@ def accordion_panel_insert( position: Literal["after", "before"] = "after", session: Optional[Session] = None, ) -> None: - """Deprecated. Please use `shiny.ui.insert_accordion_panel()` instead.""" + """Deprecated. Please use :func:`~shiny.ui.insert_accordion_panel()` instead.""" warn_deprecated( "`shiny.experimental.ui.accordion_panel_insert()` is deprecated. " "This method will be removed in a future version, " @@ -865,7 +865,7 @@ def accordion_panel_remove( target: str | list[str], session: Optional[Session] = None, ) -> None: - """Deprecated. Please use `shiny.ui.remove_accordion_panel()` instead.""" + """Deprecated. Please use :func:`~shiny.ui.remove_accordion_panel()` instead.""" warn_deprecated( "`shiny.experimental.ui.accordion_panel_remove()` is deprecated. " "This method will be removed in a future version, " @@ -888,7 +888,7 @@ def update_accordion_panel( icon: TagChild | None | MISSING_TYPE = MISSING, session: Optional[Session] = None, ) -> None: - """Deprecated. Please use `shiny.ui.update_accordion_panel()` instead.""" + """Deprecated. Please use :func:`~shiny.ui.update_accordion_panel()` instead.""" warn_deprecated( "`shiny.experimental.ui.update_accordion_panel()` is deprecated. " "This method will be removed in a future version, " @@ -947,7 +947,7 @@ def as_fillable_container( max_height: None = None, gap: None = None, ) -> TagT: - """Deprecated. Please use `shiny.ui.fill.as_fillable_container()` instead.""" + """Deprecated. Please use :func:`~shiny.ui.fill.as_fillable_container()` instead.""" warn_deprecated( "`shiny.experimental.ui.as_fillable_container()` is deprecated. " "This method will be removed in a future version, " @@ -975,7 +975,7 @@ def as_fill_item( min_height: None = None, max_height: None = None, ) -> TagT: - """Deprecated. Please use `shiny.ui.fill.as_fill_item()` instead.""" + """Deprecated. Please use :func:`~shiny.ui.fill.as_fill_item()` instead.""" warn_deprecated( "`shiny.experimental.ui.as_fill_item()` is deprecated. " "This method will be removed in a future version, " @@ -994,7 +994,7 @@ def as_fill_item( def remove_all_fill(tag: TagT) -> TagT: - """Deprecated. Please use `shiny.ui.fill.remove_all_fill()` instead.""" + """Deprecated. Please use :func:`~shiny.ui.fill.remove_all_fill()` instead.""" warn_deprecated( "`shiny.experimental.ui.remove_all_fill()` is deprecated. " "This method will be removed in a future version, " @@ -1038,7 +1038,7 @@ def is_fill_item(tag: TagChild) -> bool: # ###################### TagCallable = TagFunction -"""Deprecated. Please use `htmltools.TagFunction""" +"""Deprecated. Please use `htmltools.TagFunction` instead.""" class CardItem(MainCardItem): @@ -1061,7 +1061,7 @@ def card_header( container: TagFunction = tags.div, **kwargs: TagAttrValue, ) -> MainCardItem: - """Deprecated. Please use `shiny.ui.card_header()` instead.""" + """Deprecated. Please use :func:`~shiny.ui.card_header()` instead.""" warn_deprecated( "`shiny.experimental.ui.card_header()` is deprecated. " "This method will be removed in a future version, " @@ -1074,7 +1074,7 @@ def card_footer( *args: TagChild | TagAttrs, **kwargs: TagAttrValue, ) -> MainCardItem: - """Deprecated. Please use `shiny.ui.card_footer()` instead.""" + """Deprecated. Please use :func:`~shiny.ui.card_footer()` instead.""" warn_deprecated( "`shiny.experimental.ui.card_footer()` is deprecated. " "This method will be removed in a future version, " @@ -1103,7 +1103,7 @@ def value_box( class_: Optional[str] = None, **kwargs: TagAttrValue, ) -> Tag: - """Deprecated. Please use `shiny.ui.value_box()` instead.""" + """Deprecated. Please use :func:`~shiny.ui.value_box()` instead.""" warn_deprecated( "`shiny.experimental.ui.value_box()` is deprecated. " "This method will be removed in a future version, " @@ -1135,7 +1135,7 @@ def showcase_left_center( max_height: CssUnit = "100px", max_height_full_screen: CssUnit = "67%", ) -> MainShowcaseLayout: - """Deprecated. Please use `shiny.ui.showcase_left_center()` instead.""" + """Deprecated. Please use :func:`~shiny.ui.showcase_left_center()` instead.""" warn_deprecated( "`shiny.experimental.ui.showcase_left_center()` is deprecated. " "This method will be removed in a future version, " @@ -1153,7 +1153,7 @@ def showcase_top_right( max_height: CssUnit = "75px", max_height_full_screen: CssUnit = "67%", ) -> MainShowcaseLayout: - """Deprecated. Please use `shiny.ui.showcase_top_right()` instead.""" + """Deprecated. Please use :func:`~shiny.ui.showcase_top_right()` instead.""" warn_deprecated( "`shiny.experimental.ui.showcase_top_right()` is deprecated. " "This method will be removed in a future version, " @@ -1182,7 +1182,7 @@ def layout_column_wrap( class_: Optional[str] = None, **kwargs: TagAttrValue, ) -> Tag: - """Deprecated. Please use `shiny.ui.layout_column_wrap()` instead.""" + """Deprecated. Please use :func:`~shiny.ui.layout_column_wrap()` instead.""" warn_deprecated( "`shiny.experimental.ui.layout_column_wrap()` is deprecated. " "This method will be removed in a future version, " @@ -1228,7 +1228,7 @@ def navset_bar( collapsible: bool = True, fluid: bool = True, ) -> MainNavSetBar: - """Deprecated. Please use `shiny.ui.navset_bar()` instead.""" + """Deprecated. Please use :func:`~shiny.ui.navset_bar()` instead.""" warn_deprecated( "`shiny.experimental.ui.navset_bar()` is deprecated. " "This method will be removed in a future version, " @@ -1261,7 +1261,7 @@ def navset_card_tab( header: TagChild = None, footer: TagChild = None, ) -> MainNavSetCard: - """Deprecated. Please use `shiny.ui.navset_card_tab()` instead.""" + """Deprecated. Please use :func:`~shiny.ui.navset_card_tab()` instead.""" warn_deprecated( "`shiny.experimental.ui.navset_card_tab()` is deprecated. " "This method will be removed in a future version, " @@ -1286,7 +1286,7 @@ def navset_card_pill( footer: TagChild = None, placement: Literal["above", "below"] = "above", ) -> MainNavSetCard: - """Deprecated. Please use `shiny.ui.navset_card_pill()` instead.""" + """Deprecated. Please use :func:`~shiny.ui.navset_card_pill()` instead.""" warn_deprecated( "`shiny.experimental.ui.navset_card_pill()` is deprecated. " "This method will be removed in a future version, " @@ -1318,7 +1318,7 @@ def output_plot( brush: bool | MainBrushOpts = False, fill: bool | MISSING_TYPE = MISSING, ) -> Tag: - """Deprecated. Please use `shiny.ui.output_plot()` instead.""" + """Deprecated. Please use :func:`~shiny.ui.output_plot()` instead.""" warn_deprecated( "`shiny.experimental.ui.output_plot()` is deprecated. " "This method will be removed in a future version, " @@ -1352,7 +1352,7 @@ def output_image( fill: bool = False, # /NEW ) -> Tag: - """Deprecated. Please use `shiny.ui.output_image()` instead.""" + """Deprecated. Please use :func:`~shiny.ui.output_image()` instead.""" warn_deprecated( "`shiny.experimental.ui.output_image()` is deprecated. " "This method will be removed in a future version, " @@ -1380,7 +1380,7 @@ def output_ui( fillable: bool = False, **kwargs: TagAttrValue, ) -> Tag: - """Deprecated. Please use `shiny.ui.output_ui()` instead.""" + """Deprecated. Please use :func:`~shiny.ui.output_ui()` instead.""" warn_deprecated( "`shiny.experimental.ui.output_ui()` is deprecated. " "This method will be removed in a future version, " @@ -1409,7 +1409,7 @@ def page_sidebar( lang: Optional[str] = None, **kwargs: TagAttrValue, ) -> Tag: - """Deprecated. Please use `shiny.ui.page_sidebar()` instead.""" + """Deprecated. Please use :func:`~shiny.ui.page_sidebar()` instead.""" warn_deprecated( "`shiny.experimental.ui.page_sidebar()` is deprecated. " "This method will be removed in a future version, " @@ -1451,7 +1451,7 @@ def page_navbar( window_title: str | MISSING_TYPE = MISSING, lang: Optional[str] = None, ) -> Tag: - """Deprecated. Please use `shiny.ui.page_navbar()` instead.""" + """Deprecated. Please use :func:`~shiny.ui.page_navbar()` instead.""" warn_deprecated( "`shiny.experimental.ui.page_navbar()` is deprecated. " "This method will be removed in a future version, " @@ -1488,7 +1488,7 @@ def page_fillable( lang: Optional[str] = None, **kwargs: TagAttrValue, ) -> Tag: - """Deprecated. Please use `shiny.ui.page_fillable()` instead.""" + """Deprecated. Please use :func:`~shiny.ui.page_fillable()` instead.""" warn_deprecated( "`shiny.experimental.ui.page_fillable()` is deprecated. " "This method will be removed in a future version, " diff --git a/shiny/ui/_sidebar.py b/shiny/ui/_sidebar.py index f5a7bd1b2..02999fcbc 100644 --- a/shiny/ui/_sidebar.py +++ b/shiny/ui/_sidebar.py @@ -574,8 +574,7 @@ def panel_sidebar( width: int = 4, **kwargs: TagAttrValue, ) -> DeprecatedPanelSidebar: - """Deprecated. Please use :func:`shiny.ui.sidebar` instead of - `ui.panel_sidebar()`.""" + """Deprecated. Please use :func:`~shiny.ui.sidebar` instead.""" # TODO-future: >= 2024-01-01; Add deprecation message below # Plan of action: # * No deprecation messages today (2023-10-11), and existing code _just works_. @@ -597,7 +596,7 @@ def panel_main( width: int = 8, **kwargs: TagAttrValue, ) -> DeprecatedPanelMain: - """Deprecated. Please supply `panel_main(*args)` directly to `layout_sidebar()`.""" + """Deprecated. Please supply the `*args` of :func:`~shiny.ui.panel_main` directly to :func:`~shiny.ui.layout_sidebar`.""" # TODO-future: >= 2023-11-01; Add deprecation message below # warn_deprecated("Please use `layout_sidebar(*args)` instead of `panel_main()`. `panel_main()` will go away in a future version of Shiny.") From 9306633c7c9349f7c84a4faf46f08c21ba3ae255 Mon Sep 17 00:00:00 2001 From: Garrett Grolemund Date: Thu, 7 Dec 2023 15:01:29 -0600 Subject: [PATCH 03/13] Reformats _card.py with black --- shiny/experimental/ui/_card.py | 96 +++++++++++++++++----------------- 1 file changed, 49 insertions(+), 47 deletions(-) diff --git a/shiny/experimental/ui/_card.py b/shiny/experimental/ui/_card.py index 12f795af7..8f4765a62 100644 --- a/shiny/experimental/ui/_card.py +++ b/shiny/experimental/ui/_card.py @@ -7,14 +7,14 @@ from typing import Literal, Optional, Protocol from htmltools import ( - Tag, - TagAttrs, - TagAttrValue, - TagChild, - TagFunction, - Tagifiable, - css, - tags, + Tag, + TagAttrs, + TagAttrValue, + TagChild, + TagFunction, + Tagifiable, + css, + tags, ) from ...types import MISSING, MISSING_TYPE @@ -23,27 +23,27 @@ from ...ui.fill import as_fill_item, as_fillable_container __all__ = ( - # Worried about `wrapper` - "card", - # Do not want to expose card_body yet - "card_body", - # Questioning: - "card_title", - "card_image", + # Worried about `wrapper` + "card", + # Do not want to expose card_body yet + "card_body", + # Questioning: + "card_title", + "card_image", ) # TODO-maindocs; @add_example() def card( - *args: TagChild | TagAttrs | CardItem, - full_screen: bool = False, - height: Optional[CssUnit] = None, - max_height: Optional[CssUnit] = None, - min_height: Optional[CssUnit] = None, - fill: bool = True, - class_: Optional[str] = None, - wrapper: WrapperCallable | None | MISSING_TYPE = MISSING, - **kwargs: TagAttrValue, + *args: TagChild | TagAttrs | CardItem, + full_screen: bool = False, + height: Optional[CssUnit] = None, + max_height: Optional[CssUnit] = None, + min_height: Optional[CssUnit] = None, + fill: bool = True, + class_: Optional[str] = None, + wrapper: WrapperCallable | None | MISSING_TYPE = MISSING, + **kwargs: TagAttrValue, ) -> Tag: """ A Bootstrap card component @@ -87,7 +87,7 @@ def card( See Also -------- - * :func:`~shiny.ui.layout_column_wrap` for laying out multiple cards + * :func:`~shiny.ui.layout_column_wrap` for laying out multiple cards or multiple columns inside a card. * :func:`~shiny.ui.card_header` for creating a header within a card. * :func:`~shiny.experimental.ui.card_title` for creating a title within a card body. @@ -95,16 +95,18 @@ def card( * :func:`~shiny.ui.card_footer` for creating a footer within a card. * :func:`~shiny.experimental.ui.card_image` for adding an image to a card. """ + + return _card_impl( - *args, - full_screen=full_screen, - height=height, - max_height=max_height, - min_height=min_height, - fill=fill, - class_=class_, - wrapper=wrapper, - **kwargs, + *args, + full_screen=full_screen, + height=height, + max_height=max_height, + min_height=min_height, + fill=fill, + class_=class_, + wrapper=wrapper, + **kwargs, ) @@ -113,14 +115,14 @@ def card( # TODO-maindocs; @add_example() def card_title( - *args: TagChild | TagAttrs, - container: TagFunction = tags.h5, - **kwargs: TagAttrValue, + *args: TagChild | TagAttrs, + container: TagFunction = tags.h5, + **kwargs: TagAttrValue, ) -> Tagifiable: """ A card title container - :func:`~shiny.experimental.ui.card_title` creates a general container for the "title" of + :func:`~shiny.experimental.ui.card_title` creates a general container for the "title" of a :func:`~shiny.ui.card`. This component is designed to be provided as a direct child to :func:`~shiny.ui.card`. @@ -130,7 +132,7 @@ def card_title( Contents to appear in the card's title, or tag attributes to pass to the resolved :class:`~htmltools.Tag` object. container - Method for the returned :class:`~htmltools.Tag` object. Defaults to + Method for the returned :class:`~htmltools.Tag` object. Defaults to :func:`~shiny.ui.tags`.h5. **kwargs Additional HTML attributes for the returned :class:`~htmltools.Tag` object. @@ -192,7 +194,7 @@ def card_image( """ A card image container - :func:`~shiny.experimental.ui.card_image` creates a general container for an image within a + :func:`~shiny.experimental.ui.card_image` creates a general container for an image within a :func:`~shiny.ui.card`. This component is designed to be provided as a direct child to :func:`~shiny.ui.card`. @@ -224,7 +226,7 @@ def card_image( width Any valid CSS unit (e.g., `width="100%"`). container - Method to wrap the returned :class:`~htmltools.Tag` object. Defaults to + Method to wrap the returned :class:`~htmltools.Tag` object. Defaults to :func:`~shiny.experimental.ui.card_body`. If :func:`~shiny.experimental.ui.card_body` is used, each image will be in separate cards. If the `container` method does not return a :class:`~shiny.ui.CardItem`, it @@ -242,20 +244,20 @@ def card_image( "`mime_type` must be provided when passing an in-memory buffer" ) src = f"data:{mime_type};base64,{b64_str}" - + elif isinstance(file, (str, Path, PurePath)): with open(file, "rb") as img_file: b64_str = base64.b64encode(img_file.read()).decode("utf-8") if mime_type is None: mime_type = mimetypes.guess_type(file)[0] src = f"data:{mime_type};base64,{b64_str}" - + card_class_map = { "all": "card-img", "top": "card-img-top", "bottom": "card-img-bottom", } - + image = tags.img( { "src": src, @@ -270,10 +272,10 @@ def card_image( class_=class_, **kwargs, ) - + if fill: image = as_fill_item(image) - + if href is not None: image = as_fillable_container( as_fill_item( @@ -283,7 +285,7 @@ def card_image( ) ) ) - + if container: return container(image) else: From 293fab7f223010783b6707059c54b45fb2e1e673 Mon Sep 17 00:00:00 2001 From: Garrett Grolemund Date: Thu, 7 Dec 2023 15:06:16 -0600 Subject: [PATCH 04/13] Tweaking style of _card.py --- shiny/experimental/ui/_card.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/shiny/experimental/ui/_card.py b/shiny/experimental/ui/_card.py index 8f4765a62..8f2b36a95 100644 --- a/shiny/experimental/ui/_card.py +++ b/shiny/experimental/ui/_card.py @@ -97,17 +97,17 @@ def card( """ -return _card_impl( - *args, - full_screen=full_screen, - height=height, - max_height=max_height, - min_height=min_height, - fill=fill, - class_=class_, - wrapper=wrapper, - **kwargs, -) + return _card_impl( + *args, + full_screen=full_screen, + height=height, + max_height=max_height, + min_height=min_height, + fill=fill, + class_=class_, + wrapper=wrapper, + **kwargs, + ) ############################################################################ From 7cfdaee9848c47ce6a1e4af8e6279e6e7acaa560 Mon Sep 17 00:00:00 2001 From: Garrett Grolemund Date: Thu, 7 Dec 2023 15:10:35 -0600 Subject: [PATCH 05/13] Removes excess blank line --- shiny/experimental/ui/_card.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/shiny/experimental/ui/_card.py b/shiny/experimental/ui/_card.py index 8f2b36a95..34d518a72 100644 --- a/shiny/experimental/ui/_card.py +++ b/shiny/experimental/ui/_card.py @@ -95,8 +95,6 @@ def card( * :func:`~shiny.ui.card_footer` for creating a footer within a card. * :func:`~shiny.experimental.ui.card_image` for adding an image to a card. """ - - return _card_impl( *args, full_screen=full_screen, From b920d9360cea08c2baee9cfa41e0ec312b3218a0 Mon Sep 17 00:00:00 2001 From: Garrett Grolemund Date: Thu, 7 Dec 2023 16:07:02 -0600 Subject: [PATCH 06/13] Proofreads types section --- shiny/types.py | 6 +++--- shiny/ui/_accordion.py | 4 ++-- shiny/ui/_card.py | 10 +++++----- shiny/ui/_sidebar.py | 6 +++--- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/shiny/types.py b/shiny/types.py index 5d62c47b1..fbdedbf89 100644 --- a/shiny/types.py +++ b/shiny/types.py @@ -37,7 +37,7 @@ class MISSING_TYPE: # FileUploadOperation class. class FileInfo(TypedDict): """ - Information about a file upload. + Class for information about a file upload. See Also -------- @@ -49,7 +49,7 @@ class FileInfo(TypedDict): """ name: str - """The name of the file.""" + """The name of the file being uploaded.""" size: int """The size of the file in bytes.""" type: str @@ -144,7 +144,7 @@ class ActionButtonValue(int): class NavSetArg(Protocol): """ - An value suitable for passing to a navigation container (e.g., + A value suitable for passing to a navigation container (e.g., :func:`~shiny.ui.navset_tab`). """ diff --git a/shiny/ui/_accordion.py b/shiny/ui/_accordion.py index 1631d05fc..f8458740c 100644 --- a/shiny/ui/_accordion.py +++ b/shiny/ui/_accordion.py @@ -26,7 +26,7 @@ class AccordionPanel: """ - Internal class used to represent an accordion panel. + The internal class used to represent an accordion panel. This class is used to represent an accordion panel. It is not intended to be instantiated directly. Instead, use :func:`~shiny.ui.accordion_panel`. @@ -34,7 +34,7 @@ class AccordionPanel: Parameters ---------- *args - Contents to the accordion panel body. Or tag attributes that are supplied to the + Contents to appear in the accordion panel body, or tag attributes that are supplied to the returned :class:`~htmltools.Tag` object. data_value A character string that uniquely identifies this panel. diff --git a/shiny/ui/_card.py b/shiny/ui/_card.py index aeaba298a..daa3785cd 100644 --- a/shiny/ui/_card.py +++ b/shiny/ui/_card.py @@ -367,7 +367,7 @@ def card_body( class CardItem: """ - A wrapper around a :class:`~htmltools.Tag` object that represent the content of a + A wrapper around a :class:`~htmltools.Tag` object that represents the content of a card item (e.g., :func:`~shiny.ui.card_header` or :func:`~shiny.card_footer`). @@ -377,15 +377,15 @@ class CardItem: Parameters ---------- item - A :class:`~htmltools.Tag` object that represent the content of a card item + A :class:`~htmltools.Tag` object that represents the content of a card item (e.g., :func:`~shiny.ui.card_header` or :func:`~shiny.card_footer`). See Also -------- * :func:`~shiny.ui.card` for creating a card component. - * :func:`~shiny.ui.card_header` for creating a header within the card. - * :func:`~shiny.ui.card_footer` for creating a footer within the card. + * :func:`~shiny.ui.card_header` for creating a header within a card. + * :func:`~shiny.ui.card_footer` for creating a footer within a card. """ def __init__( @@ -396,7 +396,7 @@ def __init__( def resolve(self) -> TagChild: """ - Resolves the `CardItem` class by returning the `item` provided at initialization. + Resolves an object with the `CardItem` class by returning the `item` provided at initialization. Returns ------- diff --git a/shiny/ui/_sidebar.py b/shiny/ui/_sidebar.py index 02999fcbc..7eb4a8841 100644 --- a/shiny/ui/_sidebar.py +++ b/shiny/ui/_sidebar.py @@ -40,7 +40,7 @@ class Sidebar: """ - Sidebar object + A sidebar object Class returned from :func:`~shiny.ui.sidebar`. Please do not use this class directly. Instead, supply the :func:`~shiny.ui.sidebar` object to @@ -55,7 +55,7 @@ class directly. Instead, supply the :func:`~shiny.ui.sidebar` object to position Where the sidebar should appear relative to the main content. open - The initial state of the sidebar. + The initial state of the sidebar (open or collapsed). width A valid CSS unit used for the width of the sidebar. max_height_mobile @@ -77,7 +77,7 @@ class directly. Instead, supply the :func:`~shiny.ui.sidebar` object to position Where the sidebar should appear relative to the main content. open - The initial state of the sidebar. + The initial state of the sidebar (open or collapsed). width A valid CSS unit used for the width of the sidebar. max_height_mobile From da55d3d57bc6f72340c00cc80999f42c5af0659c Mon Sep 17 00:00:00 2001 From: Garrett Grolemund Date: Thu, 7 Dec 2023 16:34:29 -0600 Subject: [PATCH 07/13] Proofreads developer facing tools --- shiny/input_handler.py | 2 +- shiny/session/_utils.py | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/shiny/input_handler.py b/shiny/input_handler.py index 49885319a..abd48cdb2 100644 --- a/shiny/input_handler.py +++ b/shiny/input_handler.py @@ -68,7 +68,7 @@ def _process_value(self, type: str, value: Any, name: str, session: Session) -> ``add()`` ing an input handler will make it persist for the duration of the Python process (unless Shiny is explicitly reloaded). For that reason, verbose naming is encouraged to minimize the risk of colliding with other Shiny input binding(s) which -happen to use the same ``type`` (if this the binding is bundled with a package, we +happen to use the same ``type`` (if the binding is bundled with a package, we recommend the format of "packageName.widgetName"). Example diff --git a/shiny/session/_utils.py b/shiny/session/_utils.py index fce434fb1..dd1c255cd 100644 --- a/shiny/session/_utils.py +++ b/shiny/session/_utils.py @@ -44,8 +44,8 @@ def get_current_session() -> Optional[Session]: Note ---- - Shiny apps should not need to call this function directly. Instead, it's intended to - be used by Shiny developing who wish to create new functions that should only be + Shiny apps should not need to call this function directly. Instead, it is intended to + be used by Shiny developers who wish to create new functions that should only be called from within an active Shiny session. See Also @@ -58,12 +58,12 @@ def get_current_session() -> Optional[Session]: @contextmanager def session_context(session: Optional[Session]): """ - Context manager for current session. + A context manager for current session. Parameters ---------- session - A :class:`~shiny.Session` instance. If not provided, it is inferred via + A :class:`~shiny.Session` instance. If not provided, the instance is inferred via :func:`~shiny.session.get_current_session`. """ token: Token[Session | None] = _current_session.set(session) @@ -81,7 +81,7 @@ def require_active_session(session: Optional[Session]) -> Session: Parameters ---------- session - A :class:`~shiny.Session` instance. If not provided, it is inferred via + A :class:`~shiny.Session` instance. If not provided, the session is inferred via :func:`~shiny.session.get_current_session`. Returns @@ -91,8 +91,8 @@ def require_active_session(session: Optional[Session]) -> Session: Note ---- - Shiny apps should not need to call this function directly. Instead, it's intended to - be used by Shiny developing who wish to create new functions that should only be + Shiny apps should not need to call this function directly. Instead, it is intended to + be used by Shiny developers who wish to create new functions that should only be called from within an active Shiny session. Raises From 89a301560914567ec178d2bab050cd4aaba77751 Mon Sep 17 00:00:00 2001 From: Garrett Grolemund Date: Thu, 7 Dec 2023 17:36:22 -0600 Subject: [PATCH 08/13] Proofreads the Display Messages section --- shiny/ui/_bootstrap.py | 3 +++ shiny/ui/_modal.py | 31 +++++++++++++++++++++---------- shiny/ui/_notification.py | 27 ++++++++++++++++++--------- shiny/ui/_progress.py | 14 ++++++++++---- 4 files changed, 52 insertions(+), 23 deletions(-) diff --git a/shiny/ui/_bootstrap.py b/shiny/ui/_bootstrap.py index be0d23084..5687d8f8f 100644 --- a/shiny/ui/_bootstrap.py +++ b/shiny/ui/_bootstrap.py @@ -385,6 +385,9 @@ def help_text(*args: TagChild | TagAttrs, **kwargs: TagAttrValue) -> Tag: """ Create a help text element + Help text is stylized text which can be added to the user interface to provide additional explanation + or context. Text passed to :func:`~shiny.ui.help_text` receives the Bootstrap `help-block` class. + Parameters ---------- args diff --git a/shiny/ui/_modal.py b/shiny/ui/_modal.py index a1203255c..7c7b03ad5 100644 --- a/shiny/ui/_modal.py +++ b/shiny/ui/_modal.py @@ -18,8 +18,9 @@ def modal_button(label: TagChild, icon: TagChild = None, **kwargs: TagAttrValue) -> Tag: """ - Creates a button that will dismiss a :func:`modal` (useful when customising the - ``footer`` of :func:`modal`). + Creates a button that will dismiss a :func:`modal`. :func:`~shiny.ui.modal_button` is usually + passed to the `footer` of a :func:`~shiny.ui.modal` to add a button to the footer that will close + the :func:`~shiny.ui.modal`. Parameters ---------- @@ -67,7 +68,9 @@ def modal( **kwargs: TagAttrValue, ) -> Tag: """ - Creates the UI for a modal dialog, using Bootstrap's modal class. Modals are + Creates the UI for a modal dialog, using Bootstrap's modal class. + + A modal is a dialog box that appears in front of the app. Modals are typically used for showing important messages, or for presenting UI that requires input from the user, such as a user name and/or password input. @@ -80,10 +83,11 @@ def modal( footer UI for footer. Use ``None`` for no footer. size - One of "s" for small, "m" (the default) for medium, or "l" for large. + The size of the modal dialogue box. Use one of "s" for small, "m" (the default) + for medium, or "l" for large. easy_close If ``True``, the modal dialog can be dismissed by clicking outside the dialog - box, or be pressing the Escape key. If ``False`` (the default), the modal dialog + box, or by pressing the Escape key. If ``False`` (the default), the modal dialog can't be dismissed in those ways; instead it must be dismissed by clicking on a ``modal_button()``, or from a call to ``modal_remove()`` on the server. fade @@ -156,13 +160,16 @@ def modal_show(modal: Tag, session: Optional[Session] = None) -> None: """ Show a modal dialog. + :func:`~shiny.ui.modal_show` is used to display a modal that has been + created with :func:`~shiny.ui.modal`. + Parameters ---------- modal Typically a :func:`modal` instance. session - A :class:`~shiny.Session` instance. If not provided, it is inferred via - :func:`~shiny.session.get_current_session`. + The :class:`~shiny.Session` instance to display the modal in. If not provided, + the session is inferred via :func:`~shiny.session.get_current_session`. See Also ------- @@ -180,13 +187,17 @@ def modal_show(modal: Tag, session: Optional[Session] = None) -> None: def modal_remove(session: Optional[Session] = None) -> None: """ - Remove a modal dialog. + Remove a modal dialog box. + + :func:`~shiny.ui.modal_remove` provides a way to remove a modal programatically. + Modals can also be removed manually by the user if a :func:`~shiny.ui.modal_button` + is provided, or if the modal is created with `easy_close=True`. Parameters ---------- session - A :class:`~shiny.Session` instance. If not provided, it is inferred via - :func:`~shiny.session.get_current_session`. + The :class:`~shiny.Session` instance that contains the modal to remove. If not + provided, the session is inferred via :func:`~shiny.session.get_current_session`. See Also ------- diff --git a/shiny/ui/_notification.py b/shiny/ui/_notification.py index 40d4c83f7..15f9d6f50 100644 --- a/shiny/ui/_notification.py +++ b/shiny/ui/_notification.py @@ -25,17 +25,22 @@ def notification_show( """ Show a notification to the user. + A notification is a message that appears near the bottom corner of the app. + Notifications normally disappear after a short period of time, and should multiple + notifications appear together, they will stack on top of one another. + Parameters ---------- ui - Content of message. + Contents of the notification message. action Message content that represents an action. For example, this could be a link that the user can click on. This is separate from ui so customized layouts can - handle the main notification content separately from action content. + handle the main notification content separately from the action content. duration Number of seconds to display the message before it disappears. Use ``None`` to - make the message not automatically disappear. + prevent the message from disappearing automatically. The user will need to click + the corner of the notification to close it. close_button If ``True``, display a button which will make the notification disappear when clicked. If ``False`` do not display. @@ -44,11 +49,11 @@ def notification_show( notification with the same ``id`` will be replaced with this one (otherwise, a new notification is created). type - A string which controls the color of the notification. One of "default" (gray), - "message" (blue), "warning" (yellow), or "error" (red). + A string which controls the color of the notification. This should be one of + "default" (gray), "message" (blue), "warning" (yellow), or "error" (red). session - A :class:`~shiny.Session` instance. If not provided, it is inferred via - :func:`~shiny.session.get_current_session`. + The :class:`~shiny.Session` in which the notification should appear. If not + provided, the session is inferred via :func:`~shiny.session.get_current_session`. Returns ------- @@ -89,12 +94,16 @@ def notification_remove(id: str, *, session: Optional[Session] = None) -> str: """ Remove a notification. + :func:`~shiny.ui.notification_remove` provides a way to remove a notification programatically. + Notifications can also be removed manually by the user, or automatically after a + specififed amont of time passes. + Parameters ---------- id - A notification ``id``. + The ``id`` of the notification to remove. session - A :class:`~shiny.Session` instance. If not provided, it is inferred via + The :class:`~shiny.Session` in which the notification appears. If not provided, the session is inferred via :func:`~shiny.session.get_current_session`. Returns diff --git a/shiny/ui/_progress.py b/shiny/ui/_progress.py index 253916675..735ae032c 100644 --- a/shiny/ui/_progress.py +++ b/shiny/ui/_progress.py @@ -16,6 +16,11 @@ class Progress: """ Initialize a progress bar. + :func:`~shiny.ui.Progress` creates a computation manager that can be used with `with` to + run a block of code. Shiny will display a progress bar while the code runs, which + you can update by calling the `set()` and `message()` methods of the computation + manager at strategic points in the code block. + Parameters ---------- min @@ -25,8 +30,8 @@ class Progress: The value that represents the end of the progress bar. Must be greater than ``min``. session - A :class:`~shiny.Session` instance. If not provided, it is inferred via - :func:`~shiny.session.get_current_session`. + The :class:`~shiny.Session` instance that the progress bar should appear in. If not + provided, the session is inferred via :func:`~shiny.session.get_current_session`. """ _style = "notification" @@ -66,8 +71,9 @@ def set( detail: Optional[str] = None, ) -> None: """ - Updates the progress panel. When called the first time, the progress panel is - displayed. + Opens and updates the progress panel. + + When called the first time, the progress panel is displayed. Parameters ---------- From 993c5a2c19aa010815b841b9e431551328fd99f9 Mon Sep 17 00:00:00 2001 From: Garrett Grolemund Date: Thu, 7 Dec 2023 17:40:01 -0600 Subject: [PATCH 09/13] Reformatting _modal.py --- shiny/ui/_modal.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/shiny/ui/_modal.py b/shiny/ui/_modal.py index 7c7b03ad5..85e371ddf 100644 --- a/shiny/ui/_modal.py +++ b/shiny/ui/_modal.py @@ -189,8 +189,8 @@ def modal_remove(session: Optional[Session] = None) -> None: """ Remove a modal dialog box. - :func:`~shiny.ui.modal_remove` provides a way to remove a modal programatically. - Modals can also be removed manually by the user if a :func:`~shiny.ui.modal_button` + :func:`~shiny.ui.modal_remove` provides a way to remove a modal programatically. + Modals can also be removed manually by the user if a :func:`~shiny.ui.modal_button` is provided, or if the modal is created with `easy_close=True`. Parameters From 53cb3c3fabbaa4fe457bd18e43b5f79bc753d018 Mon Sep 17 00:00:00 2001 From: Garrett Grolemund Date: Fri, 8 Dec 2023 10:56:14 -0600 Subject: [PATCH 10/13] Proofreads Create and Run Apps section --- shiny/_app.py | 4 ++-- shiny/_main.py | 14 +++++++------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/shiny/_app.py b/shiny/_app.py index f8b01d139..748bef4c8 100644 --- a/shiny/_app.py +++ b/shiny/_app.py @@ -46,12 +46,12 @@ class App: ---------- ui The UI definition for the app (e.g., a call to :func:`~shiny.ui.page_fluid` or - :func:`~shiny.ui.page_fixed`, with layouts and controls nested inside). You can + similar, with layouts and controls nested inside). You can also pass a function that takes a :class:`~starlette.requests.Request` and returns a UI definition, if you need the UI definition to be created dynamically for each pageview. server - A function which is called once for each session, ensuring that each app is + A function which is called once for each session, ensuring that each session is independent. static_assets Static files to be served by the app. If this is a string or Path object, it diff --git a/shiny/_main.py b/shiny/_main.py index 57fc2d2dc..95315891e 100644 --- a/shiny/_main.py +++ b/shiny/_main.py @@ -197,7 +197,7 @@ def run_app( **kwargs: object, ) -> None: """ - Starts a Shiny app. Press ``Ctrl+C`` (or ``Ctrl+Break`` on Windows) to stop. + Starts a Shiny app. Press ``Ctrl+C`` (or ``Ctrl+Break`` on Windows) to stop the app. Parameters ---------- @@ -207,8 +207,8 @@ def run_app( directory. In other cases, the app location can be specified as a ``:`` string where the ``:`` is only necessary if the application is named something other than ``app``. Note that ```` - can be relative path to a ``.py`` file or a directory (with an ``app.py`` file - inside it); and in this case, the relative path is resolved relative to the + can be a relative path to a ``.py`` file or a directory (with an ``app.py`` file + inside of it); and in this case, the relative path is resolved relative to the ``app_dir`` directory. host The address that the app should listen on. @@ -220,8 +220,8 @@ def run_app( reload Enable auto-reload. reload_dirs - List of directories (in addition to the app directory) to watch for changes that - will trigger app reloading. + A list of directories (in addition to the app directory) to watch for changes that + will trigger an app reload. reload_includes List or tuple of file globs to indicate which files should be monitored for changes. Can be combined with `reload_excludes`. @@ -233,7 +233,7 @@ def run_app( log_level Log level. app_dir - Look for ``app`` under this directory (by adding this to the ``PYTHONPATH``). + The directory to look for ``app`` under (by adding this to the ``PYTHONPATH``). factory Treat ``app`` as an application factory, i.e. a () -> callable. launch_browser @@ -245,7 +245,7 @@ def run_app( Tip --- The ``shiny run`` command-line interface (which comes installed with Shiny) provides - the same functionality as this function. + the same functionality as :func:`~shiny.run_app`. Examples -------- From 65ce8df10c5d723ba7470cc5d6b8dc3e04a8895d Mon Sep 17 00:00:00 2001 From: Garrett Grolemund Date: Fri, 8 Dec 2023 16:39:43 -0600 Subject: [PATCH 11/13] Proofreads reactives section --- shiny/_validation.py | 7 ++++ shiny/reactive/_core.py | 25 +++++++------- shiny/reactive/_poll.py | 48 +++++++++++++------------- shiny/reactive/_reactives.py | 65 ++++++++++++++++++++---------------- 4 files changed, 82 insertions(+), 63 deletions(-) diff --git a/shiny/_validation.py b/shiny/_validation.py index 91d23f754..b6c83a15a 100644 --- a/shiny/_validation.py +++ b/shiny/_validation.py @@ -25,6 +25,13 @@ def req(*args: T, cancel_output: bool = False) -> T | None: This is a convenient shorthand for throwing :func:`~shiny.types.SilentException` / :func:`~shiny.types.SilentCancelOutputException` if any of the arguments are falsy. + + The term "falsy" generally indicates that a value is considered False when + encountered in a logical context. We use the term a little loosely here; our usage + tries to match the intuitive notions of "Is this value missing or available?", or + "Has the user provided an answer?", or in the case of action buttons, "Has the + button been clicked?". So `False`, `None`, `0`, and `""` would be examples of Falsy + values. Parameters ---------- diff --git a/shiny/reactive/_core.py b/shiny/reactive/_core.py index b3ffc94f2..2c8ad0d70 100644 --- a/shiny/reactive/_core.py +++ b/shiny/reactive/_core.py @@ -208,12 +208,12 @@ def isolate(): Ordinarily, the simple act of reading a reactive value causes a relationship to be established between the caller and the reactive value, where a change to the reactive value will cause the caller to re-execute. (The same applies for the act of - getting a reactive expression's value.) `with isolate()` lets you read a reactive - value or expression without establishing this relationship. + getting a reactive calculation's value.) `with isolate()` lets you read a reactive + value or calculation without establishing this relationship. - ``with isolate()`` can also be useful for calling reactive expression at the + ``with isolate()`` can also be useful for calling reactive calculations at the console, which can be useful for debugging. To do so, wrap the calls to the reactive - expression with ``with isolate()``. + calculation with ``with isolate()``. Returns ------- @@ -253,7 +253,7 @@ async def flush() -> None: Warning ------- - This function shouldn't ever need to be called inside a Shiny app. It's only + You shouldn't ever need to call this function inside of a Shiny app. It's only useful for testing and running reactive code interactively in the console. """ await _reactive_environment.flush() @@ -263,14 +263,15 @@ def on_flushed( func: Callable[[], Awaitable[None]], once: bool = False ) -> Callable[[], None]: """ - Register a function to be called when the reactive environment is flushed + Register a function to be called when the reactive environment is flushed. Parameters ---------- func The function to be called when the reactive environment is flushed once - If True, the function will only be called once, and then removed from the + Should the function be run once, and then cleared, or should it + re-run each time the event occurs. Returns ------- @@ -289,8 +290,8 @@ def lock() -> asyncio.Lock: """ A lock that should be held whenever manipulating the reactive graph. - For example, this makes it safe to set a :class:`~reactive.Value` and call - :func:`~reactive.flush()` from a different :class:`~asyncio.Task` than the one that + For example, :func:`~shiny.reactive.lock` makes it safe to set a :class:`~reactive.Value` and call + :func:`~shiny.reactive.flush` from a different :class:`~asyncio.Task` than the one that is running the Shiny :class:`~shiny.Session`. """ return _reactive_environment.lock @@ -303,8 +304,8 @@ def invalidate_later( """ Scheduled Invalidation - Schedules the current reactive context to be invalidated in the given number of - seconds. + When called from within a reactive context, :func:`~shiny.reactive.invalidate_later` + schedules the reactive context to be invalidated in the given number of seconds. Parameters ---------- @@ -313,7 +314,7 @@ def invalidate_later( Note ---- - When called within a reactive function (i.e., :func:`Effect`, :func:`Calc`, + When called within a reactive function (i.e., :func:`~reactive.effect`, :func:`~reactive.calc`, :func:`render.ui`, etc.), that reactive context is invalidated (and re-executes) after the interval has passed. The re-execution will reset the invalidation flag, so in a typical use case, the object will keep re-executing and waiting for the diff --git a/shiny/reactive/_poll.py b/shiny/reactive/_poll.py index 479757ae5..6fb70f088 100644 --- a/shiny/reactive/_poll.py +++ b/shiny/reactive/_poll.py @@ -29,9 +29,11 @@ def poll( """ Create a reactive polling object. - Polling is a technique that approximates "real-time" or streaming updates, using a - data source that does not actually have push notifications but does have a quick way - to repeatedly check for changes on demand. + Polling is a technique that approximates "real-time" or streaming updates, as if a + data source were pushing notifications each time it is updated. The data source does + not actually push notifications; a polling object repeatedly checks for changes in an + efficient way at specified intervals. If a change is detected, the polling object runs + a function to re-read the data source. A reactive polling object is constructed using two functions: a polling function, which is a fast-running, inexpensive function that is used to determine whether some @@ -48,7 +50,7 @@ def poll( object at the top level of app.py (outside of the server function). Both `poll_func` and the decorated (data reading) function can read reactive values - and ~shiny.reactive.Calc objects. Any invalidations triggered by reactive + and :class:`~shiny.reactive.calc` objects. Any invalidations triggered by reactive dependencies will apply to the reactive polling object immediately (not waiting for the `interval_secs` delay to expire). @@ -57,7 +59,7 @@ def poll( poll_func A function to be called frequently to determine whether a data source has changed. The return value should be something that can be compared inexpensively - using `==`. Both regular functions and coroutine functions are allowed. + using `==`. Both regular functions and co-routine functions are allowed. Note that the `poll_func` should NOT return a bool that indicates whether the data source has changed. Rather, each `poll_func` return value will be checked @@ -71,12 +73,12 @@ def poll( The function that will be used to compare each `poll_func` return value with its immediate predecessor. priority - Reactive polling is implemented using an ~shiny.reactive.Effect to call + Reactive polling is implemented using an :class:`~shiny.reactive.effect` to call `poll_func` on a timer; use the `priority` argument to control the order of this - Effect's execution versus other Effects in your app. See ~shiny.reactive.Effect - for more details. + Effect's execution versus other Effects in your app. See + :func:`~shiny.reactive.effect` for more details. session - A :class:`~shiny.Session` instance. If not provided, it is inferred via + A :class:`~shiny.Session` instance. If not provided, a session is inferred via :func:`~shiny.session.get_current_session`. If there is no current session (i.e. `poll` is being created outside of the server function), the lifetime of this reactive poll object will not be tied to any specific session. @@ -86,9 +88,9 @@ def poll( : A decorator that should be applied to a no-argument function that (expensively) reads whatever data is desired. (This function may be a regular function or a - coroutine function.) The result of the decorator is a reactive ~shiny.reactive.Calc - that always returns up-to-date data, and invalidates callers when changes are - detected via polling. + co-routine function.) The result of the decorator is a reactive + :class:`~shiny.reactive.calc` that always returns up-to-date data, and invalidates + callers when changes are detected via polling. See Also -------- @@ -224,9 +226,9 @@ def file_reader( Note that `file_reader` works only on single files, not directories of files. Both the `filepath` function and the decorated (file reading) function can read - reactive values and ~shiny.reactive.Calc objects. Any invalidations triggered by - reactive dependencies will apply to the reactive file reader object immediately (not - waiting for the `interval_secs` delay to expire). + reactive values and :class:`~shiny.reactive.calc` objects. Any invalidations + triggered by reactive dependencies will apply to the reactive file reader object + immediately (not waiting for the `interval_secs` delay to expire). Parameters ---------- @@ -239,18 +241,18 @@ def file_reader( error and close the session. If a function is used, make sure it is high performance (or is cached, i.e. use - a ~shiny.reactive.Calc), as it will be called very frequently. + a :class:`~shiny.reactive.calc)`, as it will be called very frequently. interval_secs The number of seconds to wait after each time the file metadata is checked. Note: depending on what other tasks are executing, the actual wait time may far exceed this value. priority - Reactive polling is implemented using an ~shiny.reactive.Effect to call + Reactive polling is implemented using an :class:`~shiny.reactive.effect` to call `poll_func` on a timer; use the `priority` argument to control the order of this - Effect's execution versus other Effects in your app. See ~shiny.reactive.Effect - for more details. + Effect's execution versus other Effects in your app. See + :func:`~shiny.reactive.effect` for more details. session - A :class:`~shiny.Session` instance. If not provided, it is inferred via + A :class:`~shiny.Session` instance. If not provided, a session is inferred via :func:`~shiny.session.get_current_session`. If there is no current session (i.e. `poll` is being created outside of the server function), the lifetime of this reactive poll object will not be tied to any specific session. @@ -260,9 +262,9 @@ def file_reader( : A decorator that should be applied to a no-argument function that (expensively) reads whatever data is desired. (This function may be a regular function or a - coroutine function.) The result of the decorator is a reactive ~shiny.reactive.Calc - that always returns up-to-date data, and invalidates callers when changes are - detected via polling. + co-routine function.) The result of the decorator is a reactive + :class:`~shiny.reactive.calc` that always returns up-to-date data, and invalidates + callers when changes are detected via polling. See Also -------- diff --git a/shiny/reactive/_reactives.py b/shiny/reactive/_reactives.py index fd724b130..c102cdd0e 100644 --- a/shiny/reactive/_reactives.py +++ b/shiny/reactive/_reactives.py @@ -51,8 +51,8 @@ class Value(Generic[T]): Create a reactive value. Reactive values are the source of reactivity in Shiny. Changes to reactive values - invalidate downstream reactive functions (:func:`~shiny.reactive.Calc`, - :func:`~shiny.reactive.Effect`, and `render` functions decorated with `@output`). + invalidate downstream reactive functions (:func:`~shiny.reactive.calc`, + :func:`~shiny.reactive.effect`, and `render` functions decorated with `@output`). When these functions are invalidated, they get scheduled to re-execute. Shiny input values are read-only reactive values. For example, `input.x` is a @@ -80,14 +80,14 @@ class Value(Generic[T]): Note ---- A reactive value may only be read from within a reactive function (e.g., - :func:`~shiny.reactive.Calc`, :func:`~shiny.reactive.Effect`, + :func:`~shiny.reactive.calc`, :func:`~shiny.reactive.effect`, :func:`shiny.render.text`, etc.) and, when doing so, the function takes a reactive dependency on the value (i.e., when the value changes, the calling reactive function will re-execute). See Also -------- - ~shiny.Inputs ~shiny.reactive.Calc ~shiny.reactive.Effect + ~shiny.Inputs ~shiny.reactive.calc ~shiny.reactive.effect """ # These overloads are necessary so that the following hold: @@ -232,7 +232,7 @@ class Calc_(Generic[T]): Warning ------- Most users shouldn't use this class directly to initialize a reactive calculation - (instead, use the :func:`~shiny.reactive.Calc` decorator). + (instead, use the :func:`~shiny.reactive.calc` decorator). """ def __init__( @@ -337,7 +337,7 @@ class CalcAsync_(Calc_[T]): Warning ------- Most users shouldn't use this class directly to initialize a reactive calculation - (instead, use the :func:`~shiny.reactive.Calc` decorator). + (instead, use the :func:`~shiny.reactive.calc` decorator). """ def __init__( @@ -401,18 +401,17 @@ def calc( """ 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., :class:`~shiny.Inputs`, :class:`~shiny.reactive.Value`, + A reactive calculation is a function whose return value depends on other + reactive value(s) (i.e., :class:`~shiny.Inputs`, :class:`~shiny.reactive.Value`s, 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 depend on it are "invalidated" and automatically re-execute if called while invalid. 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 - A :class:`~shiny.Session` instance. If not provided, it is inferred via + A :class:`~shiny.Session` instance. If not provided, the session is inferred via :func:`~shiny.session.get_current_session`. Returns @@ -423,13 +422,15 @@ def calc( Tip --- Reactive calculations should not produce any side effects; to reactively produce - side effects, use :func:`~shiny.reactive.Effect` instead. + side effects, use :func:`~shiny.reactive.effect` instead. + + Reactive calculations are analagous to reactive expressions in Shiny for R. See Also -------- ~shiny.Inputs ~shiny.reactive.Value - ~shiny.reactive.Effect + ~shiny.reactive.effect ~shiny.reactive.invalidate_later ~shiny.reactive.event """ @@ -671,17 +672,17 @@ def effect( """ Mark a function as a reactive side effect. - A reactive effect is like a reactive calculation (:func:`~shiny.reactive.Calc`) in + A reactive effect is like a reactive calculation (:func:`~shiny.reactive.calc`) in that it can read reactive values and call reactive calculations, and will automatically re-execute when those dependencies change. But unlike reactive calculations, it doesn't return a result and can't be used as an input to other - reactive expressions. Thus, observers are only useful for their side effects (for + reactive expressions. Thus, reactive effects are only useful for their side effects (for example, performing I/O). Another contrast between reactive calculations and effects is their execution strategy. Reactive calculations use lazy evaluation; that is, when their dependencies change, they don't re-execute right away but rather wait until they are - called by someone else. Indeed, if they are not called then they will never + called by someone else. Indeed, if they are not called, then they will never re-execute. In contrast, effects use eager evaluation; as soon as their dependencies change, they schedule themselves to re-execute. @@ -695,19 +696,23 @@ def effect( priority value will execute before all effects with lower priority values. Positive, negative, and zero values are allowed. session - A :class:`~shiny.Session` instance. If not provided, it is inferred via + A :class:`~shiny.Session` instance. If not provided, the session is inferred via :func:`~shiny.session.get_current_session`. Returns ------- : A decorator that marks a function as a reactive effect (:class:`Effect_`). + + Tip + --- + Reactive effects are analagous to observers in Shiny for R. See Also -------- ~shiny.Inputs ~shiny.reactive.Value - ~shiny.reactive.Effect + ~shiny.reactive.effect ~shiny.reactive.invalidate_later ~shiny.reactive.event """ @@ -738,18 +743,22 @@ def event( Mark a function to react only when an "event" occurs. Shiny's reactive programming framework is primarily designed for calculated values - (:func:`~shiny.reactive.Calc`) and side-effect-causing actions - (:func:`~shiny.reactive.Effect`) that respond to **any** of their inputs changing. + (:func:`~shiny.reactive.calc`) and side-effect-causing actions + (:func:`~shiny.reactive.effect`) that respond to **any** of their inputs changing. That's often what is desired in Shiny apps, but not always: sometimes you want to wait for a specific action to be taken from the user, like clicking an - :func:`~shiny.ui.input_action_button`, before calculating or taking an action. A - reactive value (or function) which triggers other calculation or action in this way - is called an event. + :func:`~shiny.ui.input_action_button`, before calculating or taking an action. You + do not want the calculation or action to be prematurely triggered if other reactive + values that it calls are invalidated. The reactive value (or function) which triggers + other calculations or actions in this way is called an event. These situations demand a more imperative, "event handling" style of programming, which ``@reactive.event()`` provides. It does this by using the :func:`~shiny.reactive.isolate` primitive under-the-hood to essentially "limit" the - set of reactive dependencies to those in ``args``. + set of reactive dependencies to those in ``args``. In other words, the event can call + as many reactive values as it likes in its code body without taking a reactive + dependency on them; it will be invalidated only when a dependency listed in args is + invalidated. Parameters ---------- @@ -761,7 +770,7 @@ def event( ignore_none Whether to ignore the event if the value is ``None`` or ``0``. ignore_init - If ``False``, the event trigger on the first run. + If ``False``, the event triggers on the first run. Returns ------- @@ -771,7 +780,7 @@ def event( Tip ---- This decorator must be applied before the relevant reactivity decorator (i.e., - ``@reactive.event`` must be applied before ``@reactive.Effect``, ``@reactive.Calc``, + ``@reactive.event`` must be applied before ``@reactive.effect``, ``@reactive.calc``, ``@render.ui``, etc). """ @@ -796,8 +805,8 @@ def decorator(user_fn: Callable[[], T]) -> Callable[[], T]: if isinstance(user_fn, Calc_): raise TypeError( - "`@reactive.event()` must be applied before `@reactive.Calc`.\n" - + "In other words, `@reactive.Calc` must be above `@reactive.event()`." + "`@reactive.event()` must be applied before `@reactive.calc`.\n" + + "In other words, `@reactive.calc` must be above `@reactive.event()`." ) # This is here instead of at the top of the .py file in order to avoid a From 34f825959906287a985fa34b9635fa778b54f1ae Mon Sep 17 00:00:00 2001 From: Garrett Grolemund Date: Fri, 8 Dec 2023 16:48:07 -0600 Subject: [PATCH 12/13] Uses black to reformat files --- shiny/_validation.py | 12 ++++++------ shiny/reactive/_core.py | 6 +++--- shiny/reactive/_poll.py | 24 ++++++++++++------------ shiny/reactive/_reactives.py | 16 ++++++++-------- 4 files changed, 29 insertions(+), 29 deletions(-) diff --git a/shiny/_validation.py b/shiny/_validation.py index b6c83a15a..35cd1f92b 100644 --- a/shiny/_validation.py +++ b/shiny/_validation.py @@ -25,12 +25,12 @@ def req(*args: T, cancel_output: bool = False) -> T | None: This is a convenient shorthand for throwing :func:`~shiny.types.SilentException` / :func:`~shiny.types.SilentCancelOutputException` if any of the arguments are falsy. - - The term "falsy" generally indicates that a value is considered False when - encountered in a logical context. We use the term a little loosely here; our usage - tries to match the intuitive notions of "Is this value missing or available?", or - "Has the user provided an answer?", or in the case of action buttons, "Has the - button been clicked?". So `False`, `None`, `0`, and `""` would be examples of Falsy + + The term "falsy" generally indicates that a value is considered False when + encountered in a logical context. We use the term a little loosely here; our usage + tries to match the intuitive notions of "Is this value missing or available?", or + "Has the user provided an answer?", or in the case of action buttons, "Has the + button been clicked?". So `False`, `None`, `0`, and `""` would be examples of Falsy values. Parameters diff --git a/shiny/reactive/_core.py b/shiny/reactive/_core.py index 2c8ad0d70..40576c527 100644 --- a/shiny/reactive/_core.py +++ b/shiny/reactive/_core.py @@ -270,8 +270,8 @@ def on_flushed( func The function to be called when the reactive environment is flushed once - Should the function be run once, and then cleared, or should it - re-run each time the event occurs. + Should the function be run once, and then cleared, or should it + re-run each time the event occurs. Returns ------- @@ -304,7 +304,7 @@ def invalidate_later( """ Scheduled Invalidation - When called from within a reactive context, :func:`~shiny.reactive.invalidate_later` + When called from within a reactive context, :func:`~shiny.reactive.invalidate_later` schedules the reactive context to be invalidated in the given number of seconds. Parameters diff --git a/shiny/reactive/_poll.py b/shiny/reactive/_poll.py index 6fb70f088..413125a8b 100644 --- a/shiny/reactive/_poll.py +++ b/shiny/reactive/_poll.py @@ -29,10 +29,10 @@ def poll( """ Create a reactive polling object. - Polling is a technique that approximates "real-time" or streaming updates, as if a - data source were pushing notifications each time it is updated. The data source does - not actually push notifications; a polling object repeatedly checks for changes in an - efficient way at specified intervals. If a change is detected, the polling object runs + Polling is a technique that approximates "real-time" or streaming updates, as if a + data source were pushing notifications each time it is updated. The data source does + not actually push notifications; a polling object repeatedly checks for changes in an + efficient way at specified intervals. If a change is detected, the polling object runs a function to re-read the data source. A reactive polling object is constructed using two functions: a polling function, @@ -75,7 +75,7 @@ def poll( priority Reactive polling is implemented using an :class:`~shiny.reactive.effect` to call `poll_func` on a timer; use the `priority` argument to control the order of this - Effect's execution versus other Effects in your app. See + Effect's execution versus other Effects in your app. See :func:`~shiny.reactive.effect` for more details. session A :class:`~shiny.Session` instance. If not provided, a session is inferred via @@ -88,8 +88,8 @@ def poll( : A decorator that should be applied to a no-argument function that (expensively) reads whatever data is desired. (This function may be a regular function or a - co-routine function.) The result of the decorator is a reactive - :class:`~shiny.reactive.calc` that always returns up-to-date data, and invalidates + co-routine function.) The result of the decorator is a reactive + :class:`~shiny.reactive.calc` that always returns up-to-date data, and invalidates callers when changes are detected via polling. See Also @@ -226,8 +226,8 @@ def file_reader( Note that `file_reader` works only on single files, not directories of files. Both the `filepath` function and the decorated (file reading) function can read - reactive values and :class:`~shiny.reactive.calc` objects. Any invalidations - triggered by reactive dependencies will apply to the reactive file reader object + reactive values and :class:`~shiny.reactive.calc` objects. Any invalidations + triggered by reactive dependencies will apply to the reactive file reader object immediately (not waiting for the `interval_secs` delay to expire). Parameters @@ -249,7 +249,7 @@ def file_reader( priority Reactive polling is implemented using an :class:`~shiny.reactive.effect` to call `poll_func` on a timer; use the `priority` argument to control the order of this - Effect's execution versus other Effects in your app. See + Effect's execution versus other Effects in your app. See :func:`~shiny.reactive.effect` for more details. session A :class:`~shiny.Session` instance. If not provided, a session is inferred via @@ -262,8 +262,8 @@ def file_reader( : A decorator that should be applied to a no-argument function that (expensively) reads whatever data is desired. (This function may be a regular function or a - co-routine function.) The result of the decorator is a reactive - :class:`~shiny.reactive.calc` that always returns up-to-date data, and invalidates + co-routine function.) The result of the decorator is a reactive + :class:`~shiny.reactive.calc` that always returns up-to-date data, and invalidates callers when changes are detected via polling. See Also diff --git a/shiny/reactive/_reactives.py b/shiny/reactive/_reactives.py index c102cdd0e..f4276abac 100644 --- a/shiny/reactive/_reactives.py +++ b/shiny/reactive/_reactives.py @@ -423,7 +423,7 @@ def calc( --- Reactive calculations should not produce any side effects; to reactively produce side effects, use :func:`~shiny.reactive.effect` instead. - + Reactive calculations are analagous to reactive expressions in Shiny for R. See Also @@ -703,7 +703,7 @@ def effect( ------- : A decorator that marks a function as a reactive effect (:class:`Effect_`). - + Tip --- Reactive effects are analagous to observers in Shiny for R. @@ -747,17 +747,17 @@ def event( (:func:`~shiny.reactive.effect`) that respond to **any** of their inputs changing. That's often what is desired in Shiny apps, but not always: sometimes you want to wait for a specific action to be taken from the user, like clicking an - :func:`~shiny.ui.input_action_button`, before calculating or taking an action. You - do not want the calculation or action to be prematurely triggered if other reactive - values that it calls are invalidated. The reactive value (or function) which triggers + :func:`~shiny.ui.input_action_button`, before calculating or taking an action. You + do not want the calculation or action to be prematurely triggered if other reactive + values that it calls are invalidated. The reactive value (or function) which triggers other calculations or actions in this way is called an event. These situations demand a more imperative, "event handling" style of programming, which ``@reactive.event()`` provides. It does this by using the :func:`~shiny.reactive.isolate` primitive under-the-hood to essentially "limit" the - set of reactive dependencies to those in ``args``. In other words, the event can call - as many reactive values as it likes in its code body without taking a reactive - dependency on them; it will be invalidated only when a dependency listed in args is + set of reactive dependencies to those in ``args``. In other words, the event can call + as many reactive values as it likes in its code body without taking a reactive + dependency on them; it will be invalidated only when a dependency listed in args is invalidated. Parameters From b508fab8beeee7900d2ae3a4ac05e69487c8b894 Mon Sep 17 00:00:00 2001 From: Barret Schloerke Date: Mon, 18 Dec 2023 15:05:06 -0500 Subject: [PATCH 13/13] Quote code --- shiny/_validation.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shiny/_validation.py b/shiny/_validation.py index 35cd1f92b..20dccf032 100644 --- a/shiny/_validation.py +++ b/shiny/_validation.py @@ -26,7 +26,7 @@ def req(*args: T, cancel_output: bool = False) -> T | None: This is a convenient shorthand for throwing :func:`~shiny.types.SilentException` / :func:`~shiny.types.SilentCancelOutputException` if any of the arguments are falsy. - The term "falsy" generally indicates that a value is considered False when + The term "falsy" generally indicates that a value is considered `False` when encountered in a logical context. We use the term a little loosely here; our usage tries to match the intuitive notions of "Is this value missing or available?", or "Has the user provided an answer?", or in the case of action buttons, "Has the