0

我有一个我正在尝试创建的示例,最好使用 Django(或其他类似的框架),它会立即将上传的内容逐块压缩成一种奇怪的压缩格式(无论是 LZMA、7zip 等)。然后写出到 S3 的另一个上传请求。

本质上,这就是将会发生的事情:

  1. 用户在 启动到我的端点的分段上传^/upload/?$
  2. 当服务器上接收到块时(可能是 1024 字节或其他数字),它们然后以块的形式通过压缩算法。
  3. 压缩后的输出通过线路写入 S3 存储桶。

第 3 步是可选的;我可以将文件存储在本地,并让消息队列以延迟的方式进行上传。

使用 Django 之类的框架是否可以执行第 2 步?是否有一种访问类文件对象中传入数据的低级方法?

4

1 回答 1

0

Django Request 对象提供了一个类似文件的接口,因此您可以从中流式传输数据。但是,由于 Django 总是将整个请求读入内存(如果文件上传太大,则读入临时文件),因此您只能在收到整个请求后使用此 API。如果您的临时存储目录足够大,并且您不介意在服务器上缓冲数据,则不需要做任何特别的事情。只需将数据上传到视图内的 S3。不过要小心超时。如果上传到 S3 的时间过长,浏览器将收到超时。因此,我建议将临时文件移动到更永久的目录并通过工作队列(如Celery.


如果您想通过服务器直接从客户端流式传输到 Amazon S3,我建议使用gevent. 使用 gevent,您可以编写一个greenlet从 a 读取queue并写入 S3 的简单程序。该队列由从请求中读取的原始 greenlet 填充。

您可以使用特殊的上传 URL,例如http://upload.example.com/部署该特殊服务器的位置。如果您设置 DJANGO_SETTINGS_MODULE 环境变量并处理中间件通常为您做的一些事情(数据库连接/断开、事务开始/提交/回滚、会话处理等),则可以从 Django 框架外部使用 Django 函数.

甚至可以在同一个 WSGI 容器中同时运行您的自定义 WSGI 应用程序和 Django。只需包装 Django WSGI 应用程序并拦截对/upload/. 在这种情况下,我建议使用gunicornasgevent worker-class服务器。


我对 Amazon S3 API 不太熟悉,但据我所知,您也可以直接从您的用户那里为文件上传生成一个临时令牌。这样,您根本不需要通过服务器传输数据。

编辑:您确实可以允许匿名上传到您的存储桶。请参阅有关此主题的此问题:S3 - 匿名上传 - 密钥前缀

于 2013-02-05T22:00:18.177 回答