Skip to content

Best way to loop a download or image module #1726

@michaelsong-vbu

Description

@michaelsong-vbu

Hello,

I am learning about modules and found that looping an input component is relatively straightforward using examples. However, looping output components like downloads or images can be tricky. I would like to know the best ways to loop such components.

from shiny import App, module, render, ui
import os

num_extra_rows = 5
extra_ids = [f"row_{i}" for i in range(1, 2 + num_extra_rows)]

@module.ui
def row_ui(row_id):
  return ui.layout_columns(
      ui.input_text("text_in", f'Enter text {row_id}'),
      ui.output_text("text_out"),
      ui.download_button("download_data", "Download CSV")
  )

@module.server
def row_server(input, output, session, row_id):
  input_id = f"text_in_{row_id}"
  
    @output
    @render.text
    def text_out():
        return f'You entered "{input.text_in()}"'

    @output
    @render.download(
        filename=lambda: f"report.csv"
    )
    def download_data():
        path = os.path.join(os.path.dirname(__file__), "../image/report/", f"report{row_id}.csv")
        return path
  
app_ui = ui.page_fluid(
  [row_ui(x, x) for x in extra_ids]
)

def server(input, output, session):
  [row_server(x, x) for x in extra_ids]

app = App(app_ui, server)

For example, I want to generate six rows as defined in extra_ids. The input_text and output_text are auto-binded using {row_id}. However, the download_data function always downloads the report with the last row_id, i.e ., reportrow_6.csv. Here is a screenshot:

Image

Every “Download CSV” button outputs reportrow_6.csv instead of the intended reportrow_1.csv, reportrow_2.csv, etc.

I have also tried this for @render.images and encountered the same issue: the last image in the loop is shown for every entry, even though I specify the dynamic {name} like this:

ImgData = {"src": str(dir / "./image/upload_image" / {name}), "width": "100px"}

I might be doing something wrong, but I have not managed to implement dynamic looping for download and image components successfully. In Shiny R, I can use lapply for this purpose with ease. However, I am deeply invested in using Shiny for Python.

Thank you very much in advance for any assistance with this issue.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions