Публикации Лето, мобильный офис и коворкинг Терминологические конфликты во взаимотношениях с клиентом

PyJamas - питон компилируемый в JS

Андрей Орлов  2009-06-04 21:46

Некоторое время назад появился интересный проект PyJamas. PyJamas - это компилятор питона в javascript, благодаря которому можно написать клиентскую часть приложения на питоне, скомпилировать его, и полученный код на HTML,CSS и JS можно закгрузить для работы в любой браузер, понимающий JavaScript.

PyJamas: питон компилируемый в JS

PyJamas: питон компилируемый в JS

PyJamas - это средство, позволяющее веб-программисту писать страницы на любимом языке программирования (python), компилировать их в JavaScript и запускать его в любом современном браузере (Mozilla, Old Mozilla (Netscape), IE, Safari and Opera) не задумываясь о совместимости.

Приложения на PyJamas

PyJamas выполняет компиляцию Python в JavaScript, поэтому питонисту при создании приложения для PyJamas требуется знаний HTML/CSS/JS не больше, чем программисту на C - знания ассемблера. Возможность писать JS непосредственно существует, но без нее можно обойтись. PyJamas предоставляет библиотеку классов, позволяющую задать внешний вид и поведение пользовательского интерфейса созданием экземпляров классов и заданием их свойств, связей и методов.

Рассмотрим пример реализации простого пользовательского интерфейса:

from pyjamas.ui.SimplePanel import SimplePanel
from pyjamas.ui.VerticalPanel import VerticalPanel
from labeledpanel import LabeledPanel

class Statistic(SimplePanel) :

    def __init__(self,query,count,engrank,rusrank) :
        SimplePanel.__init__(self)
        v = VerticalPanel()
        v.setWidth("100%")
        v.setBorderWidth("1px")
        v.add(LabeledPanel("Оценка, английский:",engrank))
        v.add(LabeledPanel("Оценка, русский:",rusrank))
        v.add(LabeledPanel("Предъявлений:",count))
        v.add(LabeledPanel("Длина выборки:",query))
        self.add(v)

Здесь используется элемент оформления VerticalPanel, в который добавляются четыре элемента вывода LabeledPanel, снабженных названием и переменной. При запуске приложения появится панель, разделенная на четыре строки, в каждой из которых выводится название и значение переменной:

screenshot_dl_pjstat.jpg/smartimagecontainer/article/get

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

Такой код похож на программирование генератора кода для веб при помощи специальных библиотек. Само по себе это не ново и известно, как минимум, начиная с perl::CGI, а уж в zope.app.form и в zope.interface имеет более чем совершенный вид. То, что PyJamas позволяет вместо многослойных разрозненных кодов на HTML/CSS/JS писать код на Python удобно, но не ново. Главное достоинство PyJamas в том, что это не библиотека, а компилятор. Поэтому не только декларации элементов веб-интерфейса, но и сложное поведение веб-приложения, вычисления и обработку данных в нем можно реализовать используя развитые средства программирования языка Python.

В качестве примера, посмотрим фрагмент кода, реализующий алгоритм смешения очереди:

class Query :

    def __init__(self) :
         self.q = []
         self.farq = []

    def shuffle(self) :
         key,translate,weight = self.q[0]
         del self.q[0]
         idx = int(random()*weight + 1)
         if idx <= len(self.q) :
             self.q.insert(idx,[key,translate,weight])
         else :
             self.farq.append([key,translate,weight])

         if len(self.q) == 0:
             self.sync()

             self.q = self.farq
             self.farq = []

Это обычный питоновский код, который после компиляции превращается в JavaScript, фрагмент которого (функция инициализации) приведен ниже:

sample.__Query.__initialize__ = function () {
    if(sample.__Query.__was_initialized__) return;
    sample.__Query.__was_initialized__ = true;
    pyjs_extend(sample.__Query, pyjslib.__Object);
    sample.__Query.prototype.__class__.__new__ = sample.Query;
    sample.__Query.prototype.__class__.__name__ = 'Query';
    sample.__Query.prototype.__init__ = function() {
    this.q = new pyjslib.List([]);
    this.farq = new pyjslib.List([]);
    };

Компиляция позволяет приложениям на PyJamas грузятся в любой современный браузер и работать в нем. Десятки работающих примеров таких приложений представлены на сайте PyJamas [2] вместе с примерами их кода.

Но и этим PyJamas не ограничивается: дополнительное расширение, PyJamas-Desktop [5], позволяет запускать приложения для PyJamas как десктопные, вообще без какого-либо браузера.

Одностраничное приложение

Среди примеров [2] можно увидеть веб-приложение, реализующее почтовый клиент, напоминающий обычные IMAP-клиенты:

mailsample.jpg/smartimagecontainer/article/get

Конечно, таких продвинутых веб-интерфейсов, совсем не похожих на HTML-странички, можно было добиться и раньше, даже на голом HTML. Но PyJamas ориентирован на создание "одностраничных приложений". Такое приложение полностью загружается при первом обращении к странице вместе со всеми элементами оформления, а нажатие на кнопки и ссылки вызывает только загрузку дополнительных данных (не обязательно полностью оформленных страниц) или вообще оффлайновую обработку. Такое приложение, в сущности, клиент специального сетевого сервиса, взаимодействующий с ним поверх HTTP.

Работая с сервером, приложение на PyJamas может считывать статические данные (страницы) или использовать вызов удаленных процедур посредством JSONRPC (или XMLRPC).

Пример приложения, работающего со статическими данными, можно посмотреть на сайте PyJamas: это BookReader - приложение, позволяющего читать PyJamas Book. PyJamas Book написана на простом варианте структурированого текста и не содержит ни строчки HTML-разметки. BookReader загружает индекс страниц, а затем, по мере надобности, и сами страницы, выполняя разметку и отображение уже на стороне клиента. Такой подход позволяет создать интерактивный сайт на самом дешевом хостинге. вообще без какого-либо движка.

А вот использование JSONRPC требуют специальным образом написанной серверной части, но существует много готовых библиотек ([8], [9], [10]), чтобы ее реализовать.

Опыт использования

Недавно мне потребовалось написать простое приложение на JS. Несколько дней ушло на борьбу за совместимость с разными браузерами и измышления такого алгоритма работы, который уложился бы в возможности этого языка без серьезных проблем. Получилось убого выглядящее, хотя и прилично работающее приложение, которое работает во "всех браузерах" (правда, я не имел возможности проверить его под Safari):

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

screenshot_dl_pj.jpg/smartimagecontainer/article/get

Основной проблемой стало изучение отсутствующей документации и легкая несовместимость python & pyjamas (об этом ниже). Несколько часов против нескольких дней это уже ощутимый выигрыш, да и добавление меню и трех форм тоску больше не навевает. Дополнительный бонус: я думаю, что оно работает на Safari, хотя и не проверял это.

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

Плюсы и минусы

Даже при небольшом опыте программирования на PyJamas становится ясно, что это не питон, а его подмножество: не все конструкции питона работают, а другие работают не совсем корректно. Изучение кода PyJamas показало, что существенное улучшение совместимости - вопрос времени. Тем, кто решит попробовать писать на pyjamas, будет полезен список заметных проблем:

  • Не все встроенные функции (map, zip, reduce, filter) есть и корректно работают;
  • Не доступны библиотеки питона :), в том числе такие, которые могли бы существовать: random, regexp (их можно отобразить на JS);
  • Странности с видимостью глобальных имен, которые не всегда оказываются видны;
  • Легкая несовместимость в поведении классов (скажем, перекрыть __setattr__ мне не удалось);
  • Имеет место несоответствие типов, что заметно даже для int.

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

Что касается предлагаемых PyJamas элементов пользовательского интерфейса и манеры его написания - то это, конечно, некий прорыв по сравнению с тем, что приходится переносить при реализации на чистом HTML/CSS. Тем не менее, если сравнивать с другими инструментами генерации веб-интерфейсов, такими как zope.app.form или ZPT, то придется отметить, что жесткое кодирования веб-интерфейса внутри кода приложения - это ощутимый шаг назад. Даже возможность раскрасить этот интерфейс при помощи CSS не приносит особой пользы: PyJamas использует табличный стиль верстки, в котором CSS не слишком спасает. Сравнение PyJamas с другими библиотеками GUI также неоднозначно: авторы напирают на преимущество HTML-ориентированности PyJamas, и сравнивают его с PyQT. Я сравню с Tck/Tk (это мой любимый GUI): модель отображения HTML/CSS вообще недостойна упоминания рядом с Tck/Tk, а PyJamas полностью наследует это убожество.

