Разработка простейших веб-приложений на языке Python.

Python Package Index

Python Package Index (PyPI) - общественная база пакетов для Python. Она используется разработчиками, когда им требуется модуль или библиотека модулей, реализующие определённый функционал. Сайт PyPI позволяет искать модули по ключевым словам и описанию. Для установки нужного пакета необходимо вызвать Python со встроенным модулем pip в качестве точки входа:

python -m pip install somepackage

После успешной установки, модули пакета становятся доступны для импорта в программе.

Рассмотрим другие подкоманды утилиты pip:

Виртуальные среды Python

Пакеты, размещаемые на PyPI редко бывают самодостаточными. Чаще всего, пакет использует модули других пакетов, которые называют зависимостями. Команда pip install вычисляет зависимости устанавливаемого пакета, и устанавливает их вместе с запрашиваемым пакетом.

Беспорядочная установка пакетов может привести систему в состояние, называемое “адом зависимостей” (англ. dependency hell). Примером такого состояния может служить ситуация, когда пакет A зависит от библиотеки L версии 1.0, а пакет B - от той же библиотеки версии 2.0. Это означает, установить одновременно A и B не представляется возможным, т.к. pip не позволяет устанавливать один и тот же пакет разных версий.

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

Создание виртуальной среды осуществляется с помощью модуля venv:

python -m venv my_virtual_env

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

Для того чтобы войти в виртуальную среду (активировать её) требуется запустить сценарий, соответствующий используемому командному интерпретатору:

После активации все последующие вызовы команды pip install будут устанавливать пакеты в директорию виртуальной среды.

Для деактивации текущей виртуальной среды достаточно ввести deactivate или же просто закрыть окно командного интерпретатора.

Понятие о веб-приложениях

Веб-приложением (англ. web application) называется программа, характеризующаяся следующими свойствами:

Код HTML, CSS и JavaScript относится к клиентской части.

Серверная часть может быть написана на любом языке программирования общего назначения: Python, C#, C++, PHP и др.

Пользователь взаимодействует с веб-приложением с помощью другой программы, называемой браузером. На сегодняшний день популярными браузерами являются Mozilla Firefox и Google Chrome. Задачами браузера являются отрисовка (англ. rendering) кода HTML и CSS, и исполнение кода JavaScript.

Для выполнения этой лабораторной работы не требуется глубокого понимания протокола HTTP, а так же знания языков CSS и JavaScript, поэтому здесь эти технологии рассматриваться не будут.

Основы языка разметки HTML

HTML является декларативным языком. Это означает, что код HTML нельзя запустить и выполнить, подобно тому как запускается код на Python. Вместо этого HTML загружается в браузер, который производит его отрисовку, т.е. заменяет конструкции языка на соответствующие им графические объекты.

HTML-страницу можно создать с помощью текстового редактора, сохранив файл с расширением .html.

Основными синтаксическими конструкциями HTML являются:

Тегом (англ. tag) называется конструкция вида <tag> или <tag>...</tag>. В первом случае тег называется одиночным, во втором - парным. Парные теги могут содержать внутри себя другие теги или же просто текст.

Каждый тег имеет ряд стандартных и нестандартных атрибутов. Атрибуты в HTML-коде указываются в следующем виде: <тег атрибут=значение>.

Стандарт HTML определяет множество различных тегов и атрибутов, описание которых можно найти в сети, например на сайте htmlbook.ru. В этой работе мы рассмотрим лишь самые необходимые из них:

В качестве примера приведём небольшой HTML-документ, использующий перечисленные выше теги:

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>

<body>

<b>Правила участия в конференции</b>
<ol>
  <li>Объём статьи - не более <i>5 страниц</i>.</li>
  <li>Язык публикаций - <i>русский</i>, <i>английский</i>.</li>
  <li>Выступающие - студенты и преподаватели <i>российских ВУЗов</i>.</li>
</ol>
<hr>

<b>Список участников конференции</b>
<table>
<tr>
  <td>Ф.И.О.</td>
  <td>Аффилиация</td>
  <td>Название публикации</td>
</tr>
<tr>
  <td>Попов Глеб Александрович</td>
  <td>Волгоградский Государственный Университет</td>
  <td>Подходы к незаметному употреблению пива на рабочем месте</td>
</tr>
<tr>
  <td>Афанасьев Анатолий Михайлович</td>
  <td>Волгоградский Государственный Университет</td>
  <td>Проблемы цветопередачи веб-камер в условиях повышенного радиационного фона</td>
</tr>
</table>
<hr>

</body>
</html>

Содержимое тега <head></head> необходимо для корректного отображения русского текста.

Элементы управления HTML для взаимодействия с пользователем

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

Тег <form></form> объявляет форму - группу элементов управления, данные с которых будут отправляться на сервер вместе. Атрибут method задаёт способ отправки информации. Не вдаваясь, пока, в подробное их описание, отметим, что для большинства форм используется method="POST". Внутри формы можно использовать следующие теги:

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

Дополним HTML-страницу из примера выше формой для добавления участника конференции. Для этого, после тега <hr> допишем следующий код:

<b>Добавление участника</b>
<form method="POST">
<p>Ф.И.О. <input type="text" name="fio"></p>
<p>Подтверждаю, что мне есть 18 лет<input type="checkbox" name="age"></p>
<p>
Список статей, по одной на каждую строку:
<textarea rows="5" cols="55" name="papers"></textarea>
</p>
<input type="submit" value="Добавить">
</form>
<hr>

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

