Понимание расширений Flask

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

Знакомство с Flask-Script

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

Как показано в разделе о «Основах Flask», сервер разработки запускается с указанием хоста и порта через метод run():

if __name__ == "__main__":
    app.run(debug=True, host="127.0.0.10", port=9000)

Однако у этого метода есть недостаток — он статичен. Более предпочтительным является использование параметров командной строки для задания хоста и порта при запуске сервера. Flask-Script предлагает такую возможность. Установите Flask-Script с помощью команды pip:

(env) gvido@vm:~/flask_app$ pip install flask-script

Для начала работы с Flask-Script сначала импортируйте класс Manager из flask_script и создайте его экземпляр, передав ваше приложение. Этот шаг необходим для успешной интеграции. Измените файл main2.py следующим образом:

from flask import Flask, render_template
from flask_script import Manager

app = Flask(__name__)
manager = Manager(app)

#...

Теперь замените вызов app.run(debug=True) на manager.run(). На данном этапе ваш main2.py будет выглядеть следующим образом:

from flask import Flask, render_template
from flask_script import Manager

app = Flask(__name__)
manager = Manager(app)

@app.route('/')
def index():
    return render_template('index.html', name='Jerry')

@app.route('/user/<int:user_id>/')
def user_profile(user_id):
    return "Profile page of user #{}".format(user_id)

@app.route('/books/<genre>/')
def books(genre):
    return "All Books in {} category".format(genre)

if __name__ == "__main__":
    manager.run()

Теперь ваше приложение обладает возможностью доступа к стандартным командам. Просто запустите main2.py и вы увидите все доступные команды:

(env) gvido@vm:~/flask_app$ python main2.py
usage: main2.py [-?] {shell,runserver} ...

positional arguments:
  {shell,runserver}
    shell		Runs  a  Python shell inside Flask application context.
    runserver		Runs the Flask development server  i.e.  app.run()

optional arguments:
-?, --help		show this  help message and  exit

На данном этапе доступно всего две команды: shell и runserver, давайте рассмотрим в первую очередь runserver.

Команда runserver предназначена для запуска веб-сервера. Она по умолчанию использует хост 127.0.0.1 и порт 5000. Чтобы узнать больше о возможных опциях команды, стоит использовать --help:

(env) gvido@vm:~/flask_app$ python main2.py runserver --help
usage: main2.py runserver [-?] [-h  HOST] [-p  PORT]  [--threaded]
			  [--processes PROCESSES] [--passthrough-errors] [-d]
			  [-D] [-r] [-R] [--ssl-crt SSL_CRT]
			  [--ssl-key SSL_KEY]

Runs the Flask development server  i.e.  app.run()

optional arguments:
  -?, --help 		show this  help message and  exit
  -h HOST, --host HOST
  -p PORT, --port PORT
  --threaded
  --processes PROCESSES
  --passthrough-errors
  -d, --debug 		enable the Werkzeug debugger (DO NOT use in production
			code)
  -D, --no-debug	disable the Werkzeug debugger
  -r, --reload		monitor Python files for changes (not 100% safe for
			production use)
  -R, --no-reload 	do not  monitor Python files for changes
  --ssl-crt SSL_CRT 	Path to ssl certificate
  --ssl-key SSL_KEY 	Path to ssl key

Чаще всего для runserver используются флаги --host и --port, которые позволяют запускать сервер на определённом адресе и порту:

(env) gvido@vm:~/flask_app$ python main2.py runserver  --host=127.0.0.2 --port 8000
* Running on http://127.0.0.2:8000/ (Press CTRL+C to quit)

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

(env) gvido@vm:~/flask_app$ python main2.py runserver -d -r
 * Restarting with stat
 * Debugger is active!
 * Debugger PIN: 250-045-653
 * Running on http://127.0.0.1:5000/ (Press CTRL+C  to  quit)

Для удобства можно также установить параметр debug в значение True непосредственно в main2.py:

#...
app = Flask(__name__)
app.debug = True
manager = Manager(app)
#...

Теперь перейдем к рассмотрению команды shell.

Команда shell позволяет запустить интерактивную консоль Python в контексте приложения Flask, что упрощает импорт внутренних объектов приложения без необходимости вручного создания контекста. Чтобы открыть shell-консоль, воспользуйтесь следующей командой:

