GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Python 3
  • Скачать Python
  • IDE
  • Скачать PyCharm
  • Django
  • Tkinter
  • Книги

This view

  • Original page
  • New address

GeezerVison is showing python-scripts.com — Начало работы с Flask - Настройка проекта

Уроки по Flask

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

  • Часть 1: Установка локальной среды разработки, запуск приложения на Heroku (данная статья);
  • Часть 2: Установка базы данных PostgreSQL вместе с SQLAlchemy и Alembic для обработки миграций;
  • Часть 3: Добавление логики бэкенда для парсинга и последующий процесс подсчета слов с веб-страницы через использование модуля Requests, BeautifulSoup и библиотеки Natural Language Toolkit NLTK;
  • Часть 4: Имплементация очереди задач в Redis для обработки текста;
  • Часть 5: Использование Angular на фронтенде для постоянного взаимодействия с бэкендом, чтобы посмотреть статус запроса;
  • Часть 6: Тестирование приложения на Heroku — установка Redis и описание запуска двух процессов (web и worker) на единственном контейнере (Dyno);
  • Часть 7: Обновление фронтенда, чтобы сделать его более удобным для пользователей;
  • Часть 8: Создание настраиваемой Angular директивы для отображения диаграммы с частотой словесных пар используя JavaScript и D3.

Есть вопросы по Python?

На нашем форуме вы можете задать любой вопрос и получить ответ от всего нашего сообщества!

Python Форум Помощи

Telegram Чат & Канал

Вступите в наш дружный чат по Python и начните общение с единомышленниками! Станьте частью большого сообщества!

Чат
Канал

Паблик VK

Одно из самых больших сообществ по Python в социальной сети ВК. Видео уроки и книги для вас!

Подписаться

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

Содержание статьи

  • Настройка проекта на Flask
  • Установка Heroku для работы с Flask
  • Рабочий поток Staging/Production
  • Файл конфигурации веб-приложения
  • Настройка локальной среды
  • Настройки Heroku для Flask

Настройка проекта на Flask

Начнем с создания базового веб-приложения «Hello World» на Heroku с двумя средами:

  • staging (стейджинг) — предназначенной для разработки и тестирования;
  • production (продакшнен) — предназначенной для релиза протестированных версий нашего веб-приложения.

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

  • Virtualenv;
  • Flask;
  • git/Github;
  • Heroku (основы).

Сперва настроим рабочую директорию:

Shell
1
$ mkdir flask-by-example && cd flask-by-example

Инициализиуем новый git репозиторий внутри нашей рабочей директории:

Shell
1
$ git init

Устанавливаем среду окружения для использования в нашем веб-приложении:

Shell
1
2
$ python3 -m venv env
$ source env/bin/activate

Теперь вы можете увидеть (env) с левой стороны терминала, это указывает на то, что сейчас вы работаете в виртуальной среде.

Чтобы покинуть виртуальную среду просто выполните в терминале команду deactivate и когда захотите продолжить работу над проектом, запустите source env/bin/activate.

Затем нам нужно будет создать базовую структуру для нашего приложения. Создадим следующие файлы в папку "flask-by-example":

Shell
1
$ touch app.py .gitignore README.md requirements.txt

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

Shell
1
2
3
4
├── .gitignore
├── app.py
├── README.md
└── requirements.txt

Не забудьте обновить файл .gitignore из репозитория.

На всякий случай, стоит обновить pip через команду:

Shell
1
pip install --upgrade pip

Устанавливаем Flask через pip:

Shell
1
$ python -m pip install Flask==1.1.2

Добавляем установленные библиотеки в наш файл requirements.txt:

Shell
1
$ python -m pip freeze > requirements.txt

Открываем файл app.py в текстовом редакторе и добавляем следующий код:

Python
1
2
3
4
5
6
7
8
9
10
from flask import Flask
app = Flask(__name__)
 
 
@app.route('/')
def hello():
    return "Hello World!"
 
if __name__ == '__main__':
    app.run()

Запускаем приложение:

Shell
1
$ python app.py

Вы должны увидеть стандартное приложение «Hello World» в действии на http://localhost:5000/. По завершению работы, веб-сервер нужно закрыть через комбинацию CTRL+C.

Затем нужно настроить Heroku для запуска веб-приложения на нем.

Установка Heroku для работы с Flask

Если вы этого еще не сделали, создайте аккаунт на Heroku, скачайте и установите Heroku Toolbelt и затем в терминале запустите команду для входа на Heroku:

Shell
1
heroku login

Форма для входа на Heroku

После удачного входа на Heroku, нужно создать файл Procfile в вашей корневой директории проекта:

Shell
1
$ touch Procfile

Добавляем следующую строку в новый созданный файл Procfile:

Shell
1
web: gunicorn app:app

Не забудьте добавить модуль gunicorn в файл зависимостей requirments.txt:

Shell
1
2
$ python -m pip install gunicorn==20.0.4
$ python -m pip freeze > requirements.txt

Нам также нужно указать версию Python, чтобы Heroku использовал верный Python Runtime для запуска нашего веб-приложения.

Просто создаем файл под названием runtime.txt со следующим содержимым:

Shell
1
python-3.8.5

Загрузим наши изменения через git (также можно разместить на Github), затем создаем две новые веб-приложения на Heroku.

Первое веб-приложение для продакшена:

Shell
1
$ heroku create wordcount-pro-22-08-2020

Второе веб-приложение для стейджинга:

Shell
1
$ heroku create wordcount-stage-22-08-2020

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

Я предлагаю использовать такой шаблон названия приложения:

Shell
1
wordcount-pro-DD-MM-YYYY

  • DD — текущий день;
  • MM — месяц;
  • YYYY — год.

В моем случае это:

  • wordcount-pro-22-08-2020;
  • wordcount-stage-22-08-2020.

В моем случае был получен вот такой результат в терминале:

Shell
1
2
3
4
heroku create wordcount-pro-22-08-2020
 
Creating ⬢ wordcount-pro-22-08-2020... done
https://wordcount-pro-22-08-2020.herokuapp.com/ | https://git.heroku.com/wordcount-pro-22-08-2020.git

Shell
1
2
3
4
heroku create wordcount-stage-22-08-2020
 
Creating ⬢ wordcount-stage-22-08-2020... done
https://wordcount-stage-22-08-2020.herokuapp.com/ | https://git.heroku.com/wordcount-stage-22-08-2020.git

Добавим новые приложения в git remote. Не забудьте назвать один remote pro (для продакшена), а другой stage (для стейджинга):

Shell
1
2
git remote add pro https://git.heroku.com/wordcount-pro-22-08-2020.git
git remote add stage https://git.heroku.com/wordcount-stage-22-08-2020.git

Подготавливаем все файлы для комита:

Shell
1
2
git add -A
git commit -m "Initial commit"

Теперь можно загрузить оба приложения для работы в режиме реального времени на Heroku:

  • Для стейджинга: git push stage master
  • Для продакшена: git push pro master

Вот так выглядит результат в терминале у меня:

Shell
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
git push pro master
Counting objects: 8, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (5/5), done.
Writing objects: 100% (8/8), 1015 bytes | 1015.00 KiB/s, done.
Total 8 (delta 0), reused 0 (delta 0)
remote: Compressing source files... done.
remote: Building source:
remote:
remote: -----> Python app detected
remote: -----> Installing python-3.8.5
remote: -----> Installing pip 20.1.1, setuptools 47.1.1 and wheel 0.34.2
remote: -----> Installing SQLite3
remote: -----> Installing requirements with pip
remote:        Collecting click==7.1.2
remote:          Downloading click-7.1.2-py2.py3-none-any.whl (82 kB)
remote:        Collecting Flask==1.1.2
remote:          Downloading Flask-1.1.2-py2.py3-none-any.whl (94 kB)
remote:        Collecting gunicorn==20.0.4
remote:          Downloading gunicorn-20.0.4-py2.py3-none-any.whl (77 kB)
remote:        Collecting itsdangerous==1.1.0
remote:          Downloading itsdangerous-1.1.0-py2.py3-none-any.whl (16 kB)
remote:        Collecting Jinja2==2.11.2
remote:          Downloading Jinja2-2.11.2-py2.py3-none-any.whl (125 kB)
remote:        Collecting MarkupSafe==1.1.1
remote:          Downloading MarkupSafe-1.1.1-cp38-cp38-manylinux1_x86_64.whl (32 kB)
remote:        Collecting Werkzeug==1.0.1
remote:          Downloading Werkzeug-1.0.1-py2.py3-none-any.whl (298 kB)
remote:        Installing collected packages: click, MarkupSafe, Jinja2, Werkzeug, itsdangerous, Flask, gunicorn
remote:        Successfully installed Flask-1.1.2 Jinja2-2.11.2 MarkupSafe-1.1.1 Werkzeug-1.0.1 click-7.1.2 gunicorn-20.0.4 itsdangerous-1.1.0
remote: -----> Discovering process types
remote:        Procfile declares types -> web
remote:
remote: -----> Compressing...
remote:        Done: 47.9M
remote: -----> Launching...
remote:        Released v3
remote:        https://wordcount-pro-22-08-2020.herokuapp.com/ deployed to Heroku
remote:
remote: Verifying deploy... done.
To https://git.heroku.com/wordcount-pro-22-08-2020.git
* [new branch]      master -> master

