2013-02-22 2 views
3

У меня есть приложение Django, которое должно иметь доступ к чтению многофайловых загрузок файлов в виде файловых объектов по мере их загрузки,, что означает, что мне нужен более или менее синхронный доступ к объект запроса и способ распаковать его в куски на двоичные данные. Django, к сожалению, обрабатывает закачки, перемещая их непосредственно в память или во временные файлы, что не будет работать для моего использования.Синхронное чтение многостраничной загрузки вместе с Django

Некоторые из них рекомендовали использовать gevent/greenlet для обработки загрузки, но я не уверен, как это играет в уравнение и какая настройка требуется вместе с Django, чтобы заставить его работать. Кроме того, запуск чего-то за пределами Django означало бы, что мне придется реализовать уровень подключения к базе данных, чтобы проверить, что загрузка разрешена (с использованием идентификатора билета).

С этим сказано, как я могу настроить это? Django должен запускаться в приложении WSGI, и кто-то также рекомендовал написать второе приложение WSGI для захвата одного URL-адреса для загрузки. Я бы хотел, по существу, использовать как можно больше преимуществ структуры Django, будучи в состоянии читать загрузки одновременно?

(я только познакомился с библиотекой requests Python и должен сказать, что я довольно большой поклонник, хотя я не знаю, первое дело об использовании его в контексте сервера.)

ответ

5

Я считаю, что многие из этих предложений являются слишком сложными.

Нужно изменить способ загрузки файлов Django? Просто измените the upload handler.

base class относительно прост и дает вам множество отличных крючков. Вы должны быть в состоянии расширить его, чтобы делать то, что вы хотите.

+0

У меня должен быть RTFM. Facepalm. –

+0

Ха-ха, он получает лучшее из нас. – Hamms

1

Хотя я не могу написать весь код для вас (это сложно), вот моя рекомендуемая настройка.

  1. Используйте Tornado + Джанго: Торнадо может встраивать процессы WSGI, так что это дает вам возможность иметь один хост процесс как Django, и это один от обработчика Tornado. Вот краткий пример одного из моих активных проектов (хотя это с помощью Tornado в качестве обработчика Socket.io, это должно дать вам суть решения (:

    # Socket Server 
    db = momoko.Pool(DB_DSN, **DB_CONFIG) 
    router = tornadio2.TornadioRouter(QueryRouter, user_settings={'db':db}) 
    sock_app = tornado.web.Application(router.urls, flash_policy_port = FL_PORT, flash_policy_file = path.join(PROJECT_ROOT, 'assets/xml/flashpolicy.xml'), socket_io_port = WS_PORT, debug=True) 
    # Django Server 
    os.environ['DJANGO_SETTINGS_MODULE'] = 'sever.settings' 
    application = django.core.handlers.wsgi.WSGIHandler() 
    container = tornado.wsgi.WSGIContainer(application) 
    
    
    # Start the web servers 
    if __name__ == "__main__": 
        try: 
         import logging 
         tornado.options.parse_command_line() 
         logging.getLogger().setLevel(logging.INFO) 
         logging.info('Server started') 
         tornado.locale.set_default_locale('us_US') 
         http_server = tornado.httpserver.HTTPServer(container) 
         http_server.listen(8000) 
         tornadio2.SocketServer(sock_app, auto_start=True) 
         tornado.ioloop.IOLoop.instance().start() 
        except KeyboardInterrupt: 
         tornado.ioloop.IOLoop.instance().stop() 
         logging.info("Stopping servers.") 
    

Это может быть легко преобразован в два сервера экземпляры, работающие на два разных портов, с 80 зарезервирован для Django и 8080 используются для обработчика загрузки.

  1. Я рекомендую Tornado, поскольку он поддерживает потоковое тело запроса, и очень хорошо подходят для этого типа Here's a gist that might help you.

  2. Ваш прокси-сервер будет иметь значение. Если вы используете NGINX, убедитесь, что вы отключили proxy_buffering.

  3. Я бы не использовал базу данных для проверки билетов/загрузки. Redis или memcache, вероятно, были бы намного более быстрым способом справиться с этим. Кэш-память также будет отличным способом для басов загрузки вперед и назад между Django и Tornado, поскольку накладные расходы для установки/получения нового значения будут настолько малы.

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

+0

Включен ли Tornado в этот потоковый запрос? Похоже, что код, упомянутый в Gist, фактически использует вилку Tornado, которая не может быть передана обратно в основное репо. –

+0

Не уверен на 100%. Возможно, вам придется разветвить его и применить патч к своей вилке. Не огромная сделка. –

+0

Помогло ли это вам в правильном направлении? –

Смежные вопросы