一个简单的Flask Web服务器
1. 初始化
Flask程序必须创建一个程序实例。
Web服务器把接收到的所有客户端请求,转交给Web服务器网关接口对象处理。
一般套路是这样的:
from flask import Flask
app = Flask(__name__)
这里创建Flask app实例(Flask的构造函数),需要提供的参数只有一个,就是程序主模块或包的名字,一般就是Python的name变量。
2. 路由和视图函数
客户端的请求经由Web服务器转发给Flask程序实例。程序实例需要URL到具体代码的映射关系。这个映射关系称为路由。
Flask中最简单的路由定义方式是app.route修饰器。
@app.route('/')
def index():
# 这里是demo,实际这么返回响应字符串是不规范的
return '<h1>Hello World!</h1>'
这里所谓的修饰器,是Python语言的特性,可以规定函数的不同行为,比如类中的静态方法就需要增加修饰器 @staticmethod。
上面的路由定义,把根路径和index函数关联起来,如果部署程序的服务器域名是 www.example.com,那么浏览器中输入 http://www.example.com,就会触发这个函数。
函数的返回值称为响应,是客户端接收到的内容。这样如果客户端是Web浏览器,响应就是给客户看的文档。
index()这样的函数,叫做视图函数(view function),返回的响应可以包含HTML的简单字符串,也可以是复杂的表单。
视图函数的参数
URL是可以含有可变部分的,比如 http://www.example.com/user/,那么这个可变的部分是可以作为视图函数的参数的:
@app.route('/user/<name>')
def user(name):
return '<h1>Hello, %s!</h1>' % name
动态部分默认是字符串,也可以指定特别的类型。比如 会匹配id是整数的URL。类似的还 float 和 path。path和字符串的区别是,path不会被斜线分隔。
3. 启动服务器
用 run 方法启动Flask集成的Web服务器:
if __name__ == '__main__':
app.run(debug=True)
Flask提供的Web服务器并不适合生产环境,生产环境的Web服务器会有专门的章节介绍。
4. 设置Web服务器IP
我的工作环境是云主机,不能在linux主机上启动浏览器。那么需要修改app.run的参数,让我能够从桌面浏览器访问云主机的web服务器。
hello.py:
from flask import Flask
app = Flask(__name__)
@app.route('/')
def index():
return '<h1>Hello World!</h1>'
if __name__ == '__main__':
app.run(host="10.xxx.xxx.184", port=80, debug=True)
运行py脚本:
[[email protected] src]$ python hello.py
* Running on http://10.xxx.xxx.184:80/ (Press CTRL+C to quit)
* Restarting with stat
* Debugger is active!
* Debugger PIN: 769-409-611
就可以通过桌面电脑的浏览器,从 http://10.xxx.xxx.184:80/ 访问网页
5 请求-响应
5.1 上下文
Flask收到客户端请求以后,会把请求发给视图函数。
视图函数如何得知请求的一些信息呢,可以通过请求上下文,可以像变量一样使用上下文对象。
变量名 | 说明 |
---|---|
request | 请求对象,客户端发来的HTTP请求 |
session | 用户会话,请求之间需要记录的值的词典 |
举个例子:
from flask import request
@app.route('/')
def index():
user_agent = request.headers.get('User-Agent')
return '<p>Your browser is %s</p>' % user_agent
request这样的上下文变量,是线程全局的,不同的线程,具有不同的request
5.2 状态码
视图函数返回的是一个HTML字符串,除了这个字符串,HTTP还需要一个状态码。
Flask默认的HTTP状态码是200。
如果需要返回其他的状态码,通过return的第二个返回值设置:
@app.route('/')
def index():
return '<h1>Bad Request</h1>', 400
查看flask的log可以看到结果:
* Running on http://10.xxx.xxx.184:80/ (Press CTRL+C to quit)
* Restarting with stat
* Debugger is active!
* Debugger PIN: 769-409-611
10.xxx.xxx.79 - - [11/Jan/2018 15:39:08] "GET / HTTP/1.1" 400 -
5.3 重定向
通过redirect()函数,可以实现重定向:
from flask import redirect
@app.route('/')
def index():
return redirect('http://www.baidu.com')
再次反问这个页面,会重定向到百度了,状态码是302:
10.xxx.xxx.79 - - [11/Jan/2018 15:44:53] "GET / HTTP/1.1" 302 -