Версия 8 от 2011-03-30 13:06:31

Убрать это сообщение

Bottle

Bottle - это быстрый, простой и легкий WSGI микро веб-фреймворк для Python. Он распространяется в виде одного файла-модуля и не имеет никаких зависимостей, кроме стандартной библиотеки Python.

Оригинальный документ

Учебник: Приложение Список-Задач

Этот учебник краткое введение в WSGI фреймфорк Bottle. Основной целью является то, что после прочтения этого учебника вы сможете создавать проекты использующие Bottle. В этом документе, будут рассмотрены не все возможности , но по крайней мере, основные и важные, такие, как маршрутизация, использование Bottle шаблонов для форматирования вывода и обработка GET / POST параметров.

Для понимания изложенного здесь материала не обязательно иметь базовые знания о WSGI, т.к. Bottle пытается скрыть механизмы работы WSGI от пользователя. Вы должны иметь чёткое понимание языка программирования Python . Кроме того, примеры используемые в учебнике извлекают и хранят данные в базе данных SQL, так что основные сведения о SQL помогут, но не являются ключевыми для понимания концепции Bottle. В некоторых примерах Bottle отправляет выходные данные браузеру отформатированными при помощи HTML. Таким образом, общее представление об HTML тегах будет полезным.

Во введении в Bottle, промежуточный код на Python максимально короткий для сохранения понимания. Кроме того, весь учебный код работает нормально, но не стоит его использовать его в "сыром" виде на общедоступном веб-сервере. Для того, его использовать лучше добавить например, больше обработок ошибок, защитить базу данных с помощью пароля, проверок и ошибок ввода т.д.

Цели

В конце этого учебника мы получим простое веб-ориентированный Список-Задач. Список представляет собой для каждой записи текст( максимум 100 символов) и статус (0 для выполненного, 1 для открытой). Через веб-ориентированный интерфейс пользователь может открыть запись для просмотра, редактирования или добавить новую запись.

В время разработки, все страницы будут доступны только локально, но в дальнейшем будет показано как адаптировать приложение для "реального" сервера, включая использование с Apache’s mod_wsgi.

Bottle будет делать маршрутизацию и форматирование вывода, при помощи шаблонов. Элементы списка будут храниться в базе данных SQLite. Чтение и запись в / из базы данных будет осуществляться с помощью кода на Python.

В итоге мы будем иметь приложение со следующими страницами и функциональными возможностями:

• Стартовая страница http://localhost:8080/todo

• Добавление новых элементов в список: http://localhost:8080/new

• Страница для редактирования элементов: http://localhost:8080/edit/:no

• Проверки данных, заданных динамическими маршрутами с @validate в качестве декоратора

• Определять ошибки

Прежде чем мы начнём ...

Установка Bottle

Предположим, что у вас установлен Python (версия 2.5 или выше) и все, что вам нужно это установить Bottle в дополнение к этому. Bottle не имеет других зависимостей, кроме самого Python.

Вы можете установить Bottle вручную или использовать easy_install от Python: easy_install bottle

Программное обеспечение которое понадобится в дальнейшем

Так как мы используем SQLite3 в качестве базы данных, убедитесь, что он установлен. В системах Linux, большинство дистрибутивов имеют SQLite3 установленным по умолчанию. SQLite также доступен для Windows and MacOS X .

Кроме того, необходим Pysqlite, модуль Python для доступа к базам данных SQLite. Опять же, во многих дистрибутивах Linux предустановлен этот модуль (их часто называют "Python-sqlite3"), в противном случае можно просто установить вручную или через easy_install pysqlite .

Примечание: Многие старые системы имеют предустановленным sqlite2 . Все примеры тоже будут корректно работать с этой версией. Вам просто нужно импортировать соответствующий модуль Python под названием "SQLite" вместо "sqlite3", как оно используется в примерах ниже.

Создание базы данных SQL

Во-первых, мы должны создать базу данных, мы используем её в дальнейшем. Для этого запустите SQLite с помощью команды sqlite3 todo.db . Это позволит создать пустую базу данных под названием "todo.sql" и вы увидите приглашение SQLite , которое может выглядеть следующим образом: sqlite> . Прямо здесь, ввести следующие команды:

CREATE TABLE todo (id int PRIMARY KEY, task char(100) NOT NULL, status bool NOT NULL);
INSERT INTO todo (task,status) VALUES ('Read A-byte-of-python to get a good introduction into Python',0);
INSERT INTO todo (task,status) VALUES ('Visit the Python website',1);
INSERT INTO todo (task,status) VALUES ('Test various editors for and check the syntax highlighting',1);
INSERT INTO todo (task,status) VALUES ('Choose your favorite WSGI-Framework',0);

