воскресенье, 6 августа 2017 г.

Bottle - полный веб-стек без Django

Перевод: Bottle, full stack without Django
Автор: Тьяго Авелино (Thiago Avelino)

Эта заметка в блоге основана на лекции, которую я прочитал здесь, в Бразилии. Посмотрите слайды!

Веб-микрофреймворк Bottle

Bottle - это веб-микрофреймворк, совместимый с WSGI, который зависит только от стандартной библиотеки Python и совместим с Python версий 2.6, 2.7, 3.2, 3.3 и 3.4. Весь исходный текст фреймворка умещается в одном файле. Он был создан Марселем Хеллкэмпом (Marcel Hellkamp - @defnull) и поддерживается сообществом, образовавшимся вокруг этого фреймворка.

Django - это прагматичный фреймворк для быстрой веб-разработки, который написан на Python, использует стандарт MTV (model-template-view - модель-шаблон-представление). Изначально он был создан как система для управления сайтом журнала в городе Лоуренс, в Канзасе. Стал проектом с открытым исходным кодом, был опубликован под лицензией BSD в 2005 году. Название Django фреймворк получил в честь джазового музыканта Джанго Рейнхардта. Django стал очень известен благодаря поставке с "батарейкам", то есть благодаря нескольким библиотекам, добавленным к основному коду фреймворка для упрощения разработки. Вместе с фреймворком эти библиотеки сформировали так называемый "полный стек".

Прагматичный - значит ориентированный на решение практических, реальных задач с чётко определённой целью. Другими словами, команда разработчиков Django приняла некоторые архитектурные решения, а пользователи Django следуют этой архитектуре, не имея возможности легко её поменять.

Хорошо ли, если вместе с веб-фреймворком поставляются "батарейки"? Если вы согласны использовать всё, что даёт вам фреймворк, то ответ - да. Однако, не все веб-проекты одинаковы.

В большинстве проектов используется не более 80% возможностей Django. В тех случаях, когда используется не более 50% возможностей, мы вынуждены платить за все, что было предусмотрено архитектурой Django. То есть теряем в производительности, потому что в Django имеется множество модулей, которые не используются, но по-прежнему продолжают работать. Когда же мы используем микрофреймворк, мы берём на себя роль архитектора приложения. Поскольку у нас нет предопределённой архитектуры, нам нужно время, чтобы определить архитектуру приложения.

Все пакеты Python, которые имеются в библиотеке Django, в микрофреймворке могут быть заменены!

SQLAlchemy

SQLAlchemy существовал до Django (да, до Django) и начиная с 2005 года появилась команда, которая стала заниматься разработкой ORM. Команда же разработчиков Django занимается одновременно и разработкой фреймворка и разработкой ORM. Я думаю, что не стоит говорить о том, что результат работы специалистов обычно бывает лучше, чем результат работы универсалов.

Структура модели:
class Entity(Base):
    __tablename__ = 'entity'
    id = Column(Integer, Sequence('id_seq'), primary_key=True)
    name = Column(String(50))

    def __init__(self, name):
        self.name = name

    def __repr__(self):
        return "<Entity('%d', '%s')>" % (self.id, self.name)

WTForms

Обходное решение для тех, кто не использует Django и кому нужно работать с формами - это WTForms, которые были созданы в 2008 году и поддержка которых продолжается до сих пор!

Структура формы:
class UserForm(Form):
    name = TextField(validators=[DataRequired(), Length(max=100)])
    email = TextField(validators=[DataRequired(), Length(max=255)])

Шаблонизатор

Jinja2 - это современный удобный для дизайнеров язык шаблонизации для Python, который был создан по образцу шаблонов Django. Он быстрый, широко используется и может быть дополнительно защищён изоляцией рабочего окружения.

Структура шаблона:
<title>{% block title %}{% endblock %}</title>
<ul>
{% for user in users %}
  <li><a href="{{ user.url }}">{{ user.username }}</a></li>
{% endfor %}
</ul>

Миграция

Использование Alembic начинается с создания среды миграции. Это каталог сценариев, которые относятся к отдельному приложению. Среда миграции создаётся единожды, а затем поддерживается совместно с исходным кодом самого приложения.

Структура миграции:
revision = '1975ea83b712'
down_revision = None

