Расширение возможностей Flask с помощью Flask-Script

Flask – это функциональный фреймворк, который при этом еще и компактный. Базовый функционал небольшой, но если нужно использовать функции, которых нет в изначальной комплектации, всегда возможна инсталляция расширений – специальных пакетов, имеющих дополнительный функционал. Ознакомьтесь с перечнем доступных расширений на странице. Здесь находятся пакеты, которые могут отправлять e-mail, создавать полноценные интерфейсы администратора и выполнять много других функций. Необходимо учитывать, что расширение возможностей Flask доступно не только с использованием расширений. В принципе, можно использовать любой модуль, который входит в стандартную библиотеку Python или PyPi.

Расширение Flask-Script

Это дополнение дает возможность работать над command-prompt интерфейсами, осуществлять запуск сервера и «пайтоновской» консоли в контексте приложений, делать так, чтобы конкретные переменные отображались в консоли автоматически, и так далее.

Чтобы запустить сервер разработки, необходимо сперва их передать адрес и порт методу run().  

if __name__ == "__main__":

    app.run(debug=True, host="127.0.0.10", port=9000

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

Вот с этой задачей и справляется Flask-Scripti.

Чтобы установить это расширение, необходимо использовать pip

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

Для использования Flask-Script, необходимо сначала импортировать класс Manager из пакета flask-script и создать объект класса Manager, передав ему экземпляр приложения. Таким образом осуществляется интегрирование расширения во фреймворк. Сперва осуществляется импорт требуемого класса из пакета, после чего создается экземпляр путем передачи ему экземпляра приложения.

Необходимо открыть файл main2.py и внести в него следующие коррективы. 

from flask import Flask, render_template

from flask_script import Manager




app = Flask(__name__)

manager = Manager(app)




#...

Созданный объект, помимо этого, имеет метод run(), который, кроме запуска сервера разработки, умеет считывать аргументы командной строки. Необходимо заменить строку 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()

Теперь программа имеет доступ к базовым командам. Чтобы понять, какие из них доступны, необходимо запустить этот файл. 

(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. Начнем со второй.

Она предназначена для запуска веб-сервера. Если говорить о стандартных настройках, то он запускается по IP 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 и –-post. Они дают возможность включить сервер разработки на конкретном порте и интерфейсе. 

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

(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)

Есть также менее трудоемкий метод запуска отладчика. Он заключается в том, чтобы пользователь выбрал значение True для атрибута debug объекта класса app. Для этого необходимо изменить файл main2.py, чтобы в нем были следующие строки. 

#...

app = Flask(__name__)

app.debug = True

manager = Manager(app)

#...

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

(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. С применением декоратора @comand.

Использование класса Command 

В файле, с которым мы работаем, добавим класс Faker

#...

from flask_script import Manager, Command

#...




manager = Manager(app)




class Faker(Command):

    'Команда для добавления поддельных данных в таблицы'

    def run(self):

        # логика функции

        print("Fake data entered")

       

@app.route('/')

#...

Таким образом мы создали команду Faker. Использовался при этом принцип наследования. Когда выполняется команда, используется содержимое метода run(). Чтобы выполнить команду через командную строку, ее необходимо добавить в экземпляр 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

Учтите, что в дополнение к shell и runserver имеется еще одна команда – faker. Из строки с документацией соответствующего класса было взято описание. Для запуска следует указать такую команду.

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

Fake data entered

Использование декоратора @command, чтобы создать команду

Декоратор @command – неплохая альтернатива, которая позволяет значительно уменьшить количество строчек, необходимых для создания команд с использованием класса Command.

Для этого необходимо изменить файл main2.py таким образом. 

#...

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




@manager.command

def foo():

    "Это созданная команда"

    print("foo command executed")




@app.route('/')

#...

Так мы создали простую команду foo, которая при вызове выводит строку foo command executed

Автоматический импорт объектов

Конечно, может потребоваться немало времени и сил на то, чтобы импортировать большое количество объектов. Решить эту проблему позволяет расширение Flask Script, которое позволяет увеличить видимость объектов в терминале, при этом не используя явного импорта. 

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

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

Давайте откроем файл main2.py и внесем в него такие изменения: 

#...

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. Теперь доступ к этим объектам можно получить и без импорта.

ОфисГуру
Adblock
detector