How to use data uploaded through a FileInput widget in a param.Parameterized class and handle situation where no data has been uploaded yet?

I decided to make a separate topic for how to watch for changes in the global variable file_input, because this seems slightly off-topic. The solution was given here: Inside a class, how to watch for changes in a global variable? - #2 by carl. Special thanks to @carl

For documentation purposes, the final code needed to close this topic is:

import panel as pn
import param
import pandas as pd 
import io

pn.extension()

file_upload = pn.widgets.FileInput(accept=".xlsx")

class DataSelector(param.Parameterized):
    select = param.Selector(["Please upload data"])
    
    def __init__(self, file_upload, **params):
        super().__init__(**params)
        self.file_upload = file_upload
        
    def file_callback(self, event):
        if event.new:
            data = io.BytesIO()
            self.file_upload.save(data)
            data.seek(0)
            df = pd.read_excel(data)
            self.param.select.objects = sorted(df.columns.to_list(), key=str.lower)
            
data_selector = DataSelector(file_upload=file_upload) 
file_upload.param.watch(data_selector.file_callback, 'value')

pn.Column(
    file_upload, 
    data_selector.param.select
).servable()
1 Like