Flask扩展flask-script文档中文翻译

原创
2013/09/03 13:51
阅读数 4.7W

Flask扩展flask-script文档中文翻译

Flask-Script扩展提供向Flask插入外部脚本的功能。包括运行一个开发用的服务器,一个定制的 Python shell,设置数据库的脚本,cronjobs,以及其他的运行在web应用之外的命令行任务。

Flask-Script和Flask本身的工作方式类似。只需要定义和添加能从命令行中被Manager实例调用的 命令即可。

'''
# manage.py

from flask.ext.script import Manager
from myapp import app

manager = Manager(app)
@manager.command
def hello():
    print "hello"

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

只要像上面一样定义你自己的命令脚本,就可以在命令行中如下调用他们:

'''
python manage.py hello
> hello

Flask-Script的源代码和bug追踪见 GitHub

安装Flask-Script

可以使用pip或者easy_install安装装:

'''
pip install Flask-Script

或者下载最新开发版本:

'''
git clone https://github.com/techniq/flask-script.git
cd flask-script
python setup.py develop

如果你使用virtualenv,需保证把Flask-Script和你的Flask应用安装在同一virtualenv环境下。

创建并且运行命令

首先,创建一个Python模块运行你的命令脚本。可以任意起名,例如manage.py。

无需把所有的命令都放在同一个文件里,例如,在一个大型项目中,可以把相关联的命令放在不同的文件里。

在你的manage.py文件中,必须有一个Manager实例。Manager类将追踪所有的在命令行中调用的命令和处理过程的调用运行 情况:

'''
from flask.ext.script import Manager

app = Flask(__name__)
# configure your app

manager = Manager(app)

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

调用 manager.run()将启动Manger实例接收命令行中的命令。

Manager只有一个参数:一个Flask实例。如果你想用工场模式,那也可以是一个函数或者其他的返回Flask实例的玩意儿。

其次,创建并且加入命令。有三种方法可创建命令:

  • 创建Command的子类
  • 使用 @command 修饰符
  • 使用 @option 修饰符

下面是一个简单的例子,创建一个Hello命令,该命令只是简单的输出“hello word”。

'''
from flask.ext.script import Command

class Hello(Command):
    "prints hello world"

    def run(self):
        print "hello world"

再把上面创建的Hello命令加入Manager实例:

'''
manager.add_command('hello', Hello())

很明显,上面的语句需要在manager.run()之前运行。现在执行下面的命令:

'''
python manage.py hello
> hello world

也可传给Command实例的run方法一个字典:

'''
manager.run({'hello' : Hello()})

Command class 必须定义一个run方法。定义的位置和参数依赖于你的定义的命令的参数。详见下文。

运行下面的命令获取可以使用的命令及其描述的列表:

'''
python manage.py

通过运行下面的命令获取一个特定命令的帮助,这将输出这个命令的docstring。

'''
python manage.py runserver -h

上面的第一种方法是最适用的,但也是最麻烦的。对于简单的命令,只需要使用Command实例的@command修饰符。

@manager.command
def hello():
    "Just say hello"
    print "hello"

这种方法创建的命令的运行方式和Command类创建的运行方式是相同的。

'''
python manage.py hello
> hello

如果用Comman类来实现,下面的命令将输出manage类的docstring:

'''
python manage.py -h
> Just say hello

最后,@option修饰符适用于更精细的命令行控制:

'''
@manager.option('-n', '--name', help='Your name')
def hello(name):
    print "hello", name

后面会有更详细的对@option的介绍。

增加命令行参数

大多数命令都带有参数。还是上面的例子,如果不仅仅是打印"hello world",还想输出一个额外的名字,如:

python manage.py hello --name=Joe
hello Joe

或者短参数:

python manage.py hello -n Joe

为实现这一功能,需要使用Command类的option_list属性。

from flask.ext.script import Command, Manager, Option

class Hello(Command):

    option_list = (
        Option('--name', '-n', dest='name'),
    )

    def run(self, name):
        print "hello %s" % name

长参数和短参数都是存储在Option实例中。详见API部分。

另一种方法是为你的Command类定义一个get——options方法,这将在希望依赖运行实例返回值来得到参数时非常有效。

class Hello(Command):

    def __init__(self, default_name='Joe'):
        self.default_name=default_name

    def get_options(self):
        return [
            Option('-n', '--name', dest='name', default=self.default_name),
        ]

    def run(self, name):
        print "hello",  name

若使用@command修饰符,参数将直接自动的从函数的参数中获取:

@manager.command
def hello(name):
    print "hello", name

