How to access multiple files server-side from the fileloader

Hi,

What I’m trying to do:

I need my users to be able to click on my app’s fileloader, select multiple files (csv or xlsx) and have them sent over the uplink to the server as media objects, then write a tempfile for each media object so they can be processed individually.

What I’ve tried and what’s not working:

It looks like only one media object gets sent even when multiple files are selected, with my current code.

I have been able to select multiple files in the Windows folder dialog box which opens when the fileloader is clicked, and the fileloader then says ‘3 files selected’, using the following client code with the fileloader ‘multiple’ option checked, so far so good:

Code Sample:

def file_loader_1_change(self, file, **event_args)
  server_response = anvil.server.call('access_files', media_object) 

On the server, the ‘access_files’ function is called, which uses anvil.media.TempFile to create a temporary file of the media object, accessible via file_name:

@anvil.server.callable
def access_files(media_object):
    with anvil.media.TempFile(media_object) as file_name:
        print(file_name)

file_name when printed looks something like this:
/tmp/xvj16vglc4bljbkpnzs9on5a9vtqnuo5

Question: What am I doing wrong?

I looked here and nothing seems to cover accessing multiple files: Anvil Docs | Files on Disk

Thank you,

Richard

Multiple files is a feature of the FileLoader, not the MediaObject. If I read the FileLoader docs correctly, file_loader_1_change will be called once per file, not per list-of-files.

So access_files will be called 3 times.

In between those times, the server-side /tmp/ folder may be cleared. If you want to keep the file contents around longer than that, you could use a Media column in a database table.

2 Likes

If you can defer processing until a Save button is clicked, then you can access the file loader’s files property which is a list of all the files selected, e.g.:

self.file_loader_1.files

That allows you to make a single server call with a list of files submitted.

4 Likes

Thank you, I used this method to pass the files list and this enabled me to loop through the media objects on the server to create temp files, process and store them in a dictionary on the server in a single call.

On the client:

  def file_loader_1_change(self, file, **event_args):
    files_list = self.file_loader_1.files
    server_response = anvil.server.call('access_files', file, files_list)

On the server (I’m using pandas as pd to make the Excel files ready for processing):

@anvil.server.callable
def access_files(file, files_list):
    files_dict = {}
    for f in range(len(files_list)):
        with anvil.media.TempFile(files_list[f]) as temp_file_name:
            files_dict['File ' + str(f)] = pd.ExcelFile(temp_file_name)
    print(files_dict)

The resulting dictionary, containing files that I can manipulate:

{'File 0': <pandas.io.excel._base.ExcelFile object at 0x7fc72a7576d8>, 'File 1': <pandas.io.excel._base.ExcelFile object at 0x7fc72a757b00>}

Hi, Richard.
Would you please tell me the format of your “file”, likely say .exl, .csv, . txt? and what is your “files_list” look like?
Please give me one more tangible example.
Thx

@kzhou3, He was talking about this, the list of media objects that comes from the file loader component on a client form:

Also, This thread is 15 months old, I strongly suggest starting a new question if you are still having trouble? You can always link back to this thread for context in the new question.

thx for a quick reply. … yes., I will start a new question.