Передача данных в mod_wsgi
Вопрос
В 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()
можно вызвать, если этого можно избежать.
Но это не рекомендуется.
Вообще говоря, приложения достигают наилучшей пропускной способности, буферизуя свои выходные данные (небольшого размера) и отправляя их все одновременно.Это распространенный подход в существующих фреймворках, таких как Zope:выходные данные буферизуются в StringIO или аналогичном объекте, а затем передаются сразу вместе с заголовками ответов.
Соответствующий подход в WSGI заключается в том, что приложение просто возвращает одноэлементную итерацию (например, список), содержащую тело ответа в виде одной строки.Это рекомендуемый подход для подавляющего большинства функций приложения, которые отображают HTML-страницы, текст которых легко помещается в памяти.
http://www.python.org/dev/peps/pep-0333/#buffering-and-streaming
Если вы не хотите изменять само приложение WSGI для частичной буферизации данных ответа перед его отправкой, реализуйте промежуточное программное обеспечение WSGI, которое обертывает ваше приложение WSGI и выполняет эту задачу.