Значение

Веб начал свое развитие со статического HTML, который был интуитивно понятен новичкам и поэтому смог быстро распространится. Дальнейшее развитие привело к динамическим страницам, создаваемым под нужды индивидуального пользователя. По мере того, как алгоритмы динамической адаптации контента развивались, требовались все более мощные вычислительные сервера и все более толстые каналы связи. Постепенно появлялись сервера приложений и системы управления контентом, решающие распространенные задачи. Каждое из таких решений (Plone, Wordpress, Joomla или даже моя собственная CMS DreamBot) используется на множестве сайтов, отличие между которыми - только скин, тонкая прослойка графического представления, созданная под конкретный сайт. Все программное взаимодействие внутри системы идентично для всех сайтов, сделанных на ее основе: скины можно переставлять между разными сайтами. Но не смотря на такую свободу, выбор скина всегда остается за владельцем сайта.

web-evolution.jpg/smartimagecontainer/article/get

В тоже самое время наблюдалась и иная тенденция развития: чем более сложными и нагруженными становились сервера, чем большая толщина канала требовалось для быстрого отклика пользовательских приложений, тем большую часть вычислений пытались перенести с сервера на клиент. Основной способ добиться этого - создание HTML со встроенными обработчиками событий, реализованных на JS. Его развитие в конце концов и привело к концепции "одностраничного приложения", которое загружает контент с сервера по мере надобности. PyJamas отражает и развивает эту тенденцию, делая еще один, почти незаметный, шаг: одностраничное приложение пишется не на каком-то специализированном языке, а на языке общего назначения с использованием среды, понятной люблому прикладнику, пишущему десктопные приложения.

И в этот момент происходит прыжок в будущее: появляется PyJamas-Desktop [5], который позволяет не только написать веб-интерфейс как десктопное приложение, но и использовать его так же: вне какого-либо браузера, как обычный клиент сетевого сервиса.

Как было сказано выше, протокол взаимодействия внутри любой CMS (или иной веб-службы) стандартизован в достаточной степени для свободной смены слоя представления (скина). Если роль слоя представления отводится одностраничному приложению, написанному на PyJamas, то стоит пересобрать его с PyJamas-Desktop и превратить в десктопное приложение, как пользователи сайтов смогут выбирать более удобный "скин" для работы. Если такое шаг будет сделан, то это действительно переворот в веб-технологиях: владелец сайта лишается возможности и потребности быть капризным ребенком, изобретающим "более представительный скин", приводящий в ступор посетителей. Посетитель будет сам выбирать более удобный и привычный веб-интерфейс для работы с сетевым сервисом: в сущности, это действительно его право и потребность.

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

Ссылки

Для более подробного знакомства с PyJamas и связанными с ним технологиями будут полезны несколько ссылок:

[1] Сайт PyJamas;
[2](1, 2) Подборка примеров, Kitchen Sink;
[3] Книга про PyJamas, реализованная на PyJamas;
[4] Google Web Toolkit - предшественник и основа PyJamas;
[5](1, 2) PyJamas-Desktop - запуск приложений на PyJamas как десктопных;
[6] WebKit
[7] Pyjamas - Python Applications for Desktop and Web на Advogato;
[8]XMLRPC сервер
[9] Web.py - простейшая среда для разработки вебсерверов;
[10] Библиотека JSONRPC для Web.Py;
[11] Слайды, представленные на конференции в Омске.
[12] О скорости pyjamas (pyv8)
DreamBot Zope3 Учат тут Нейросети Репозиторий Слив! Статистика Редакторам Мобильный блог
Официальный сайт Zope3 Московская группа изучения реактивного движения The Dream Bot Site nooxml Сайт посуточной аренды квартир в москве