> python manage.py hello Joe
hello Joe

或者使用可选参数:

@manager.command
def hello(name="Fred")
	print hello, name

调用方法如下:

> python manage.py hello --name=Joe
hello Joe

或者:

> python manage.py hello -n Joe
hello Joe

这里需要注意:

-n 是由参数的第一个字母决定的。所以"name" > "-n"

其次,-h选项通常输出命令的帮助文档,所以避免使用h开头的参数。

同时,需要注意选项参数是boolean值,例如:

@manage.command
def verify(verified=False):
    """
    Checks if verified
    """
    print "VERIFIED?", "YES" if verified else "NO"

只能这样调用:

> python manage.py verify
VERIFIED? NO

> python manage.py verify -v
VERIFIED? YES

> python manage.py verify --verified
VERIFIED? YES

@command修饰符随便简单好用,但在复杂情况下,@option是更好的选择:

@manager.option('-n', '--name', dest='name', default='joe')
def hello(name):
    print "hello", name

可以增加更多的选项参数:

@manager.option('-n', '--name', dest='name', default='joe')
@manager.option('-u', '--url', dest='url', default=None)
def hello(name, url):
    if url is None:
        print "hello", name
    else:
        print "hello", name, "from", url

可以这样调用: > python manage.py hello -n Joe -u reddit.com hello Joe from reddit.com

或者:

> python manage.py hello --name=Joe --url=reddit.com
hello Joe from reddit.com

向manager加入配置项

配置项也可以传给Manager实例。这是你可以设置传给Flask应用的配置项以便一条命令即可完成。例如,你可以使用一个标 志来为你的应用设置配置文件。例如:

def create_app(config=None):

    app = Flask(__name__)
    if config is not None:
        app.config.from_pyfile(config)
    # configure your app...
    return app

可以使用命令行定义配置文件参数,例如使用一条命令设置数据库,可以根据生产环境和开发环境选用不同的配置文件。

为实现传配置参数,可以使用add_option()方法,这和Option的参数一样。

manager.add_option('-c', '--config', dest='config', required=False)

同其他Flask-Script配置一样,可以在任何地方使用上面的语句,但确保在manager.run()之前执行。

假设你有下面的命令:

@manager.command
def hello(name):
    uppercase = app.config.get('USE_UPPERCASE', False)
    if uppercase:
        name = name.upper()
    print hello, name

> python manage.py hello joe -c dev.cfg
hello JOE

注意,”config“选项并没有传给上面的hello命令。

为保证manage的选项能正常工作,需要传一个工厂函数给Manager的构造器,而不是一个Flask实例。上面既是可以简单的示 例。

获取用户输入

Flask-Script拥有一组helper函数来获取用户在命令行中的输入,例如:

from flask.ext.script import Manager, prompt_bool

from myapp import app
from myapp.models import db

manager = Manager(app)

@manager.command
def dropdb():
    if prompt_bool(
        "Are you sure you want to lose all your data"):
        db.drop_all()

执行如下:

python manage.py dropdb
> Are you sure you want to lose all your data ? [N]

从下文API中获取更多关于prompt functions的内容。

默认命令

Flask-Script拥有一对预设的命令,你可以加入或者定制:Server and Shell。

Server命令运行Flask的开发server,它带有一个可选的端口参数,默认是5000。

from flask.ext.script import Server, Manager
from myapp import create_app

manager = Manager(create_app)
manager.add_command("runserver", Server())

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

运行如下:

python manage.py runserver

Server命令有一组命令行参数,运行python manage.py runserver -h 获取详细信息。你也可以在构造函数中重新定义默认 行为:

server = Server(host="0.0.0.0", port=9000)

无需赘言,开发Server不是为生产环境准备的。

Shell名令启动一个Python shell。可以穿进去一个make_context参数,这个参数必须是一个字典。默认情况下,将返回你的 Flask应用实例。

from flask import app

from flask.ext.script import Shell, Manager

from myapp import app
from myapp import models
from myapp.models import db

def _make_context():
    return dict(app=app, db=db, models=models)

manager = Manager(create_app)
manager.add_command("shell", Shell(make_context=_make_context))

这将对于你希望在shell引入一组默认的包非常有利,无需再输入很多import语句。

Shell命令将使用IPthon,如果安装了的话。否则,默认使用标准Python shell。你可以用两种方法关闭这一 行为:传use_ipython参数给Shell构造器,或者在命令行中传标记--no-ipython。

shell = Shell(use_ipython=False)

也有一个shell修饰符,你可以在函数上下文中使用。

