Руководство по веб-интерфейсу Python Flask

Оглавление

В первых двух частях этой серии блогов я сначала показал вам, как программно создавать QR-коды доступа к WiFi с помощью Python и печатать их в 3D, а затем как разработать и создать программу интерфейса командной строки (CLI), которая позволит вам создавать QR-коды, набрав несколько подсказок в терминале.

В этой записи блога я хочу продемонстрировать, как создать веб-приложение, которое создает QR-коды, используя информацию WiFi, которую может ввести конечный пользователь. Создав это приложение, вы, надеюсь, придете к тому же выводу, что и я: приложения командной строки и веб-приложения - это просто текстовые конечные точки для произвольного кода Python. Как только вы это поймете, процесс создания веб-приложений и приложений командной строки, надеюсь, станет гораздо менее мистическим!

Что такое Flask?

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

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

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

Структурирование приложения Flask

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

проект
├── шаблоны
└── app.py

Мы пишем наше приложение Flask в каталоге app.py. В каталоге templates/ мы храним HTML-шаблоны, которые наше приложение Flask будет использовать для отображения конечному пользователю. В нашей предыдущей записи в блоге у нас была следующая структура:

├── environment.yml
├── qrwifi
├── __init__.py
├──── app.py
├──── cli.py
├──── functions.py
├── шаблоны
├──── index.html.j2
├──── qr.html.j2
├──── template.html.j2
└── setup.py

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

Создание приложения Flask

Начнем с app.py. Как и в предыдущем посте, я буду развивать вашу интуицию бит за битом, а затем соберу окончательный копируемый/пастируемый участок кода, который вы сможете легко запустить. Вы можете следить за полным кодом этого проекта на github-репозитории Kite.

├── environment.yml
├── qrwifi
├── __init__.py
├──── app.py **
├──── cli.py
├──── functions.py
├── шаблоны
├──── index.html.j2
├──── qr.html.j2
├── template.html.j2
└── setup.py
from flask import Flask, render_template, request

from qrwifi.functions import wifi_qr


app = Flask(__name__)

Первая строка импорта содержит наиболее часто используемый набор объектов и функций Flask, которые мы будем использовать. Вторая строка imports позволяет нам импортировать функцию wifi_qr из нашего модуля qrwifi.functions, который сам является устанавливаемым. Наконец, третья строка позволяет нам создать объект Flask, которому мы присваиваем имя переменной app.

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

Работа с функциями представления

Лучше всего думать о функциях представления как о функциях, которые вызываются, когда вы набираете URL в браузере. Место, которое вы вводите, - это URI, иногда называемый конечной точкой, а сама функция называется callback - функция, вызываемая в ответ на какое-то событие. Наш обратный вызов возвращает шаблон, который при работе с Flask мы будем называть "представлением". Рассмотрим пример:

@app.route("/")
def home():
    return render_template("index.html.j2")

Здесь мы определили функцию home(), которая вызывается, когда мы вводим строку маршрутизации после имени нашего хоста в строке URL нашего браузера. Там есть много чего распаковать, так что давайте разберем это на части.

Строка маршрутизации?

Если вы перейдете в браузер и наберете следующий URL:

http://example.com/blog

Вы попадете в блог example.com - это строка, указывающая нам на сервер, на котором расположен блог, а /blog - это строка маршрутизации, которая говорит нам, куда идти. Вместе они образуют URI, "унифицированный указатель ресурса".

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

В приложениях Flask нам нужно указать только строку маршрутизации и соответствующую функцию, которая будет вызвана при вводе строки маршрутизации в браузер пользователя. В данном случае /, которая канонически направляет на домашнюю страницу сайта, назначена для вызова функции home(), которая возвращает вызов функции render_template.

Что здесь делает render_template, так это говорит приложению Flask заполнить все необходимое в шаблоне, а затем вернуть полученную HTML-страницу в браузер.

home() не представляет особого интереса, поскольку все, что мы делаем - это рендеринг HTML-шаблона, в котором нет переменных областей. Давайте посмотрим на этот шаблон - звездочки (**) указывают на файл, который мы сейчас редактируем.

HTML шаблон

├── environment.yml
├── qrwifi
├── __init__.py
├──── app.py
├──── cli.py
├──── functions.py
├── шаблоны
├──── index.html.j2 **
├──── qr.html.j2
├──── template.html.j2
└── setup.py
{% extends "template.html.j2" %}


{% block body %}

