我想知道使用Pyramid从GridFS提供文件的最佳和最简单的方法是什么。我使用nginx作为代理服务器(对于ssl)和waitress作为我的应用程序服务器。
我需要能够提供的文件类型如下:mp3,pdf,jpg,png
应通过以下网址“/ files / {userid} / {filename}”
访问这些文件现在,文件由客户端的正确应用程序打开,因为我在代码中明确设置了内容类型,如下所示:
if filename[-3:] == "pdf":
response = Response(content_type='application/pdf')
elif filename[-3:] in ["jpg", "png"]:
response = Response(content_type='image/*')
elif filename[-3:] in ["mp3"]:
response = Response(content_type='audio/mp3')
else:
response = Response(content_type="application/*")
response.app_iter = file #file is a GridFS file object
return response
唯一的问题是我无法正确播放mp3。我用audio.js来播放它们。它们打开并播放但没有显示轨道长度,我无法寻找它们。我知道它与“接受范围”属性有关,但我似乎无法正确设置它。它与nginx或女服务员有关吗?或者我只是没有正确设置标题?
我想使用像return FileResponse(file)
一样简单的东西,如指定的here,但我的文件不是直接来自文件系统...是否有即插即用的方法来使这个工作?< / p>
任何建议都会非常感激!
非常感谢你的帮助!
答案 0 :(得分:1)
我找到了blog的解决方案。
我们的想法是使用来自DataApp
的修补paste.fileapp
。所有细节都在帖子中,现在我的应用就像我想要的那样!
答案 1 :(得分:1)
我刚刚在Pyramid 1.4,Python 3中解决了没有粘贴相关性的问题。
似乎属性“conditional_response = True”和“content_length”很重要:
f = request.db.fs.files.find_one( { 'filename':filename, 'metadata.bucket': bucket } )
fs = gridfs.GridFS( request.db )
with fs.get( f.get( '_id') ) as gridout:
response = Response(content_type=gridout.content_type,body_file=gridout,conditional_response=True)
response.content_length = f.get('length')
return response
答案 2 :(得分:0)
另一种方式(在Python 2.7上使用Pyramid 1.5.7):
fs = GridFS(request.db, 'MyFileCollection')
grid_out = fs.get(file_id)
response = request.response
response.app_iter = FileIter(grid_out)
response.content_disposition = 'attachment; filename="%s"' % grid_out.name
return response