Программный каркас Flask

Flask - минималистичный программный каркас (англ. framework) для построения веб-приложений на языке Python. Приложение, написанное с использованием Flask, играет роль веб-сервера, т.е. программы, в задачи которой входит обработка запросов пользователей. В простейшем случае, клиент запрашивает некоторый ресурс (HTML-страницу, картинку и т.д.), который и возвращается сервером. В более сложных случаях веб-сервер производит дополнительные операции - доступ к базе данных, файловой системе, каким-либо службам.

Рассмотрим код простейшего Flask-приложения, которое выводит сообщение “Hello world” в браузер пользователя:

# импорт класса Flask из модуля flask
from flask import Flask

# создание объекта Flask, который будет представлять приложение
app = Flask(__name__)

# объявление функции-обработчика
@app.route("/")
def hello_world():
    return '''
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<p>Hello world</p>
</body>
</html>
'''

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

Декоратором в Python называется синтаксический сахар, позволяющий модифицирвоать поведение объекта класса или функции другой функцией. Декораторы могут применяться для различных целей. Во Flask они связывают адрес ресурса (URL) и соответствующую ему функцию-разработчик. Например, чтобы добавить ещё одну статичную страницу в веб-приложение по адресу /page2, нужно дописать следующий код:

@app.route("/page2")
def page_handler():
    return "<p>Это вторая страница</p>"

Чтобы запустить приложение, используется следующая команда:

flask --app myapp run

В этой команде аргумент --app принимает имя запускаемого приложения, т.е. имя файла с кодом без расширения .py. Выполнение данной команды приведёт к запуску веб-сервера, который будет доступен по адресу localhost:5000. Вторая страница будет доступна по адресу localhost:5000/page2. Чтобы остановить веб-сервер, нужно нажать Ctrl+C в окне командной строки.

Виды пользовательских запросов

Протокол HTTP определяет множество типов запросов, называемых методами. Для выполнения этой работы нам понадобится рассмотреть два наиболее часто используемых - GET и POST.

Согласно стандарту, GET-запросы используются для получения информации с сервера. GET-запрос формируется при нажатии на какую-либо ссылку в браузере, а так же при вводе URL в адресную строку вручную. Основную информативную нагрузку GET-запроса несёт путь к ресурсу, часть URL, следующая после имени сервера. Соотношения между частями URL схематично изображены ниже:

                      URL
__________________________________________________
|                                                |

https://volsu.ru/struct/institutes/ipt/itsecurity/

       |        |                                |
       |        |________________________________|
       |        |         путь к ресурсу
       |________|
       | Домен
_______|
Схема протокола

Веб-сервер извлекает путь к ресурсу из URL и возвращает браузеру содержимое, соответствующее этому ресурсу.

POST-запросы используются для передачи данных на сервер. Чтобы браузер произвёл POST-запрос, в HTML-коде страницы должен присутствовать тег <form method="POST">. Нажатие на элемент управления <input type="submit"> приведёт к формированию POST-запроса, который будет содержать данные со всех остальных элементов управления формы.

Обработка POST-запросов в Flask

В примерах выше была рассмотрена обработка GET-запросов. Для доступа к значениям, передающихся в POST-запросах во Flask используется глобальная переменная request, которую необходимо импортировать перед использованием:

from flask import request

Затем, в декораторе обработчика нужно обозначить список поддерживаемых методов:

@app.route('/', methods=['POST', 'GET'])
...

Наконец, в коде обработчика поле request.method позволяет отличать GET-запрос от POST-запроса:

def hello_world():
    if request.method == "POST":
      return "Hello world from POST"
    else:
      return "Hello world from GET"

Чтобы извлечь переданные данные из POST-запроса, используется словарь request.form, ключами которого являются имена элементов HTML-формы, указанные в атрибуте name. Например, обработчик приведённой выше формы имеет следующий вид:

def hello_world():
    if request.method == "POST":
      return "Ф.И.О. = " + request.form["fio"] + "<hr>"
          +  "Возраст = " + request.form["age"] + "<hr>"
          +  "Статьи = " + request.form["papers"]

Контрольные вопросы

  1. Как добавить свой собственный пакет на PyPI?
  2. Что будет, если активировать две виртуальные среды Python подряд в одном окне командной строки?
  3. Можно ли взаимодействовать с веб-приложением через командную строку?
  4. Может ли HTML-форма иметь два элемента <input type="submit">?
  5. Что происходит, если в браузере попытаться обновить страницу, которая была открыта в результате POST-запроса?

Задание на лабораторную работу

  1. Создать новую виртуальную среду virtualenv для выполнения этой лабораторной работы.
  2. В виртуальной среде установить пакет Flask.
  3. Переписать код предыдущей лабораторной работы таким образом, чтобы программа функционировала как веб-приложение. Пользователь взаимодействует с веб-интерфейсом через браузер, а введённые им данные отправляются на серверную часть. Серверная часть обрабатывает запрос и возвращает пользователю ответ в виде HTML кода, который отображается в браузере.
  4. Запустить веб-приложение, перейти в браузере на его адрес и убедиться в его правильном функционировании.