0%

Flask扩展Flask-Script文档中文翻译

本文转载自https://my.oschina.net/lijsf/blog/158828



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


Flask-Script扩展提供向Flask插入外部脚本的功能。包括运行一个开发用的服务器,一个定制的 Python shell,设置数据库的脚本,cronjobs,以及其他的运行在web应用之外的命令行任务。
Flask-Script和Flask本身的工作方式类似。只需要定义和添加能从命令行中被Manager实例调用的命令即可。
1
2
3
4
5
6
7
8
9
10
11
12
# 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

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类将追踪所有的在命令行中调用的命令和处理过程的调用运行 情况:
1
2
3
4
5
6
7
8
9
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”。
1
2
3
4
5
6
7
from flask.ext.script import Command

class Hello(Command):
"prints hello world"

def run(self):
print "hello world"
再把上面创建的Hello命令加入Manager实例:
1
manager.add_command('hello', Hello())
很明显,上面的语句需要在manager.run()之前运行。现在执行下面的命令:

python manage.py hello
hello world

也可传给Command实例的run方法一个字典:
1
manager.run({'hello' : Hello()})
Command class 必须定义一个run方法。定义的位置和参数依赖于你的定义的命令的参数。详见下文。
运行下面的命令获取可以使用的命令及其描述的列表:

python manage.py

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

python manage.py runserver -h

上面的第一种方法是最适用的,但也是最麻烦的。对于简单的命令,只需要使用Command实例的@command修饰符。
1
2
3
4
@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修饰符适用于更精细的命令行控制:
1
2
3
@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属性。
1
2
3
4
5
6
7
8
9
10
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方法,这将在希望依赖运行实例返回值来得到参数时非常有效。
1
2
3
4
5
6
7
8
9
10
11
12
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修饰符,参数将直接自动的从函数的参数中获取:
1
2
3
4
5
6
7
8
9
10
11
12
13
@manager.command
def hello(name):
print "hello", name
```

> python manage.py hello Joe
> hello Joe

##### 或者使用可选参数:
```python
@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值,例如:
1
2
3
4
5
6
@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是更好的选择:
1
2
3
4
5
6
7
8
9
10
11
12
13
@manager.option('-n', '--name', dest='name', default='joe')
def hello(name):
print "hello", name
```
##### 可以增加更多的选项参数:
```python
@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应用的配置项以便一条命令即可完成。例如,你可以使用一个标 志来为你的应用设置配置文件。例如:
1
2
3
4
5
6
7
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的参数一样。
1
manager.add_option('-c', '--config', dest='config', required=False)
同其他Flask-Script配置一样,可以在任何地方使用上面的语句,但确保在manager.run()之前执行。
假设你有下面的命令:
1
2
3
4
5
6
@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函数来获取用户在命令行中的输入,例如:
1
2
3
4
5
6
7
8
9
10
11
12
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。
1
2
3
4
5
6
7
8
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 获取详细信息。你也可以在构造函数中重新定义默认 行为:
1
server = Server(host="0.0.0.0", port=9000)
无需赘言,开发Server不是为生产环境准备的。
Shell名令启动一个Python shell。可以穿进去一个make_context参数,这个参数必须是一个字典。默认情况下,将返回你的 Flask应用实例。
1
2
3
4
5
6
7
8
9
10
11
12
13
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。
1
shell = Shell(use_ipython=False)
也有一个shell修饰符,你可以在函数上下文中使用。
1
2
3
@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参数,则这些命令不会被载入。
1
manager = Manager(app, with_default_commands=False)