介紹python
一.使用python tornado實現web
# -*- coding: utf-8 -*- __Author__ = 'Traveler' import json import datetime import tornado.httpserver import tornado.ioloop import tornado.web import tornado.gen # from tornado.concurrent import run_on_executor from werkzeug import secure_filename from concurrent import futures # import pymongo import gridfs from bson.objectid import ObjectId from cStringIO import StringIO import logging # import logging.handlers logging.basicConfig(level=logging.INFO,format='%(asctime)s %(filename)s %(module)s %(funcName)s %(process)d %(thread)d %(threadName)s [line:%(lineno)d] [%(levelname)s] %(message)s') log = logging.getLogger() # 定義 storage Handler class StorageFiles(tornado.web.RequestHandler): def initialize(self): self.mongo = pymongo.MongoClient('127.0.0.1', 27017) self.db = self.mongo['storage'] self.fs = gridfs.GridFS(self.db, 'files') self.executor = futures.ThreadPoolExecutor(max_workers=24) # def Time(self): date1 = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') date2 = datetime.datetime.now().strftime('.%f')[:4] date = date1 + date2 return date # 只容許上傳下列後綴的文件 def __allowed_file(self, filename): ALLOWED_EXTENSIONS = set(['txt', 'conf', 'ini', 'cf', 'yml', 'xml', 'pdf', 'png', 'jpg', 'jpeg', 'gif', 'json', 'gz', 'rar', 'unzip','tgz']) return '.' in filename and filename.split('.', 1)[1] in ALLOWED_EXTENSIONS # @tornado.web.asynchronous @tornado.gen.coroutine def get(self): yield self._get() @run_on_executor def _get(self): filename = self.get_argument('filename') files_id = self.get_argument('files_id') # files = self.fs.get(ObjectId(files_id)) data = files.read() # self.set_header('Content-Type', 'application/octet-stream;charset=utf-8') self.set_header('Content-Disposition', 'attachment; filename=' + filename) self.write(data) # @tornado.web.asynchronous @tornado.gen.coroutine def post(self): yield self._post() @run_on_executor def _post(self): begin_time = self.Time() # files_meta = self.request.files['files'] # uri = [] for meta in files_meta: if meta and self.__allowed_file(meta['filename']): filename = secure_filename(meta['filename']) # 獲取一個安全的文件名,僅支持ASAII字符,若是須要文件包含中文,可註釋此行代碼 # files_meta.save(os.path.join(self._upload_folder,filename)) data = StringIO(meta['body']).getvalue() files_id = self.fs.put(data=data, filename=filename) args = '?filename=%s&files_id=%s' % (filename, files_id) uri.append(self.reverse_url(name='StorageFiles') + args) else: self.write(json.dumps({'error': 'The format is not correct'})) # runtime = {'begin_time': begin_time, 'end_time': self.Time()} res = {} res['status'] = 'ok' res['runtime'] = runtime # res['uri'] = {'download': download, 'delete': delete} res['uri'] = uri # self.write(json.dumps(res,sort_keys=True,indent=4,separators=(',',':'))) # @tornado.web.asynchronous @tornado.gen.coroutine def delete(self): yield self._delete() @run_on_executor def _delete(self): begin_time = self.Time() files_id = self.get_argument('files_id') self.fs.delete(ObjectId(files_id)) # os.remove(self._upload_folder + '/' + filename) runtime = {'begin_time': begin_time, 'end_time': self.Time()} res = {} res['status'] = 'ok' res['runtime'] = runtime self.write(json.dumps(res,sort_keys=True,indent=4,separators=(',',':'))) # class Application(tornado.web.Application): def __init__(self): handlers = [ (r'/storage',StorageFiles,{},'StorageFiles') ] # settings = { 'debug': True, } # super(Application,self).__init__(handlers=handlers,**settings) # def run(): import tornado.options from tornado.options import define, options define('port', default=8000, help='run on the given port', type=int) tornado.options.parse_command_line() app = Application() # app.listen(options.port,address='0.0.0.0') tornado.httpserver.HTTPServer(app).listen(options.port) log.info('listen http://127.0.0.1:8000') tornado.ioloop.IOLoop.instance().start() if __name__ == '__main__': run()
二.使用python flask實現json
ps: 其實flask-restful 的工做模式與tornado比較接近了.flask
# -*- coding: utf-8 -*- # from flask import Flask from flask import jsonify from flask import request from flask import make_response from werkzeug import secure_filename # from flask.ext.restful import Api from flask.ext.restful import Resource from flask.ext.restful import fields # import datetime # import pymongo from bson.objectid import ObjectId import gridfs from cStringIO import StringIO # class StorageFiles(Resource): def __init__(self): super(StorageFiles, self).__init__() # self._upload_folder = '/tmp/storage' self.mongo = pymongo.MongoClient('127.0.0.1',27017) self.db = self.mongo['storage'] self.fs = gridfs.GridFS(self.db,'files') def Time(self): date1 = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') date2 = datetime.datetime.now().strftime('.%f')[:4] date = date1 + date2 return date # def __allowed_file(self,filename): ALLOWED_EXTENSIONS = set(['txt', 'conf', 'ini', 'cf', 'yml', 'xml', 'pdf', 'png', 'jpg', 'jpeg', 'gif', 'json', 'gz', 'rar','unzip', 'tgz']) return '.' in filename and filename.split('.',1)[1] in ALLOWED_EXTENSIONS # def get(self): filename = request.values['filename'] files_id = request.values['files_id'] # files = self.fs.get(ObjectId(files_id)) data = files.read() headers = {} headers['Content-Type'] = 'application/octet-stream; charset=utf-8' headers['Content-Disposition'] = 'attachment; filename=' + filename return make_response(data,200,headers) # def post(self): begin_time = self.Time() # files = request.files['files'] files_meta = request.files.getlist('files') # uri = [] for meta in files_meta: filename = meta.filename if filename and self.__allowed_file(filename): filename = secure_filename(filename) # files.save(os.path.join(self._upload_folder,filename)) data = StringIO(meta.read()).getvalue() files_id = self.fs.put(data=data,filename=filename) uri.append(fields.url_for(endpoint='StorageFiles',files_id=files_id,filename=filename)) else: return make_response(jsonify({'error':'The format is not correct'}),403) # runtime = {'begin_time': begin_time, 'end_time': self.Time()} res = {} res['status'] = 'ok' res['runtime'] = runtime res['uri'] = uri # return make_response(jsonify(res),200) # def put(self): pass # def delete(self): begin_time = self.Time() files_id = request.values['files_id'] self.fs.delete(ObjectId(files_id)) # os.remove(self._upload_folder + '/' + filename) runtime = {'begin_time': begin_time, 'end_time': self.Time()} res = {} res['status'] = 'ok' res['runtime'] = runtime return make_response(jsonify(res), 200) # app = Flask(__name__) api = Api(app=app) api.add_resource(StorageFiles,'/storage',endpoint='StorageFiles') # if __name__ == '__main__': app.run(port=8000,debug=True)
測試後端
文件:test.txtapi
上傳:安全
curl -i -F 'files=@test.txt' http://127.0.0.1:8000/storage
下載:restful
curl 'http://127.0.0.1:8000/storage?filename=test.txt&files_id=57a856942f4dfd2f9923ba26'
刪除:app
curl -X DELETE 'http://127.0.0.1:8000/storage?filename=test.txt&files_id=57a856942f4dfd2f9923ba26'
備註: 下載和刪除的url改爲上傳後返回的uri.curl