如何从 Python Pyramid 提供临时文件 [英] How can I serve temporary files from Python Pyramid

查看:29
本文介绍了如何从 Python Pyramid 提供临时文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

目前,我只是提供这样的文件:

Currently, I'm just serving files like this:

# view callable
def export(request):
    response = Response(content_type='application/csv')
    # use datetime in filename to avoid collisions
    f = open('/temp/XML_Export_%s.xml' % datetime.now(), 'r')
        # this is where I usually put stuff in the file
    response.app_iter = f
    response.headers['Content-Disposition'] = ("attachment; filename=Export.xml")
    return response

这样做的问题是我无法在响应返回后关闭或删除文件.该文件变得孤立.我可以想到一些解决这个问题的hacky方法,但我希望在某个地方有一个标准的方法.任何帮助都会很棒.

The problem with this is that I can't close or, even better, delete the file after the response has been returned. The file gets orphaned. I can think of some hacky ways around this, but I'm hoping there's a standard way out there somewhere. Any help would be awesome.

推荐答案

您不想将文件指针设置为 app_iter.这将导致 WSGI 服务器逐行读取文件(与 for line in file 相同),这通常不是控制文件上传的最有效方法(想象每行一个字符).Pyramid 支持的文件服务方式是通过 pyramid.response.FileResponse.您可以通过传递文件对象来创建其中之一.

You do not want to set a file pointer as the app_iter. This will cause the WSGI server to read the file line by line (same as for line in file), which is typically not the most efficient way to control a file upload (imagine one character per line). Pyramid's supported way of serving files is via pyramid.response.FileResponse. You can create one of these by passing a file object.

response = FileResponse('/some/path/to/a/file.txt')
response.headers['Content-Disposition'] = ...

另一种选择是将文件指针传递给 app_iter,但将其包装在 pyramid.response.FileIter 对象中,该对象将使用合理的块大小以避免仅读取一行一行的文件.

Another option is to pass a file pointer to app_iter but wrap it in the pyramid.response.FileIter object, which will use a sane block size to avoid just reading the file line by line.

WSGI 规范严格要求包含 close 方法的响应迭代器在响应结束时被调用.因此设置 response.app_iter = open(...) 不应该导致任何内存泄漏.FileResponseFileIter 都支持 close 方法,因此会按预期清理.

The WSGI specification has strict requirements that response iterators which contain a close method will be invoked at the end of the response. Thus setting response.app_iter = open(...) should not cause any memory leaks. Both FileResponse and FileIter also support a close method and will thus be cleaned up as expected.

作为对这个答案的一个小更新,我想我会解释为什么 FileResponse 采用文件路径而不是文件指针.WSGI 协议为服务器提供了一个可选的能力,通过 environ['wsgi.file_wrapper'] 提供一种优化机制来服务静态文件.FileResponse 如果您的 WSGI 服务器提供了该支持,将自动处理此问题.考虑到这一点,您会发现将数据保存到 ramdisk 上的 tmpfile 并为 FileResponse 提供完整路径,而不是尝试将文件指针传递给 FileIter.

As a minor update to this answer I thought I'd explain why FileResponse takes a file path and not a file pointer. The WSGI protocol provides servers an optional ability to provide an optimized mechanism for serving static files via environ['wsgi.file_wrapper']. FileResponse will automatically handle this if your WSGI server has provided that support. With this in mind, you find it to be a win to save your data to a tmpfile on a ramdisk and providing the FileResponse with the full path, instead of trying to pass a file pointer to FileIter.

http://docs.pylonsproject.org/projects/pyramid/en/1.4-branch/api/response.html#pyramid.response.FileResponse

这篇关于如何从 Python Pyramid 提供临时文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