码迷,mamicode.com
首页 > Web开发 > 详细

flask web开发笔记 -- 快速入门

时间:2015-06-08 07:21:38      阅读:237      评论:0      收藏:0      [点我收藏+]

标签:

flask web开发笔记 -- 快速入门 

初始化

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扩展

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/


参考资料


flask web开发笔记 -- 快速入门

标签:

原文地址:http://my.oschina.net/u/1433482/blog/463952

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!