После загрузки файлов на Heroku, можно открыть URL веб-приложения в браузере и, если все прошло хорошо, вы увидите «Hello World!».

Рабочий поток создания веб-приложения

Сделаем изменение в нашем веб-приложении и загрузим их только на стейджинге (тестовой версии нашего веб-приложения):

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from flask import Flask
app = Flask(__name__)
 
 
@app.route('/')
def hello():
    return "Привет, мир!"
 
 
@app.route('/<name>')
def hello_name(name):
    return f"Привет, {name}!"
 
if __name__ == '__main__':
    app.run()

Запустите веб-приложение локально и убедитесь, что все работает:

Shell
1
python app.py

Попробуйте добавить в какое либо имя после / в URL, то есть http://localhost:5000/mike.

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

Убедитесь, что ваши изменения зафиксированы в git:

Python
1
2
git add -A
git commit -m "Добавили новый метод hello_name"

Затем, загружаем все изменения на стейджинг (приложение для предварительного тестирования):

Shell
1
git push stage master

У меня получился вот такой вывод:

Shell
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
Counting objects: 3, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 460 bytes | 460.00 KiB/s, done.
Total 3 (delta 1), reused 0 (delta 0)
remote: Compressing source files... done.
remote: Building source:
remote:
remote: -----> Python app detected
remote: -----> No change in requirements detected, installing from cache
remote: -----> Installing pip 20.1.1, setuptools 47.1.1 and wheel 0.34.2
remote: -----> Installing SQLite3
remote: -----> Installing requirements with pip
remote: -----> Discovering process types
remote:        Procfile declares types -> web
remote:
remote: -----> Compressing...
remote:        Done: 47.9M
remote: -----> Launching...
remote:        Released v4
remote:        https://wordcount-stage-22-08-2020.herokuapp.com/ deployed to Heroku
remote:
remote: Verifying deploy... done.
To https://git.heroku.com/wordcount-stage-22-08-2020.git
   8453284..253dc75  master -> master

Теперь при переходу в среду стейджинга вы сможете использовать новый URL, то есть /mike и увидите Привет, mike! в зависимости от того, какое имя вы поместили в URL.

В моем случае это:

Shell
1
https://wordcount-stage-22-08-2020.herokuapp.com/Mike

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

Если все хорошо, давайте загрузим изменения и для продакшена:

Shell
1
git push pro master

Теперь та же функциональность доступна на продакшен сайте.

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

Создаем файл конфигурации веб-приложения

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

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

Добавим файл config.py в корень проекта:

Shell
1
$ touch config.py

В файле конфигурации мы собираемся позаимствовать кое-что из того, как настраивается конфигурация в Django. У нас будет базовый класс Config, от которого наследуются другие классы конфигурации. Затем при необходимости мы импортируем соответствующий класс.

Добавьте следующей код в созданный файл config.py:

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import os
basedir = os.path.abspath(os.path.dirname(__file__))
 
 
class Config(object):
    DEBUG = False
    TESTING = False
    CSRF_ENABLED = True
    SECRET_KEY = 'this-really-needs-to-be-changed'
 
 
class ProductionConfig(Config):
    DEBUG = False
 
 
class StagingConfig(Config):
    DEVELOPMENT = True
    DEBUG = True
 
 
class DevelopmentConfig(Config):
    DEVELOPMENT = True
    DEBUG = True
 
 
