Потоковая передача файлов WSGI с помощью генератора

У меня есть следующий код:

def application(env, start_response): path = process(env) fh = open(path,'r') start_response('200 OK', [('Content-Type','application/octet-stream')]) return fbuffer(fh,10000) def fbuffer(f, chunk_size): '''Generator to buffer file chunks''' while True: chunk = f.read(chunk_size) if not chunk: break yield chunk 

Я не уверен, что это правильно, но обрывки информации, которую я нашел в Интернете, заставили меня думать, что это должно сработать. В принципе, я хочу передать файл в куски, и для этого я передаю генератор из своей прикладной функции. Однако это только распечатывает заголовки и фактически не отправляет какие-либо данные, может ли кто-нибудь сказать мне, почему это так?

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

Третичный вопрос: как лучше всего закрыть файл, как только я закончил его вывод? В коде, который я разместил, я не вижу, чтобы фактически закрыть файл.

(Я запускаю python 3.2.3 с uWSGI 1.2.4)

One Solution collect form web for “Потоковая передача файлов WSGI с помощью генератора”

Не заботясь о том, что uwsgi осторожно не допускает утечки ошибок, но если вы запустите приложение в более строгой реализации, скажем, тот, который предоставляется с python как wsgiref.simple_server , вы можете более легко увидеть проблему.

 Serving <function application at 0xb65848> http://0.0.0.0:8000 Traceback (most recent call last): File "/usr/lib64/python3.2/wsgiref/handlers.py", line 138, in run self.finish_response() File "/usr/lib64/python3.2/wsgiref/handlers.py", line 179, in finish_response self.write(data) File "/usr/lib64/python3.2/wsgiref/handlers.py", line 264, in write "write() argument must be a bytes instance" AssertionError: write() argument must be a bytes instance localhost.localdomain - - [04/Aug/2012 16:27:08] "GET / HTTP/1.1" 500 59 

Проблема заключается в том, что wsgi требует, чтобы данные, передаваемые в и из HTTP-шлюза, должны обслуживаться как bytes , но когда вы используете open(path, 'r') , python 3 удобно преобразует данные, считываемые в unicode, что в python 3 является str , используя кодировку по умолчанию.

изменения

 fh = open(path, 'r') 

в

 fh = open(path, 'rb') # ^ 

исправляет его.

  • Несколько приложений mod_wsgi на одном виртуальном хосте, направляющем неправильное приложение
  • uwsgi: ваш серверный слуховой журнал отстает от 100 подключений
  • Как легко хранить удобные для чтения на python структуры данных только для чтения в общей памяти
  • Разница между утилитами WSGI и веб-серверами
  • Запланировать скрипт python для запуска на веб-сервере
  • Как я могу сказать Phusion Passenger, какой питон использовать?
  • Почему некоторые соединения mysql выбирают старые данные в базе данных mysql после удаления + вставки?
  • Как включить приложение Django в существующий витой сервер?
  • openID в wsgi с Python 3
  • Как создать новый auth_user и auth_group на Web2py, запущенном в Google App Engine (GAE)?
  • Как прекратить получение ImportError: не удалось импортировать настройки «mofin.settings» при использовании django с wsgi?
  • Python - лучший язык программирования в мире.