from alembic import op
import sqlalchemy as sa

def upgrade():
    pass

def downgrade():
    pass
Как создать обновление и откат:
def upgrade():
    op.create_table(
        'account',
        sa.Column('id', sa.Integer, primary_key=True),
        sa.Column('name', sa.String(50), nullable=False),
        sa.Column('description', sa.Unicode(200)),
    )

def downgrade():
    op.drop_table('account')
Структура модификации таблицы:
"""
$ alembic revision -m "Add a column"
"""

revision = 'ae1027a6acf'
down_revision = '1975ea83b712'

from alembic import op
import sqlalchemy as sa

def upgrade():
    op.add_column('account', sa.Column('last_transaction_date', sa.DateTime))

def downgrade():
    op.drop_column('account', 'last_transaction_date')

Заключение

Здесь было продемонстрировано всё, что можно найти в стеке Django. Я писал эту заметку для не для того, чтобы принизить Django. Я лишь показал, что существуют другие полностековые решения для разработки приложений. Многие люди используют Django, не понимая экосистемы Python. В наше время Django предоставляет множество готовых решений, что заставляет некоторых разработчиков лениться и не наращивать мастерство в проектировании архитектуры приложения.

Помогайте Bottle. Мы - растущее сообщество. Чтобы внести свой вклад в код Bottle, обратитесь к списку открытых задач. В случае сомнений можно обратиться в список рассылки или в IRC-канал.

ПРИСОЕДИНЯЙТЕСЬ

Примечания переводчика:
Считаю, что в статье тема не раскрыта. Не понятно, какая такая особенная архитектура приложения имелась в виду,
которая никак не сочетается с Django. Перечислено несколько средств, которые в чём-то заменяют средства, имеющиеся в Django. Без сомнений, SQLAlchemy заткнёт за пояс джанговский ORM. Безусловно, Jinja2 - очень быстрый шаблонизатор, быстрее джанговского. Но стоит иметь в виду, что в Django все эти средства глубоко интегрированы друг с другом.

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

Другой пример - в Django миграции можно сгенерировать автоматически. Автоматическая генерация даже умеет определять переименованные поля. А если же автоматика не сработала корректно, то автоматически сгенерированный код миграции можно подправить и руками.

Наконец, в комплекте с Django имеется административный интерфейс, для которого можно определять собственные классы для редактирования таблиц. В большинстве случаев этот административный интерфейс позволяет сэкономить время на создании шаблонов и написании представлений для просмотра и редактирования таблиц. Да, его возможности ограничены, но ведь в комплекте с Bottle ничего подобного нет, а если и есть в сторонних модулях, то наверняка такие модули тоже окажутся недостаточно интегрированными с ORM или модулем форм - придётся писать дополнительный код, который предоставит необходимую информацию этому модулю.

Я сам в своих проектах использую Django, но для некоторых задач он действительно избыточен. Например, в одной из прошлых своих заметок я писал Тайловый сервер на основе Python, Mapnik и Bottle. Денис Рыков, материалами которого я воспользовался, тоже писал тайловый сервер, воспользовавшись фреймворком Bottle. Для себя я решил, что если приложение не работает с собственной базой данных, а берёт информацию из сторонних источников и занимается лишь её преобразованием, или выполняет какие-то действия по требованию, то лучше использовать Bottle, т.к. в нём нет избыточных возможностей, а сам он обладает минимумом зависимостей и работает с любой версией Python.

4 комментария:

GhostKU комментирует...

Почему Bottle а не Flask?

Вадим комментирует...

Почему bottle, а не, скажем, flask? В статье только критика Django.

morbo комментирует...

Bottle - самостоятельный фреймворк в одном файле, который не имеет жёстких зависимостей от библиотек, не входящих в стандартную поставку Python.

Flask располагается в нескольких файлах и зависит от библиотеки Werkzeug.

Bottle легче, имеет меньше зависимостей, приложения с его использованием проще распространять, т.к. к веб-приложению можно добавить всего один файл - bottle.py и запускать его везде, где есть Python.

У Flask больше готовых модулей и, видимо, лучше поддержка сообщества.

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

morbo комментирует...

Критики Django в статье нет. В статье только говорят, что для некоторых задач она излишняя.