PNG or JPG, up to 10 MB each. The first photo becomes the cover.
defproduct_photos()->None:withui.vstack(gap="xs",classes="w-full max-w-xl"):ui.file_upload(label="Product photos",multiple=True,max_files=6,accept="image/*",max_size_mb=10)ui.text("PNG or JPG, up to 10 MB each. The first photo becomes the ""cover.",color="muted",size="sm")
Attach to a message
variant="button" keeps the composer compact; list="chips" lines files up inline. paste=True turns a Ctrl+V of a screenshot into an attachment.
defcomposer()->None:withui.card(padding="md",classes="w-full max-w-xl"),ui.form(), \
ui.vstack(gap="sm"):ui.textarea(placeholder="Reply to Lumen Studio…",rows=3,size="sm")withui.hstack(gap="sm",justify="between",align="start"):ui.file_upload(variant="button",list="chips",multiple=True,max_files=5,paste=True,size="sm",label="Attach")ui.button("Send reply",type="button",icon_right="send",size="sm",classes="shrink-0")
Documents in a form
Chips in narrow columns, a colour and a size, and a disabled picker.
Drop the PDFAccepted: .pdfMax size: 5 MB
Drop a different file to replace
Quotes, minutes…Accepted: .pdf,.docxMultiple files allowed (up to 3)
Drop more files here
Up to 3 files, PDF or DOCX.
Choose a logo
Uploads are paused during the migration.
defcontract_documents()->None:withui.grid(min_col="16rem",gap="md",classes="w-full"):withui.form_field(label="Signed contract",required=True):ui.file_upload(list="chips",accept=".pdf",max_size_mb=5,color="success",size="sm",label="Drop the PDF")withui.form_field(label="Supporting documents",hint="Up to 3 files, PDF or DOCX."):ui.file_upload(list="chips",multiple=True,max_files=3,accept=[".pdf",".docx"],size="sm",label="Quotes, minutes…")withui.form_field(label="Company logo",hint="Uploads are paused during the migration."):ui.file_upload(variant="button",accept="image/*",disabled=True,size="sm",label="Choose a logo")
Import a CSV
Inside a form, the file is posted with it: the handler receives it by its name= and reads it.
classImportResult(PageState):file_name:str=field(default="")rows:int=field(default=0)defimport_contacts(contacts=None)->None:"""``contacts`` is the file_upload's ``name=``: the upload arrives here."""ifcontactsisNoneornothasattr(contacts,"read"):ui.notification("Drop a CSV file first.",variant="warning")returntext=contacts.file.read().decode("utf-8",errors="replace")result=ImportResult()result.file_name=contacts.filenameresult.rows=max(len(text.splitlines())-1,0)@refreshable(deps=[ImportResult])defimport_summary()->None:result=ImportResult()ifresult.file_name:ui.alert(f"{result.rows} contacts ready to import.",title=result.file_name,color="success",icon="file-check")defcsv_import()->None:withui.card(padding="md",classes="w-full max-w-xl"), \
ui.form(on_submit=import_contacts),ui.vstack(gap="md"):ui.heading("Import contacts",level=3,size="md")ui.file_upload(name="contacts",accept=".csv",max_files=1,max_size_mb=2,list="chips",label="Drop a CSV export from your CRM")withui.hstack(justify="end"):ui.button("Import",type="submit",icon_left="upload")import_summary()