@manager.shell
def make_shell_context():
    return dict(app=app, db=db, models=models)

这将使这个命令成为shell的默认执行的命令。

> python manage.py shell

默认命令shell和runserver是默认引入的,并且带有这两个命令的默认选项。若你想用其他命令替代默认的命令,只要重写 add_command()或者修饰符。若你传给Manager的构造器一个with_default_commands=False参数,则这些命令不会被载入。

manager = Manager(app, with_default_commands=False)

Sub-Managers A Sub-Manager is an instance of Manager added as a command to another Manager

To create a submanager:

sub_manager = Manager()

manager = Manager(self.app) manager.add_command("sub_manager", sub_manager) Restrictions A sub-manager does not provide an app instance/factory when created, it defers the calls to it’s parent Manager’s A sub-manager inhert’s the parent Manager’s app options (used for the app instance/factory) A sub-manager does not get default commands added to itself (by default) A sub-manager must be added the primary/root Manager instance via add_command(sub_manager) A sub-manager can be added to another sub-manager as long as the parent sub-manager is added to the primary/root Manager New in version 0.5.0.

Note to extension developers Extension developers can easily create convenient sub-manager instance within their extensions to make it easy for a user to consume all the available commands of an extension.

Here is an example how a database extension could provide (ex. database.py):

manager = Manager(usage="Perform database operations")

@manager.command def drop(): "Drops database tables" if prompt_bool("Are you sure you want to lose all your data"): db.drop_all()

@manager.command def create(default_data=True, sample_data=False): "Creates database tables from sqlalchemy models" db.create_all() populate(default_data, sample_data)

@manager.command def recreate(default_data=True, sample_data=False): "Recreates database tables (same as issuing 'drop' and then 'create')" drop() create(default_data, sample_data)

@manager.command def populate(default_data=False, sample_data=False): "Populate database with default data" from fixtures import dbfixture

if default_data:
    from fixtures.default_data import all
    default_data = dbfixture.data(*all)
    default_data.setup()

if sample_data:
    from fixtures.sample_data import all
    sample_data = dbfixture.data(*all)
    sample_data.setup()

Then the user can register the sub-manager to their primary Manager (within manage.py):

manager = Manager(app)

from flask.ext.database import manager as database_manager manager.add_command("database", database_manager) The commands will then be available:

python manage.py database

Please provide a command:

Perform database operations create Creates database tables from sqlalchemy models drop Drops database tables populate Populate database with default data recreate Recreates database tables (same as issuing 'drop' and then 'create') Accessing local proxies The Manager runs the command inside a Flask test context. This means that you can access request-local proxies where appropriate, such as current_app, which may be used by extensions.

API class flask_script.Manager(app=None, with_default_commands=None, usage=None, disable_argcomplete=False) Controller class for handling a set of commands.

Typical usage:

class Print(Command):

def run(self):
    print "hello"

app = Flask(name)

manager = Manager(app) manager.add_command("print", Print())

if name == "main": manager.run() On command line:

python manage.py print

hello Parameters: app – Flask instance or callable returning a Flask instance. with_default_commands – load commands runserver and shell by default. disable_argcomplete – disable automatic loading of argcomplete. run(commands=None, default_command=None) Prepares manager to receive command line input. Usually run inside “if name == “main” block in a Python script.

Parameters: commands – optional dict of commands. Appended to any commands added using add_command(). default_command – name of default command to run if no arguments passed. add_option(*args, **kwargs) Adds an application-wide option. This is useful if you want to set variables applying to the application setup, rather than individual commands.

For this to work, the manager must be initialized with a factory function rather than an instance. Otherwise any options you set will be ignored.

The arguments are then passed to your function, e.g.:

def create_app(config=None): app = Flask(name) if config: app.config.from_pyfile(config)

return app

manager = Manager(create_app) manager.add_option("-c", "--config", dest="config", required=False) and are evoked like this:

python manage.py -c dev.cfg mycommand Any manager options passed in the command line will not be passed to the command.

Arguments for this function are the same as for the Option class.

add_command(name, command) Adds command to registry.

Parameters: command – Command instance command(func) Decorator to add a command function to the registry.

Parameters: func – command function.Arguments depend on the options. option(*args, **kwargs) Decorator to add an option to a function. Automatically registers the function - do not use together with @command. You can add as many @option calls as you like, for example:

@option('-n', '--name', dest='name') @option('-u', '--url', dest='url') def hello(name, url): print "hello", name, url Takes the same arguments as the Option constructor.