class TestingConfig(Config):
    TESTING = True

Мы импортировали модуль os и затем создали переменную basedir значение которой является полным путем к файлу config.py. Затем мы создаем базовый класс Config с некоторыми основными настройками, которые будут наследовать другие классы.

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

  • локальной на нашем компьютере;
  • стейджингом (приложение только для тестирования);
  • продакшеном (рабочее приложение для пользователей).

Flask: Настройка локальной среды

Для настройки нашего веб-приложения с индивидуальными переменными в зависимости от среды, мы будем использовать модуль autoenv.

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

Сначала выходим из виртуальной среды в терминале, устанавливаем глобально модуль autoenv и создаем файл .env:

Shell
1
2
3
$ deactivate
$ pip install autoenv==1.0.0
$ touch .env

В файле .env добавим следующее содержимое:

Shell
1
2
source env/bin/activate
export APP_SETTINGS="config.DevelopmentConfig"

Выполняем следующие команды в терминале для изменения и обновления файла ~/.bashrc:

Shell
1
2
$ echo "source `which activate.sh`" >> ~/.bashrc
$ source ~/.bashrc

Теперь при переходе в данную папку, виртуальная среда автоматически запустится и объявится переменная APP_SETTINGS.

Настройки Heroku для Flask

Аналогичным образом мы настроим переменные на Heroku.

Для стейджинга запустим следующую команду:

Shell
1
$ heroku config:set APP_SETTINGS=config.StagingConfig --remote stage

Полученный ответ:

Shell
1
2
Setting APP_SETTINGS and restarting ⬢ wordcount-stage-22-08-2020... done, v5
APP_SETTINGS: config.StagingConfig

Для продакшена:

Shell
1
$ heroku config:set APP_SETTINGS=config.ProductionConfig --remote pro

Полученный ответ:

Shell
1
2
Setting APP_SETTINGS and restarting ⬢ wordcount-pro-22-08-2020... done, v5
APP_SETTINGS: config.ProductionConfig

Не забудьте проверить, правильно ли работают наши изменения. Обновите содержимое файла app.py:

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import os
from flask import Flask
 
 
app = Flask(__name__)
app.config.from_object(os.environ['APP_SETTINGS'])
print(os.environ['APP_SETTINGS'])
 
 
@app.route('/')
def hello():
    return "Hello World!"
 
 
@app.route('/<name>')
def hello_name(name):
    return "Hello {}!".format(name)
 
if __name__ == '__main__':
    app.run()

Мы импортировали модуль os и использовали метод os.environ для импорта соответствующей переменной APP_SETTINGS, в зависимости от нашей среды. Затем мы настраиваем конфигурацию в нашем приложении с помощью метода app.config.from_object.

Нам остается только зафиксировать изменения и загрузить их на стейджинг и продакшен (и Github, если он у вас настроен).

Shell
1
2
git add -A
git commit -m "Настройки среды"

Затем загружаем изменения:

Python
1
2
git push stage master
git push pro master

Если вы хотите проверить переменную среды, чтобы убедиться, что она определяет правильную среду, добавьте такой вывод в app.py:

Python
1
print(os.environ['APP_SETTINGS'])

Теперь при запуске приложения, будет показаны текущие настройки конфигурации:

Локально:

Shell
1
2
$ python app.py
config.DevelopmentConfig

Стейджинг:

Shell
1
2
3
$ heroku run python app.py --app wordcount-stage-22-08-2020
Running python app.py on wordcount-stage... up, run.7699
config.StagingConfig

Продакшен:

Shell
1
2
3
$ heroku run python app.py --app wordcount-pro-22-08-2020
Running python app.py on wordcount-pro... up, run.8934
config.ProductionConfig

Не забудьте удалить print(os.environ['APP_SETTINGS']) по завершению тестирования.

Заключение

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

Удачи!

Vasile Buldumac

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

E-mail: [email protected]

Образование
Universitatea Tehnică a Moldovei (utm.md)

  • 2014 — 2018 Технический Университет Молдовы, ИТ-Инженер. Тема дипломной работы «Автоматизация покупки и продажи криптовалюты используя технический анализ»
  • 2018 — 2020 Технический Университет Молдовы, Магистр, Магистерская диссертация «Идентификация человека в киберпространстве по фотографии лица»
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.