express.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.


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/*".


Type Description
Tag A UI element.


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

  • download_button


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

## file:
import pandas as pd

from shiny import reactive
from import input, render, ui
from shiny.types import FileInfo

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

def parsed_file():
    file: list[FileInfo] | None = input.file1()
    if file is None:
        return pd.DataFrame()
    return pd.read_csv(file[0]["datapath"])  # pyright: ignore[reportUnknownMemberType]

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()]