shell(func) Decorator that wraps function in shell command. This is equivalent to:

def _make_context(app): return dict(app=app)

manager.add_command("shell", Shell(make_context=_make_context)) The decorated function should take a single “app” argument, and return a dict.

For more sophisticated usage use the Shell class.

option(*args, **kwargs) Decorator to add an option to a function. Automatically registers the function - do not use together with @command. You can add as many @option calls as you like, for example:

@option('-n', '--name', dest='name') @option('-u', '--url', dest='url') def hello(name, url): print "hello", name, url Takes the same arguments as the Option constructor.

class flask_script.Command Base class for creating commands.

run() Runs a command. This must be implemented by the subclass. Should take arguments as configured by the Command options.

get_options() By default, returns self.option_list. Override if you need to do instance-specific configuration.

class flask_script.Shell(banner=None, make_context=None, use_ipython=True, use_bpython=True) Runs a Python shell inside Flask application context.

Parameters: banner – banner appearing at top of shell when started make_context – a callable returning a dict of variables used in the shell namespace. By default returns a dict consisting of just the app. use_bpython – use BPython shell if available, ignore if not. The BPython shell can be turned off in command line by passing the –no-bpython flag. use_ipython – use IPython shell if available, ignore if not. The IPython shell can be turned off in command line by passing the –no-ipython flag. class flask_script.Server(host='127.0.0.1', port=5000, use_debugger=True, use_reloader=True, threaded=False, processes=1, passthrough_errors=False, **options) Runs the Flask development server i.e. app.run()

Parameters: host – server host port – server port use_debugger – if False, will no longer use Werkzeug debugger. This can be overriden in the command line by passing the -d flag. use_reloader – if False, will no longer use auto-reloader. This can be overriden in the command line by passing the -r flag. threaded – should the process handle each request in a separate thread? processes – number of processes to spawn passthrough_errors – disable the error catching. This means that the server will die on errors but it can be useful to hook debuggers in (pdb etc.) options – werkzeug.run_simple() options. class flask_script.Option(*args, **kwargs) Stores positional and optional arguments for ArgumentParser.add_argument.

Parameters: name_or_flags – Either a name or a list of option strings, e.g. foo or -f, –foo action – The basic type of action to be taken when this argument is encountered at the command-line. nargs – The number of command-line arguments that should be consumed. const – A constant value required by some action and nargs selections. default – The value produced if the argument is absent from the command-line. type – The type to which the command-line arg should be converted. choices – A container of the allowable values for the argument. required – Whether or not the command-line option may be omitted (optionals only). help – A brief description of what the argument does. metavar – A name for the argument in usage messages. dest – The name of the attribute to be added to the object returned by parse_args(). class flask_script.Group(*options, **kwargs) Stores argument groups and mutually exclusive groups for ArgumentParser.add_argument_group http://argparse.googlecode.com/svn/trunk/doc/other-methods.html#argument-groups or ArgumentParser.add_mutually_exclusive_group http://argparse.googlecode.com/svn/trunk/doc/other-methods.html#add_mutually_exclusive_group.

Note: The title and description params cannot be used with the exclusive or required params.

Parameters: options – A list of Option classes to add to this group title – A string to use as the title of the argument group description – A string to use as the description of the argument group exclusive – A boolean indicating if this is an argument group or a mutually exclusive group required – A boolean indicating if this mutually exclusive group must have an option selected flask_script.prompt(name, default=None) Grab user input from command line.

Parameters: name – prompt text default – default value if no input provided. flask_script.prompt_bool(name, default=False, yes_choices=None, no_choices=None) Grabs user input from command line and converts to boolean value.

Parameters: name – prompt text default – default value if no input provided. yes_choices – default ‘y’, ‘yes’, ‘1’, ‘on’, ‘true’, ‘t’ no_choices – default ‘n’, ‘no’, ‘0’, ‘off’, ‘false’, ‘f’ flask_script.prompt_pass(name, default=None) Grabs hidden (password) input from command line.

Parameters: name – prompt text default – default value if no input provided. flask_script.prompt_choices(name, choices, default=None, resolve=<function lower at 0x7f3ba568ba28>, no_choice=('none', )) Grabs user input from command line from set of provided choices.

Parameters: name – prompt text choices – list or tuple of available choices. Choices may be single strings or (key, value) tuples. default – default value if no input provided. no_choice – acceptable list of strings for “null choice”

展开阅读全文
加载中
点击加入讨论🔥(1) 发布并加入讨论🔥
打赏
1 评论
29 收藏
8
分享
返回顶部
顶部