Первая строка создаёт таблицу которая называется "todo" с тремя столбцами "id", "task" и "status". "id" является уникальным идентификатором для каждой строки, который используется в дальнейшем для обращения к строкам. В графе "task" хранится текст, который описывает задачу, он может быть не более 100 символов. Наконец, колонка "status" используется для обозначения задачи как открыта (значение 1) или закрыта (значение 0).

Использование Bottle для веб-приложения Список-Задач (ToDo)

Теперь настало время применить Bottle с целью создания веб-приложения. Но во-первых, мы должны рассмотреть основную концепцию Bottle: маршруты.

Понимание маршрутов

В принципе, каждая страница отображается в браузере после динамической генерации когда вызывается адрес страницы. Таким образом, нет статического контента. Это именно то, что называется "route" в Bottle: некий адрес на сервере. Так, например, когда страница http://localhost:8080/todo вызывается из браузера, Bottle "перехватывает" вызов и проверяет, есть ли (Python) функция, определённая для маршрута(route) "todo". Если да, то Bottle будет выполнять соответствующий код Python и возвращает результат.

Первый шаг - Отображение всех открытых задач

Таким образом, после понимания концепции маршрутов, давайте создадим один первый. Цель состоит в том, чтобы увидеть все открытые элементы из Списка-Заданий(ToDo):

import sqlite3
from bottle import route, run

@route('/todo')
def todo_list():
    conn = sqlite3.connect('todo.db')
    c = conn.cursor()
    c.execute("SELECT id, task FROM todo WHERE status LIKE '1'")
    result = c.fetchall()
    return str(result)

run()

Сохраните код "todo.py", предпочтительно в той же папке где и файл "todo.db". В противном случае, вам необходимо добавить путь к "todo.db" в параметрах sqlite3.connect().

Давайте посмотрим, что мы только что сделали: мы импортировали необходимый модуль "sqlite3" для доступа к базе данных SQLite и из Bottle мы импортировали "route" и "run". Оператор run() просто запускает веб-сервер находящийся в Bottle. По умолчанию веб-сервер обслуживает страницы на localhost и порту 8080. Кроме того, мы импортировали "route", функцию которая отвечает в Bottle за маршрутизацию. Как вы можете видеть, мы определили одну функцию " todo_list ()", с несколькими строками кода чтения из базы данных. Важным моментом является определение декоратора @route('/todo') непосредственно перед определением def todo_list(). Делая это, мы связываем эту функцию с маршрутом "/todo", так что каждый раз, когда браузер вызывает http://localhost:8080/todo , Bottle возвращает результат функции "todo_list ()". Так работает маршрутизации внутри Bottle.

На самом деле вы можете к функции связать более чем один маршрут.

Так следующий код

...
@route('/todo')
@route('/my_todo_list')
def todo_list():
...

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

То, что вы увидите в браузере является данными которые описаны в параметрах return. В этом примере, мы должны преобразовать "result" в строку через функцию str() , т.к. Bottle ожидает строку или список строк в параметрах оператора return. Но здесь, в результате запроса к базе данных возвращается список кортежей, который является стандартом определеным в Python DB API .

Теперь, после понимания немного скрипта выше , настало время исполнить его и посмотреть результат самостоятельно. Помните о том, что в Linux-/ Unix подобных системах сначала файл "todo.py" необходимо сделать исполняемым . После этого достаточно просто запустить python todo.py и открыть страницу http://localhost:8080/todo в вашем браузере. Если Вы не ошиблись в написании скрипта, результат должен выглядеть следующим образом:

[(2, u'Visit the Python website'), (3, u'Test various editors for and check the syntax highlighting')]

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

На самом деле, будет не очень интересно и не приятно читать вывод . Это сырой результат возвращённый SQL-запросом.

Таким образом, в следующем шаге мы красивым способом отформатируем вывод . Но прежде, чем мы это делаем, мы делаем нашу жизнь легче.

Отладка и Авто-Обновление

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

from bottle import run, route, debug
...
#add this at the very end:
debug(True)
run()

При включении "debug", вы получите полную трассировку стека интерпретатора Python, который обычно содержит полезную информацию для поиска ошибок. Кроме того, шаблоны (см. ниже) не будут кэшироваться, таким образом, изменения в шаблон вступит в силу без остановки сервера.

Обратите внимание, что опция debug(True) должна быть использована только при разработке, не должны использоваться в рабочей обстановке.

Дальнейшей полезным свойством является автоматическая перезагрузка, которая может быть включена по изменению параметров run()

run(reloader=True)

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

Опять же, в основном предполагается использовать функцию при разработке, а не на рабочих системах.