Вопрос

В mod_wsgi я отправляю заголовки, запуская функцию start_response(), но все содержимое страницы передается с помощью метода yield/return.Есть ли способ передать содержимое страницы аналогично start_response()?Использование оператора return.yield накладывает очень серьезные ограничения при работе с фрагментированными данными.

Например.

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 байт).

Это было полезно?

Решение

Нет;Но я не думаю, что это является ограничительным.Возможно, вы хотите вставить пример кода, в котором вы описываете свое ограничение, и мы сможем помочь.

Для работы с данными фрагментов вам просто 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'

Другие советы

Это возможный чтобы ваше приложение «передавало» данные на сервер WSGI:

Некоторые существующие API-интерфейсы платформы приложений поддерживают небуферизованный вывод иначе, чем WSGI.В частности, они предоставляют функцию или метод «записи» для записи небуферизованного блока данных или же они предоставляют буферизованную функцию «записи» и механизм «очистки» для очистки буфера.

К сожалению, такие API не могут быть реализованы с использованием «итеративного» возвращаемого значения приложения WSGI, если не используются потоки или другие специальные механизмы.

Поэтому, чтобы позволить этим платформам продолжать использовать императивный 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

Если вы не хотите изменять само приложение WSGI для частичной буферизации данных ответа перед его отправкой, реализуйте промежуточное программное обеспечение WSGI, которое обертывает ваше приложение WSGI и выполняет эту задачу.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top