How to download a variable number of files with one multi-page post header

I have a repeating form field:

<div class="repeat">
    <input type="file" name="files[==row-count-placeholder==]" />
</div>

      

which will (using jQuery) for example will result in

<div class="repeat">
    <input type="file" name="files[0]" />        
    <input type="file" name="files[1]" />  
    <input type="file" name="files[2]" />
    <!-- and so on -->
</div>

      

depending on how many files the user needs to download. Forms method post

and enctype is multipart/form-data

.

Using cherrypy as my server and voluptuous validation library, I would like to keep the uploaded files:

import voluptuous

def save_uploaded_file(file, path)
    #save file on server...

def validate_files(files):    
    for file in files:
        save_uploaded_file(file, cherrypy.request.config['static_dir'])

@cherrypy.expose
def index(self, **kwargs):

    schema = Schema({
        'files' : validate_files
    }, required = True, extra = True)

    kwargs = schema(kwargs)

      

So I really need a message header containing information about all the files (something like a list of files would be best) under one key called files

, but all I get is a few keys like files[0]

, files[1]

etc.

How do I approach this? Should I somehow manually create an array containing all the information files

, or is there a more general or practical way to do this?

Solution (following suggestion by saaj):

schema_dict = {
    'name' : All(Length(min=3, msg="Can't believe that there is a name less than 3 characters...")),
    # ...
    }

# validate files
isPart = lambda v: isinstance(v, cherrypy._cpreqbody.Part)      
files1 = [a for a in kwargs.values() if isPart(a)]
files2 = [a for a in cherrypy.request.params.values() if isPart(a)]
assert files1 == files2

for file in files1:
    # for each file add dict entry and route to validation function
    schema_dict.update({file.name : validate_file}) 

schema = volu.Schema(schema_dict, required = True, extra = True)

      

Likewise it Schema

can contain many other fields. The presented files are generally added to any Schema

. Cool!

+3


source to share


1 answer


Just take the files from the request (if your form doesn't contain other types of parts, you can take the request parameters as they are).

@cherrypy.expose
def index(self, **kwargs):
  isPart = lambda v: isinstance(v, cherrypy._cpreqbody.Part)
  files1 = [a for a in kwargs.values() if isPart(a)]
  files2 = [a for a in cherrypy.request.params.values() if isPart(a)]

  assert files1 == files2
  print(files1) # pass it where you want to

      



CherryPy related questions: load performance , asynchronous loading .

+1


source







All Articles