<div class="row">
  <div class="col-12">
    <h1>WiFi QR Code Creator</h1>
  </div>
  <div class="col-12">
    <form action="/create" method="post">
      <div class="form-group">
        <label for="ssid">SSID</label>
        <input class="form-control" type="text" name="ssid" id="ssid" placeholder="My WiFi Network Name">
      </div>

      <div class="form-group">
        <label for="security">Security Mode</label>
        <select class="form-control" name="security" id="security">
          <option value="WPA">WPA</option>
          <option value="WEP">WEP</option>
          <option value="">None</option>
        </select>
      </div>

      <div class="form-group">
        <label for="password">Password</label>
        <input class="form-control" type="password" name="password" id="password" placeholder="Protection is good!">
      </div>

      <div class="form-group">
        <button class="btn btn-lg btn-success" type="submit">Create QR Code!</button>
      </div>

    </form>
  </div>
</div>

{% endblock %}

"index.html.j2"

Здесь я не буду слишком углубляться в HTML, поскольку HTML не является основной темой этой статьи в блоге. Однако важно понимать, что HTML-страница с формой позволяет пользователям вводить SSID, тип безопасности и пароль. Конечно, знание HTML является необходимым условием для создания полезных вещей в Интернете.

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

Еще одна полезная вещь, которую следует упомянуть для изучения, - это синтаксис jinja2. Jinja2, который в разговоре обычно называют просто "Jinja", - это специальный язык шаблонов, версия HTML, которую мы можем использовать для организации нашего HTML-кода. Хотя вам не нужно быть экспертом в Jinja2, чтобы использовать преимущества Flask, важно понимать, что такое шаблоны и как они вписываются в приложение Flask.

Функции просмотра (продолжение)

Вернемся к функциям представления в app.py. На главной странице мы создали HTML-форму, в которую конечный пользователь может ввести информацию о своем WiFi. Теперь нам нужна функция представления, которая будет показывать полученный QR-код. Назовем ее create(), которая указывает на строку маршрутизации /create.

@app.route("/create", methods=["POST"])
def create():
    res = request.form
    qr = wifi_qr(ssid=res["ssid"], password=res["password"], security=res["security"])
    qr_b64 = qr.png_data_uri(scale=10)
    return render_template("qr.html.j2", qr_b64=qr_b64)

В функции create() мы делаем несколько вещей.

Сначала мы получаем отправленные данные из формы, которые мы можем использовать как словарь, к которому можно подобрать ключ. Затем мы передаем эту информацию в функцию wifi_qr, которую мы импортировали из functions.py. Наконец, мы создаем base64-кодированную версию QR-кода, которая позволит нам отобразить QR-код в шаблоне qr.html.j2.

Шаблон отображения кода QR

Давайте рассмотрим этот конкретный шаблон. (qr.html.j2)

{% extends "template.html.j2" %}

{% block body %}
<div class="row">
    <div class="col-12">
        <h1>WiFi QR Code Creator</h1>
        <p>Here is your QR Code!</p>
        <img src="{{ qr_b64|safe }}">
    </div>
</div>
{% endblock %}

В этом разделе раскрывается важность шаблонизатора. Мы можем вставить PNG-версию QR-кода в кодировке base64 в HTML-страницу, передав переменную qr_b64 в функцию render_template(), которая затем будет вставлена в тег <img>. QR-код в base64-кодировке будет меняться, но HTML-теги, окружающие его, останутся прежними, поэтому нам нужно только задать его как переменную в HTML-шаблоне.

Возврат к функции просмотра

Наконец, представим последнюю часть app.py.

def run():
    app.run(debug=True, port=5690, host="0.0.0.0")

if __name__ == "__main__":
    run()

По сути, мы сделали это, обслуживая приложение Flask на порту 5690 на нашем localhost. Я решил использовать обертку, аналогичную приложению CLI, чтобы мы могли запускать приложение Flask из командной строки. Питонисты считают лучшей практикой всегда сохранять некоторую функциональность командной строки.

Собираем все вместе

Давайте посмотрим все app.py вместе:

from flask import Flask, render_template, request

from qrwifi.functions import wifi_qr


app = Flask(__name__)


@app.route("/")
def home():
    return render_template("index.html.j2")


@app.route("/create", methods=["POST"])
def create():
    res = request.form
    print(res)
    qr = wifi_qr(ssid=res["ssid"], password=res["password"], security=res["security"])
    qr_b64 = qr.png_data_uri(scale=10)
    return render_template("qr.html.j2", qr_b64=qr_b64)


def run():
    app.run(debug=True, port=5690, host="0.0.0.0")

if __name__ == "__main__":
    run()

Использование создателя QR-кодов

В качестве дополнительного шага, если вы наберете на терминале:

$ python app.py

После этого вы можете перейти в браузер и ввести localhost:5690, и ваше приложение Flask начнет работать.

 

Вернуться на верх