Package cherrypy :: Package tutorial :: Module tut09_files
[hide private]
[frames] | no frames]

Source Code for Module cherrypy.tutorial.tut09_files

  1  """ 
  2   
  3  Tutorial: File upload and download 
  4   
  5  Uploads 
  6  ------- 
  7   
  8  When a client uploads a file to a CherryPy application, it's placed 
  9  on disk immediately. CherryPy will pass it to your exposed method 
 10  as an argument (see "myFile" below); that arg will have a "file" 
 11  attribute, which is a handle to the temporary uploaded file. 
 12  If you wish to permanently save the file, you need to read() 
 13  from myFile.file and write() somewhere else. 
 14   
 15  Note the use of 'enctype="multipart/form-data"' and 'input type="file"' 
 16  in the HTML which the client uses to upload the file. 
 17   
 18   
 19  Downloads 
 20  --------- 
 21   
 22  If you wish to send a file to the client, you have two options: 
 23  First, you can simply return a file-like object from your page handler. 
 24  CherryPy will read the file and serve it as the content (HTTP body) 
 25  of the response. However, that doesn't tell the client that 
 26  the response is a file to be saved, rather than displayed. 
 27  Use cherrypy.lib.static.serve_file for that; it takes four 
 28  arguments: 
 29   
 30  serve_file(path, content_type=None, disposition=None, name=None) 
 31   
 32  Set "name" to the filename that you expect clients to use when they save 
 33  your file. Note that the "name" argument is ignored if you don't also 
 34  provide a "disposition" (usually "attachement"). You can manually set 
 35  "content_type", but be aware that if you also use the encoding tool, it 
 36  may choke if the file extension is not recognized as belonging to a known 
 37  Content-Type. Setting the content_type to "application/x-download" works 
 38  in most cases, and should prompt the user with an Open/Save dialog in 
 39  popular browsers. 
 40   
 41  """ 
 42   
 43  import os 
 44  localDir = os.path.dirname(__file__) 
 45  absDir = os.path.join(os.getcwd(), localDir) 
 46   
 47  import cherrypy 
 48  from cherrypy.lib import static 
 49   
 50   
51 -class FileDemo(object):
52
53 - def index(self):
54 return """ 55 <html><body> 56 <form action="upload" method="post" enctype="multipart/form-data"> 57 filename: <input type="file" name="myFile" /><br /> 58 <input type="submit" /> 59 </form> 60 </body></html> 61 """
62 index.exposed = True 63
64 - def upload(self, myFile):
65 out = """<html> 66 <body> 67 myFile length: %s<br /> 68 myFile filename: %s<br /> 69 myFile mime-type: %s 70 </body> 71 </html>""" 72 73 # Although this just counts the file length, it demonstrates 74 # how to read large files in chunks instead of all at once. 75 # CherryPy uses Python's cgi module to read the uploaded file 76 # into a temporary file; myFile.file.read reads from that. 77 size = 0 78 while True: 79 data = myFile.file.read(8192) 80 if not data: 81 break 82 size += len(data) 83 84 return out % (size, myFile.filename, myFile.type)
85 upload.exposed = True 86
87 - def download(self):
88 path = os.path.join(absDir, "pdf_file.pdf") 89 return static.serve_file(path, "application/x-download", 90 "attachment", os.path.basename(path))
91 download.exposed = True
92 93 94 cherrypy.tree.mount(FileDemo()) 95 96 if __name__ == '__main__': 97 import os.path 98 # Start the CherryPy server. 99 cherrypy.config.update(os.path.join(os.path.dirname(__file__), 'tutorial.conf')) 100 cherrypy.server.quickstart() 101 cherrypy.engine.start() 102