воскресенье, 18 августа 2013 г.

WSGI - приложения

WSGI - приложения

Вот пример простейшего WSGI приложения:

def MyApplication(environ, start_response):
     start_response('200 OK', [('Content-type', 'text/plain')])
     yield "Hello, world!"

Помимо yield можно делать return(это основной способ) и print(если позволяет веб-сервер). Обратите внимание, что Apache mod_wsgi запрещает использовать поток вывода, поэтому любая попытка сделать print будет приводить к ошибке.




Давайте теперь разберём по порядку.
Первое, что делает наше приложение, это start_response - эта функция сообщает веб-серверу статус и http-заголовки. Загоовки передаются в виде массива, каждый элемент которого представляет из себя tuple с двумя полями. Первое поле - название заголовка, второе - значение. Соответсвенно, так же передаются и куки.

Затем, мы возвращает результат веб-серверу. Делается это с помощью yield или return. Главное, чтобы возвращаемый объект был итератором. Т.е. вы можете сами определить возвращаемый объект, но как правило используются простые массивы.


Как сделать выдачу в реальном времени
Допустим, на вашем сайте есть такие страницы, расчёт выдачи которых занимает много времени, но вы не хотите заставлять пользователя смотреть в пустую страницу, пока идёт обработка запроса. Для сглаживания таких моментов можно применить следующий способ:
  • Определяете свой собственный класс, делаете этот класс итератором, т.е. определяете методы __iter__() и next()
  • Метод next() переопределяете таким образом, что в нём будет происходить вся обработка запроса. Результаты обработки возвращаются с помощью yield.
Допустим, вы хотите вернуть шапку вашего сайта, тогда вы делаете yield "html-текст вашей шапки" а затем вы обрабатываете запрос дальше и следующий ответ снова выводите через yield.


Пример
Вот простой пример, как сделать выдачу в реальном времени.

class Response()
    def __iter__(self):
        return self
    def next(self):
        "тут начинаем обработку запроса"
        "когда нам уже есть что показать, отдаём ответ"
        yield "Hello"
        "Продолжаем обрабатывать запрос"
        "Допустим, делаем какие-то ресурсоёмкие операции"
        "Когда нам снова есть что отдавать, отдаём"
        yield "World"
        "Ну, теперь мы можем выводит остальную часть страницы"
        yield "!!!"
        "Чтобы остановить итерацию, надо вызвать исключение"
        raise StopIteration

Само WSGI-приложение теперь будет выглядеть вот так:

def Application(environ,start_response):
    answer=Response()
    start_response('200 OK',[("Content-type","text/html")])
    return answer

IT-записки

comments powered by Disqus