Skip to main content
 首页 » 编程设计

用于流式传输请求正文内容的 Python 服务器

2025年05月04日9mfrbuaa

我正在尝试创建 python 智能代理服务器,它应该能够将大量请求正文内容从客户端流式传输到一些内部存储(可能是 amazon s3、swift、ftp 或类似的东西)。在流媒体服务器应该请求一些内部 API 服务器来确定上传到内部存储的参数之前。主要限制是它应该在一个 HTTP 操作中使用方法 PUT 完成。它还应该异步工作,因为会有很多文件上传。

什么解决方案可以让我从上传的内容中读取 block ,并在用户上传整个文件之前开始将这些 block 流式传输到内部存储?我知道的所有 python web 应用程序都将等待完整的内容,然后再将管理权交给 wsgi 应用程序/python web 服务器。

我找到的解决方案之一是 tornado fork https://github.com/nephics/tornado .但它是非官方的,tornado 开发人员不会急于将它包含到主分支中。 那么您可能知道我的问题的一些现有解决方案吗? Tornado ?扭曲?事件?

请您参考如下方法:

这是一个使用 Twisted 编写的进行流式上传处理的服务器示例:

from twisted.internet import reactor 
from twisted.internet.endpoints import serverFromString 
 
from twisted.web.server import Request, Site 
from twisted.web.resource import Resource 
 
from twisted.application.service import Application 
from twisted.application.internet import StreamServerEndpointService 
 
# Define a Resource class that doesn't really care what requests are made of it. 
# This simplifies things since it lets us mostly ignore Twisted Web's resource 
# traversal features. 
class StubResource(Resource): 
    isLeaf = True 
 
    def render(self, request): 
        return b"" 
 
class StreamingRequestHandler(Request): 
    def handleContentChunk(self, chunk): 
        # `chunk` is part of the request body. 
        # This method is called as the chunks are received. 
        Request.handleContentChunk(self, chunk) 
        # Unfortunately you have to use a private attribute to learn where 
        # the content is being sent. 
        path = self.channel._path 
 
        print "Server received %d more bytes for %s" % (len(chunk), path) 
 
class StreamingSite(Site): 
    requestFactory = StreamingRequestHandler 
 
application = Application("Streaming Upload Server") 
 
factory = StreamingSite(StubResource()) 
endpoint = serverFromString(reactor, b"tcp:8080") 
StreamServerEndpointService(endpoint, factory).setServiceParent(application) 

这是一个 tac 文件(将其放入 streamingserver.tac 并运行 twistd -ny streamingserver.tac)。

因为需要使用 self.channel._path 这不是一个完全支持的方法。总体而言,API 也相当笨拙,因此这更多地是一个示例,说明它可能,而不是它很好。长期以来,人们一直有意使这类事情变得更容易 (http://tm.tl/288),但要实现这一点可能还需要很长时间。