Flask-Script扩展提供向Flask插入外部脚本的功能。包括运行一个开发用的服务器,一个定制的 Python shell,设置数据库的脚本,cronjobs,以及其余的运行在web应用以外的命令行任务。html
Flask-Script和Flask自己的工做方式相似。只须要定义和添加能从命令行中被Manager实例调用的 命令便可。python
''' # 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()
只要像上面同样定义你本身的命令脚本,就能够在命令行中以下调用他们:git
''' python manage.py hello > hello
Flask-Script的源代码和bug追踪见 GitHubgithub
可使用pip或者easy_install安装装:web
''' pip install Flask-Script
或者下载最新开发版本:sql
''' git clone https://github.com/techniq/flask-script.git cd flask-script python setup.py develop
若是你使用virtualenv,需保证把Flask-Script和你的Flask应用安装在同一virtualenv环境下。shell
首先,建立一个Python模块运行你的命令脚本。能够任意起名,例如manage.py。数据库
无需把全部的命令都放在同一个文件里,例如,在一个大型项目中,能够把相关联的命令放在不一样的文件里。flask
在你的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实例的玩意儿。
其次,建立而且加入命令。有三种方法可建立命令:
下面是一个简单的例子,建立一个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实例。这是你能够设置传给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”