将数据传递给mod_wsgi

时间:2009-06-02 17:29:08

标签: python mod-wsgi wsgi

在mod_wsgi中,我通过运行函数start_response()发送头文件,但所有页面内容都通过yield / return传递。有没有办法以与start_response()类似的方式传递页面内容?在处理分块数据时,使用return.yield语句是非常严格的。

E.g。

def Application():

    b = buffer()

    [... page code ...]

    while True:
        out = b.flush()    
        if out:
            yield out

class buffer:

    def __init__(self):        
        b = ['']
        l = 0

    def add(self, s):
        s = str(s)
        l += len(s)
        b.append(s)

    def flush(self):

        if self.l > 1000:
            out = ''.join(b)
            self.__init__()
            return out

我希望缓冲区在页面加载时输出内容,但只有在内容堆积起来时才输出内容(例如1000字节)。

3 个答案:

答案 0 :(得分:2)

没有;但我不认为这是限制性的。也许您想要在描述限制的地方粘贴示例代码,我们可以提供帮助。

要处理块数据,只需yield块:

def application(environ, start_response):
    start_response('200 OK', [('Content-type', 'text/plain')]
    yield 'Chunk 1\n'    
    yield 'Chunk 2\n'    
    yield 'Chunk 3\n'
    for chunk in chunk_data_generator():
        yield chunk

def chunk_data_generator()
    yield 'Chunk 4\n'
    yield 'Chunk 5\n'

编辑:根据您提供的评论,在向前发送之前将数据堆积到一定长度的示例:

BUFFER_SIZE = 10 # 10 bytes for testing. Use something bigger
def application(environ, start_response):
    start_response('200 OK', [('Content-type', 'text/plain')]
    buffer = []
    size = 0
    for chunk in chunk_generator():
        buffer.append(chunk)
        size += len(chunk)
        if size > BUFFER_SIZE:
            for buf in buffer:
                yield buf
            buffer = []
            size = 0

def chunk_data_generator()
    yield 'Chunk 1\n'    
    yield 'Chunk 2\n'    
    yield 'Chunk 3\n'
    yield 'Chunk 4\n'
    yield 'Chunk 5\n'

答案 1 :(得分:1)

您的应用程序可能将数据“推送”到WSGI服务器:

  

一些现有的应用程序框架API以不同于WSGI的方式支持无缓冲输出。具体来说,它们提供了一种“写”功能或某种方法来编写一个无缓冲的数据块,或者它们提供了一个缓冲的“写”功能和一个“刷新”机制来刷新缓冲区。

     

不幸的是,除非使用线程或其他特殊机制,否则无法根据WSGI的“可迭代”应用程序返回值实现此类API。

     

因此,为了允许这些框架继续使用命令式API,WSGI包含一个特殊的write()可调用,由start_response可调用返回。

     

新的WSGI应用程序和框架不应该使用write()可调用的,如果可以避免这样做的话。

     

http://www.python.org/dev/peps/pep-0333/#the-write-callable

但不建议这样做。

  

一般来说,应用程序将通过缓冲其(适度大小)输出并立即发送所有内容来实现最佳吞吐量。这是现有框架(如Zope)中的常见方法:输出缓存在StringIO或类似对象中,然后一起传输,并与响应头一起传输。

     

WSGI中的相应方法是让应用程序简单地将包含响应主体的单元素可迭代(例如列表)作为单个字符串返回。这是绝大多数应用程序函数的推荐方法,它可以呈现其文本很容易适合内存的HTML页面。

     

http://www.python.org/dev/peps/pep-0333/#buffering-and-streaming

答案 2 :(得分:1)

如果您不希望在发送之前更改WSGI应用程序本身以部分缓冲响应数据,那么实现一个WSGI中间件,它包装您的WSGI应用程序并执行该任务。