Skip to content

Consider replacing output_args() #971

@wch

Description

@wch

The output_args() function (added in #786) does the following: In Express, it allows passing arguments to the output function that's associated with a render function. For example, with the upcoming render.download() function (#967), it would look something like this:

@output_args(label="Download file")
@render.download(filename="hello.txt")
def dl:
    yield f"Hello, world! n = {input.n()}"

One major drawback is that the function signature accepts just *args and **kwargs, so it can't give any help for argument completion or typing. In the example above, you just have to know that the output UI function is download_button(), and look up the parameter names (and types) for that function.

Currently, if you want finer control and completion support, you can use @suspend_display and call the output UI function directly:

@suspend_display
@render.download(filename="hello.txt")
def dl:
    yield f"Hello, world! n = {input.n()}"

ui.download_button("dl", label="Download file")

The downside of this is that when the user just wants to customize a single parameter value, the code becomes a lot more verbose. And it's conceptually a bit of a leap to turn off the automatic UI, and then manually create it.

For the case of render_plot(), we've done something different: we added the output arguments to the render.plot() function. If we were to use that strategy here, it would look like this:

@render.download(filename="hello.txt", label="Download file")
def dl:
    yield f"Hello, world! n = {input.n()}"

This is concise, but it has the following drawbacks:

  • It's not immediately obvious to the user which arguments are for the output UI, and which are for the rendering step.
  • Those arguments are also present for Shiny Core, which may be confusing.

Another way we could go is to have a method for setting UI output arguments, that chains off the renderer object:

@render.download(filename="hello.txt").ui_args(label="Download file")
def dl:
    yield f"Hello, world! n = {input.n()}"

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions