ui.input_file

ui.input_file(
    id
    label
    *
    multiple=False
    accept=None
    width=None
    button_label='Browse...'
    placeholder='No file selected'
    capture=None
)

Create a file upload control that can be used to upload one or more files.

Parameters

id : str

An input id.

label : TagChild

An input label.

multiple : bool = False

Whether the user should be allowed to select and upload multiple files at once.

accept : Optional[str | list[str]] = None

Unique file type specifier(s) which give the browser a hint as to the type of file the server expects. Many browsers use this to prevent the user from selecting an invalid file. Examples of valid values include a case insensitive extension (e.g. .csv or .rds), a valid MIME type (e.g. text/plain or application/pdf) or one of audio/*, video/*, or image/* meaning any audio, video, or image type, respectively.

width : Optional[str] = None

The CSS width, e.g. â€˜400px’, or ‘100%’

button_label : str = 'Browse…'

The label used on the button.

placeholder : str = 'No file selected'

The text to show on the input before a file has been uploaded.

capture : Optional[Literal[‘environment’, ‘user’]] = None

On mobile devices, this can be used to open the device’s camera for input. If “environment”, it will open the rear-facing camera. If “user”, it will open the front-facing camera. By default, it will accept either still photos or video. To accept only still photos, use accept="image/*"; to accept only video, use accept="video/*".

Returns

: Tag

A UI element.

Notes

Server value

A list of dictionaries (one for each file upload) with the following keys:

  • name: The filename provided by the web browser. This is not the path to read to get at the actual data that was uploaded (see ‘datapath’).
  • size: The size of the uploaded data, in bytes.
  • type: The MIME type reported by the browser (for example, ‘text/plain’), or empty string if the browser didn’t know.
  • datapath: The path to a temp file that contains the data that was uploaded. This file may be deleted if the user performs another upload operation.

See Also

Examples

#| standalone: true
#| components: [editor, viewer]
#| layout: vertical
#| viewerHeight: 400

## file: app.py
import pandas as pd

from shiny import App, Inputs, Outputs, Session, reactive, render, ui
from shiny.types import FileInfo

app_ui = ui.page_fluid(
    ui.input_file("file1", "Choose CSV File", accept=[".csv"], multiple=False),
    ui.input_checkbox_group(
        "stats",
        "Summary Stats",
        choices=["Row Count", "Column Count", "Column Names"],
        selected=["Row Count", "Column Count", "Column Names"],
    ),
    ui.output_table("summary"),
)


def server(input: Inputs, output: Outputs, session: Session):
    @reactive.calc
    def parsed_file():
        file: list[FileInfo] | None = input.file1()
        if file is None:
            return pd.DataFrame()
        return pd.read_csv(  # pyright: ignore[reportUnknownMemberType]
            file[0]["datapath"]
        )

    @render.table
    def summary():
        df = parsed_file()

        if df.empty:
            return pd.DataFrame()

        # Get the row count, column count, and column names of the DataFrame
        row_count = df.shape[0]
        column_count = df.shape[1]
        names = df.columns.tolist()
        column_names = ", ".join(str(name) for name in names)

        # Create a new DataFrame to display the information
        info_df = pd.DataFrame(
            {
                "Row Count": [row_count],
                "Column Count": [column_count],
                "Column Names": [column_names],
            }
        )

        # input.stats() is a list of strings; subset the columns based on the selected
        # checkboxes
        return info_df.loc[:, input.stats()]


app = App(app_ui, server)