I saw examples that used pycurl, but could not be sure if this is the way to go with? Some examples will help. Thanks.
Here is demo application that implements tornado upload.
Here is server code:
import tornado.httpserver, tornado.ioloop, tornado.options, tornado.web, os.path, random, string
from tornado.options import define, options
define("port", default=8888, help="run on the given port", type=int)
class Application(tornado.web.Application):
def __init__(self):
handlers = [
(r"/", IndexHandler),
(r"/upload", UploadHandler)
]
tornado.web.Application.__init__(self, handlers)
class IndexHandler(tornado.web.RequestHandler):
def get(self):
self.render("upload_form.html")
class UploadHandler(tornado.web.RequestHandler):
def post(self):
file1 = self.request.files['file1'][0]
original_fname = file1['filename']
extension = os.path.splitext(original_fname)[1]
fname = ''.join(random.choice(string.ascii_lowercase + string.digits) for x in range(6))
final_filename= fname+extension
output_file = open("uploads/" + final_filename, 'w')
output_file.write(file1['body'])
self.finish("file" + final_filename + " is uploaded")
def main():
http_server = tornado.httpserver.HTTPServer(Application())
http_server.listen(options.port)
tornado.ioloop.IOLoop.instance().start()
if __name__ == "__main__":
main()
The only thing, you have to understand from this code, that file content located in self.request.files[<file_input_name>][0]
.
Here is html code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<title>Tornado Upload Application</title>
</head>
<body>
<p><h1>Tornado Upload App</h1></p>
<form enctype="multipart/form-data" action="/upload" method="post">
File: <input type="file" name="file1" />
<br />
<br />
<input type="submit" value="upload" />
</form>
When working with files - be sure, that form has enctype="multipart/form-data"
.
It's simple:
<form action="/file" methods="POST"><!--your code--></form>
in Python:
class FileHandler(tornado.web.RequestHandler):
# get post data
file_body = self.request.files['filefieldname'][0]['body']
img = Image.open(StringIO.StringIO(file_body))
img.save("../img/", img.format)
but it's not recommended, because all uploaded data is loaded in RAM; the best way is use nginx loadup module, but this is complex.
Previous code returned bad filename and wrong encoding. Following code works:
import tornado.httpserver, tornado.ioloop, tornado.options, tornado.web, os.path, random, string
class Application(tornado.web.Application):
def __init__(self):
handlers = [
(r"/", IndexHandler),
(r"/upload", UploadHandler)
]
tornado.web.Application.__init__(self, handlers)
class IndexHandler(tornado.web.RequestHandler):
def get(self):
self.render("tornadoUpload.html")
class UploadHandler(tornado.web.RequestHandler):
def post(self):
file1 = self.request.files['file1'][0]
original_fname = file1['filename']
output_file = open("uploads/" + original_fname, 'wb')
output_file.write(file1['body'])
self.finish("file " + original_fname + " is uploaded")
settings = {
'template_path': 'templates',
'static_path': 'static',
"xsrf_cookies": False
}
application = tornado.web.Application([
(r"/", IndexHandler),
(r"/upload", UploadHandler)
], debug=True,**settings)
print "Server started."
if __name__ == "__main__":
application.listen(8888)
tornado.ioloop.IOLoop.instance().start()
I was running into trouble when accesses the files properties with the [''] syntax, not sure why, but I switched to dot syntax and was able to read the data. I'm on a windows machine so I also had to change 'open("static/public/" + file_name, 'w')' to 'open("static/public/" + file_name, 'wb')'. Without the 'wb' the files were getting corrupted.
def uploadFile(self,input_name,file_type):
a_file = self.request.files[input_name][0]
extension = os.path.splitext(a_file.filename)[1]
if file_type is 'photo':
type_list = ['.png','.jpg','.jpeg','.gif']
elif file_type is 'attachment':
type_list = ['.pdf','.doc','.docx','.xls']
if extension in type_list:
file_name = ''.join(random.choice(string.ascii_lowercase + string.digits) for x in range(16))
output_file = open("static/public/" + file_name + extension, 'wb')
output_file.write(a_file.body)
return (a_file.filename + " has been uploaded.")
tornado.web.RequestHandler
has self.request.files
method.
it's result like
{u'file': [{'body':FILEBODY, 'content_type':CONTENT_TYPE, 'filename': FILENAME}],...}
来源:https://stackoverflow.com/questions/11909397/how-to-upload-an-image-with-python-tornado-from-an-html-form