Example: File Upload with Preview¶
Demonstrates ui.FileUpload — uploading an image and displaying a preview,
or uploading a CSV and showing the first rows in a table.
file_upload.py
import fluxui as ui
app = ui.App("File Upload Demo")
@app.page("/")
def home(session):
# State for image upload
image_path = ui.state("")
# State for CSV upload
csv_rows = ui.state([])
csv_name = ui.state("")
csv_error = ui.state("")
def handle_image(paths: list[str]) -> None:
if paths:
image_path.set(paths[0])
def handle_csv(paths: list[str]) -> None:
if not paths:
return
path = paths[0]
csv_name.set(path.split("/")[-1])
csv_error.set("")
try:
import csv
with open(path, newline="", encoding="utf-8") as f:
reader = csv.DictReader(f)
rows = [row for row in reader]
csv_rows.set(rows[:20]) # show at most 20 rows
except Exception as exc:
csv_error.set(f"Could not parse CSV: {exc}")
csv_rows.set([])
with ui.Column(gap="var(--s-8)"):
ui.Heading("File Upload Demo", level=1)
# ── Image upload ─────────────────────────────────────────────────
with ui.Card(title="Image upload", description="Upload any image file for a preview"):
ui.FileUpload(
prompt="Drop an image here or click to browse",
accept="image/*",
on_change=handle_image,
)
if image_path.value:
ui.Divider()
ui.Text("Preview:", variant="label")
ui.Image(
lambda: f"/uploads/{image_path.value.split('/')[-1]}",
alt="Uploaded image",
width="100%",
)
ui.Text(lambda: f"Path: {image_path.value}", variant="caption")
# ── CSV upload ───────────────────────────────────────────────────
with ui.Card(title="CSV upload", description="Upload a CSV to preview the first 20 rows"):
ui.FileUpload(
prompt="Drop a .csv file here or click to browse",
accept=".csv,text/csv",
on_change=handle_csv,
)
if csv_error.value:
ui.Alert(csv_error, variant="danger")
if csv_rows.value:
ui.Divider()
ui.Text(
lambda: f"Showing first {len(csv_rows.value)} rows of {csv_name.value}",
variant="label",
)
ui.Table(
data=csv_rows,
striped=True,
hover=True,
)
# ── Multi-file upload ─────────────────────────────────────────────
file_list = ui.list_state([])
def handle_multi(paths: list[str]) -> None:
for p in paths:
file_list.value.append(p.split("/")[-1])
with ui.Card(
title="Multiple files",
description="Select several files at once",
):
ui.FileUpload(
prompt="Drop files here or click to browse",
multiple=True,
on_change=handle_multi,
)
if file_list.value:
ui.Divider()
ui.Text("Uploaded files:", variant="label")
for fname in file_list.value:
with ui.Row(gap="var(--s-2)", align="center"):
ui.Badge("✓", variant="success")
ui.Text(fname)
if __name__ == "__main__":
app.run(port=8000)
How It Works¶
- The browser sends the selected file(s) via an HTTP
POST /uploadrequest. - FluxUI saves each file to a per-session temporary directory on the server.
- The server-side paths are passed to
on_changeaslist[str]. - Your handler reads, parses, or stores those paths however it likes.
Accessing uploaded files
Use pathlib.Path(paths[0]).read_bytes() to get the raw bytes, or pass
the path directly to pandas.read_csv(), PIL.Image.open(), etc.