(env) gvido@vm:~/flask_app$ python main2.py shell

Теперь можно легко получить доступ ко всем необходимым объектам:

>>>
>>> from flask import current_app, url_for, request
>>>
>>> current_app.name
'main2'
>>>
>>>
>>> url_for("user_profile", user_id=10)
'/user/10/'
>>>
>>> request.path
'/'
>>>

Таким образом, можно избежать необходимости явного создания контекста приложения и запроса.

Разработка собственных команд

После того как объект Manager создан, вы можете начать разработку своих собственных команд. Существует два основных способа достижения этой цели:

  1. Использование класса Command
  2. Применение декоратора @command
Использование классового подхода для создания команд

Добавьте в main2.py следующий код, описывающий класс Faker:

#...
from flask_script import Manager, Command
#...

manager = Manager(app)

class Faker(Command):
    'Команда для добавления поддельных данных в таблицы'
    def run(self):
        # логика функции
        print("Fake data entered")

@app.route('/')
#...

Для запуска команды через терминал необходимо зарегистрировать ее в экземпляре Manager, используя метод add_command():

#...
class Faker(Command):
    'Команда для добавления поддельных данных в таблицы'
    def run(self):
        # логика функции
        print("Fake data entered")

manager.add_command("faker", Faker())
#...

Откройте терминал и запустите ваш скрипт main2.py:

(env) gvido@vm:~/flask_app$ python main2.py
usage: main2.py [-?] {faker,shell,runserver} ...

positional arguments:
  {faker,shell,runserver}
    faker  		Команда для добавления поддельных данных в таблицы
    shell		Runs  a  Python shell inside Flask application context.
    runserver		Runs the Flask development server  i.e.  app.run()

optional arguments:
-?, --help		show this  help message and  exit

Теперь у вас есть команда faker, которая будет генерировать фиктивные данные. Воспользуйтесь командой через терминал:

(env) gvido@vm:~/flask_app$ python main2.py faker
Fake data entered
Создание команд при помощи декоратора @command

Чтобы упростить процесс создания команд, можно использовать декоратор @command менеджера. Сделайте изменения в main2.py следующим образом:

#...
manager.add_command("faker", Faker())

@manager.command
def foo():
    "Это созданная команда"
    print("foo command executed")

@app.route('/')
#...

Команда foo создана и после запуска выводит foo command executed. Декоратор @command автоматически добавляет эту команду в менеджер, поэтому использование add_command() не требуется. Вернитесь в терминал и протестируйте изменения запустив main2.py.

(env) gvido@vm:~/flask_app$ python main2.py
usage: main2.py [-?] {faker,foo,shell,runserver} ...

positional arguments:
  {faker,foo,shell,runserver}
    faker  		Команда для добавления поддельных данных в таблицы
    foo 		Это созданная команда
    shell		Runs  a  Python shell inside Flask application context.
    runserver		Runs the Flask development server  i.e.  app.run()

optional arguments:
-?, --help		show this  help message and  exit

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

(env) gvido@vm:~/flask_app$ python main2.py foo
foo command executed

Автоматизация импорта объектов

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

Команда Shell запускает интерпретатор. Её аргумент make_context позволяет задать объекты, доступные по умолчанию при запуске. В стандартной конфигурации доступен только app, но этот набор можно легко расширить.

Откройте main2.py и после функции foo() добавьте следующий код:

#...
from flask_script import Manager, Command, Shell
#...

def shell_context():
    import os, sys
    return dict(app=app, os=os, sys=sys)

manager.add_command("shell", Shell(make_context=shell_context))
#...

Функция shell_context() передаётся в make_context и возвращает словарь с объектами app, os и sys. Эти объекты теперь будут доступны при запуске shell, без необходимости выполнять импорт вручную:

(env) gvido@vm:~/flask_app$ python main2.py shell
>>>
>>> app
<Flask 'main2'>
>>>
>>> os.name
'posix'
>>>
>>> sys.platform
'linux'
>>>
>>>

Вопросы для самопроверки:

  1. Что такое Flask-Script и какие задачи он упрощает?
  2. Для чего используется команда runserver в Flask-Script?
  3. Как активировать отладчик при запуске сервера с помощью Flask-Script?
  4. Что позволяет делать команда shell в контексте Flask-Script?
  5. Как работает декоратор @command в Flask-Script?