mon*_*res 14 python web-frameworks flask
我目前正在开发一个服务器端json接口,其中有几个临时文件在请求期间进行操作.
我在请求结束时清理这些文件的当前解决方案如下所示:
@app.route("/method",methods=['POST'])
def api_entry():
with ObjectThatCreatesTemporaryFiles() as object:
object.createTemporaryFiles()
return "blabalbal"
Run Code Online (Sandbox Code Playgroud)
在这种情况下,清理采用对象中的花边.__ exit __()
但是在少数情况下我需要将临时文件返回给客户端,在这种情况下代码如下所示:
@app.route("/method",methods=['POST'])
def api_entry():
with ObjectThatCreatesTemporaryFiles() as object:
object.createTemporaryFiles()
return send_file(object.somePath)
Run Code Online (Sandbox Code Playgroud)
这当前不起作用,因为当我进行清理时,烧瓶正在读取文件并将其发送到客户端.¨我怎么解决这个问题?
编辑:我忘了提到文件位于临时目录中.
如果您使用的是Flask 0.9或更高版本,则可以使用after_this_request装饰器:
@app.route("/method",methods=['POST'])
def api_entry():
tempcreator = ObjectThatCreatesTemporaryFiles():
tempcreator.createTemporaryFiles()
@after_this_request
def cleanup(response):
tempcreator.__exit__()
return response
return send_file(tempcreator.somePath)
Run Code Online (Sandbox Code Playgroud)
编辑
由于这不起作用,您可以尝试使用cStringIO(这假设您的文件足够小以适应内存):
@app.route("/method", methods=["POST"])
def api_entry():
file_data = dataObject.createFileData()
# Simplest `createFileData` method:
# return cStringIO.StringIO("some\ndata")
return send_file(file_data,
as_attachment=True,
mimetype="text/plain",
attachment_filename="somefile.txt")
Run Code Online (Sandbox Code Playgroud)
或者,您可以像现在一样创建临时文件,但不依赖于您的应用程序来删除它们.相反,设置一个cron作业(或者如果你在Windows上运行一个计划任务)每小时左右运行一次,并删除临时目录中超过半小时创建的文件.
我使用的方法是在响应完成后使用弱引用来删除文件.
import shutil
import tempfile
import weakref
class FileRemover(object):
def __init__(self):
self.weak_references = dict() # weak_ref -> filepath to remove
def cleanup_once_done(self, response, filepath):
wr = weakref.ref(response, self._do_cleanup)
self.weak_references[wr] = filepath
def _do_cleanup(self, wr):
filepath = self.weak_references[wr]
print('Deleting %s' % filepath)
shutil.rmtree(filepath, ignore_errors=True)
file_remover = FileRemover()
Run Code Online (Sandbox Code Playgroud)
在烧瓶电话中,我有:
@app.route('/method')
def get_some_data_as_a_file():
tempdir = tempfile.mkdtemp()
filepath = make_the_data(dir_to_put_file_in=tempdir)
resp = send_file(filepath)
file_remover.cleanup_once_done(resp, tempdir)
return resp
Run Code Online (Sandbox Code Playgroud)
这是非常通用的,因为我已经使用了三种不同的python web框架.