标签:
Flask应用需要创建应用实例。 Web服务器通过Web Server Gateway Interface (WSGI)协议把从客户端接收到的请求传递给该对象。应用程序实例是Flask类对象,通常创建如下:
from flask import Flask app = Flask(__name__)
Flask类的构造函数唯一的参数是应用的主模块名或包名,用于确定应用的根目录。对于大多数应用程序,使用Python的__name__变量即可。
客户端如Web浏览器发送请求到Web服务器,再转发到Flask应用实例。应用程序实例需要知道每个URL执行哪些代码,因此它保留URL到Python函数的映射。URL和处理函数的关联叫route(路由)。
添加路由最方便的方法是通过应用实例的装饰器app.route,注册函数为路由。比如:
@app.route(‘/‘)def index(): return ‘<h1>Hello World!</h1>‘
装饰器是Python语言的标准功能,可以修改的函数的行为。常用装饰器注册函数为事件处理器。上面的index叫做视图函数。
处理变量:
@app.route(‘/user/<name>‘)def user(name): return ‘<h1>Hello, %s!</h1>‘ % name
默认是字符串,还支持int, float, 和path。比如/user/<int:id>。path和字符串类似,但是不把斜杠当做分隔符。
if __name__ == ‘__main__‘: app.run(debug=True)
此时如果访问不存在的网址,就会返回404。
from flask import Flask app = Flask(__name__) @app.route(‘/‘) def index(): return ‘<h1>Hello World!</h1>‘ @app.route(‘/user/<name>‘) def user(name): return ‘<h1>Hello, %s!</h1>‘ % name if __name__ == ‘__main__‘: app.run(debug=True, host=‘0.0.0.0‘, port=80)
执行服务器端:
#python hello.py * Running on http://0.0.0.0:80/ * Restarting with reloader 192.168.0.231 - - [01/Sep/2014 05:03:41] "GET /user/Andrew HTTP/1.1" 200 - 192.168.0.231 - - [01/Sep/2014 05:03:45] "GET / HTTP/1.1" 200 -
执行客户端:
#curl http://192.168.0.233/user/Andrew <h1>Hello, Andrew!</h1> root@localhost:[/root]# root@localhost:[/root]#curl http://192.168.0.233 <h1>Hello World!</h1>
应用和请求上下文
Flask使用上下文临时存储一些对象。比如request对象封装了客户端的HTTP请求。Flask通过context把请求数据放入全局空间。因此可以这样操作。
from flask import Flask from flask import request app = Flask(__name__) @app.route(‘/‘)def index(): user_agent = request.headers.get(‘User-Agent‘) return ‘<p>Your browser is %s</p>‘ % user_agent if __name__ == ‘__main__‘: app.run(debug=True,host=‘0.0.0.0‘,port=80)
执行结果:
$ curl http://192.168.1.100 <p>Your browser is curl/7.35.0</p> # 浏览器执行Your browser is Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:28.0) Gecko/20100101 Firefox/28.0
注意不同线程看到是不同的request。全局的上下文如下:
变量名 | 上下文 | 说明 |
current_app | 应用上下文 | 活动应用的实例。 |
g | 应用上下文 | 应用处理时使用的临时存储,每次请求都会重置 |
request | 请求上下文 | 封装了客户端的HTTP请求的请求对象 |
session | 请求上下文 | 用户session,应用可以存储值的字典,适用于不同请求之间的通用数据 |
push之后方可看到这四个变量。
>>> from hello import app >>> from flask import current_app >>> current_app.name Traceback (most recent call last):...RuntimeError: working outside of application context >>> app_ctx = app.app_context() >>> app_ctx.push() >>> current_app.name ‘hello‘ >>> app_ctx.pop()
请求分发
app.route添加网址映射,等效于方法app.add_url_rule()。app.add_url_rule()存储了url映射。
(venv) $ python >>> from hello import app >>> app.url_map Map([<Rule ‘/‘ (HEAD, OPTIONS, GET) -> index>, <Rule ‘/static/<filename>‘ (HEAD, OPTIONS, GET) -> static>, <Rule ‘/user/<name>‘ (HEAD, OPTIONS, GET) -> user>])
请求Hook
hook适用于一些通用性的操作。目前有before_first_request、before_request、after_request(有异常不会执行)、teardown_request(有异常也会执行)。hook和视图函数之前可以使用全局变量g传递参数。
响应
默认返回状态码200,可以修改:
@app.route(‘/‘)def index(): return ‘<h1>Bad Request</h1>‘, 400
执行结果:
$ curl http://127.0.0.1<h1>Bad Request</h1>
可以添加头的字典作为第3个参数,但是很少使用。另外也可以返回Response对象。make_response()接纳1-3个参数,适用于视图函数定制响应,比如:
from flask import make_response @app.route(‘/‘)def index(): response = make_response(‘<h1>This document carries a cookie!</h1>‘) response.set_cookie(‘answer‘, ‘42‘) return response
另有特殊的响应redirect,多用于表单。redirect返回状态码302和URL。也可以直接return 3个值或Response对象,但是redirect更快捷。
from flask import Flask app = Flask(__name__) from flask import redirect @app.route(‘/‘)def index(): return redirect(‘http://automationtesting.sinaapp.com/‘) if __name__ == ‘__main__‘: app.run(debug=True,host=‘0.0.0.0‘,port=80)
执行结果:
$ curl http://127.0.0.1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> <title>Redirecting...</title> <h1>Redirecting...</h1> <p>You should be redirected automatically to target URL: <a href="http://automationtesting.sinaapp.com/">http://automationtesting.sinaapp.com/</a>. If not click the link
用浏览器访问通常会直接跳转。
abort也是特殊响应,用于错误处理。它直接产生异常,把控制交给web server。
from flask import abort @app.route(‘/user/<id>‘) def get_user(id): user = load_user(id) if not user: abort(404) return ‘<h1>Hello, %s</h1>‘ % user.name
简化的实例:
from flask import Flask app = Flask(__name__) from flask import abort @app.route(‘/user/<id>‘) def get_user(id): abort(404) return ‘<h1>Hello, %s</h1>‘ % user.name if __name__ == ‘__main__‘: app.run(debug=True,host=‘0.0.0.0‘,port=80)
执行结果:
$ curl http://127.0.0.1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> <title>404 Not Found</title> <h1>Not Found</h1> <p>The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.</p>
Flask支持大量的启动配置选项,方法是将它们作为参数传递给app.run()。Flask-Script扩展增加了命令行参数支持。
# pip install flask-scriptCollecting flask-script Downloading Flask-Script-2.0.5.tar.gz (42kB) 100% |################################| 45kB 236kB/s Requirement already satisfied (use --upgrade to upgrade): Flask in /usr/local/lib/python2.7/dist-packages (from flask-script)Requirement already satisfied (use --upgrade to upgrade): Werkzeug>=0.7 in /usr/local/lib/python2.7/dist-packages (from Flask->flask-script)Requirement already satisfied (use --upgrade to upgrade): Jinja2>=2.4 in /usr/local/lib/python2.7/dist-packages (from Flask->flask-script)Requirement already satisfied (use --upgrade to upgrade): itsdangerous>=0.21 in /usr/local/lib/python2.7/dist-packages (from Flask->flask-script)Requirement already satisfied (use --upgrade to upgrade): markupsafe in /usr/local/lib/python2.7/dist-packages (from Jinja2>=2.4->Flask->flask-script)Installing collected packages: flask-script Running setup.py install for flask-script Successfully installed flask-script-2.0.5
from flask import Flask from flask.ext.script import Manager app = Flask(__name__) manager = Manager(app) @app.route(‘/‘)def index(): return ‘<h1>Hello World!</h1>‘ @app.route(‘/user/<name>‘)def user(name): return ‘<h1>Hello, %s!</h1>‘ % name if __name__ == ‘__main__‘: manager.run()
用法:
]# python hello.pyusage: hello.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# python hello.py runserver --helpusage: hello.py runserver [-?] [-h HOST] [-p PORT] [--threaded] [--processes PROCESSES] [--passthrough-errors] [-d] [-D] [-r] [-R]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{‘const‘: True, ‘help‘: ‘monitor Python files for changes (not 100% safe for production use)‘, ‘option_strings‘: [‘-r‘, ‘--reload‘], ‘dest‘: ‘use_reloader‘, ‘required‘: False, ‘nargs‘: 0, ‘choices‘: None, ‘default‘: None, ‘prog‘: ‘hello.py runserver‘, ‘container‘: <argparse._ArgumentGroup object at 0x21dc150>, ‘type‘: None, ‘metavar‘: None}afe for production use) -R, --no-reload do not monitor Python files for changes# 默认是监听localhost# python hello.py runserver --host 0.0.0.0 -p 80 * Running on http://0.0.0.0:80/
标签:
原文地址:http://my.oschina.net/u/1433482/blog/463952