Flask Web 开发

Flask Web 开发

一、安装

Flask由3个主要依赖:路由、调试和Web服务器网关接口(WSGI, Web Server gateway interface)子系统由Werkzeug提供;模版系统由Jinjia2提供;命令行集成由Click提供。

1.1 虚拟环境

虚拟环境的安装和使用,请看本人的博客Python虚拟环境的安装

二、应用的基本机构

2.1 初始化

所有的Flask必须创建一个应用实例。

1
2
from flask import Flask
app = Flask(__name__)

2.2 路由和视图函数

客户端把请求发送给Web服务器,Web服务器再把请求发送给Flask应用实例。

处理URL和函数之间关系的程序成为路由

比如:

1
2
3
@app.route('/')
def index():
return '<h1>Hello World!</h1>'
1
2
3
4
def index():
return '<h1>Hello World!</h1>'

app.add_url_rule('/', 'index', index)
1
2
3
@app.route('/user/<name>')
def user(name):
return '<h1>Hello, {}!</h1>'.format(name)

2.3 请求-响应循环

2.3.1 应用和请求上下文

在Flask中有两种上下文:应用上下文请求上下文

Flask上下文全局变量

变量名 上下文 说明
current_app 应用上下文 当前应用的应用实例
g 应用上下文 处理请求时用作临时存储的对象, 每次请求都会重设这个变量
request 请求上下文 请求对象,封装了客户端发出的HTTP请求中的内容
session 请求上下文 用户会话,值为一个字典,存储请求之间需要“记住”的值
2.3.2 请求对象

Flask请求对象中最常用的属性和方法:

| 属性或方法 | 说明 |
| form | 一个字段,存储请求提交的所有表单字段 |

二、应用编程接口

Flask是开发表现层状态转移(REST,representational state transfer)架构Web服务的理想框架,因为Flask天生轻量。

2.1 REST简介

REST架构方式的六大特征:

  1. 客户端-服务端

    客户端和服务端之间必须要有明确的界线。

  2. 无状态

    客户端发出的请求这必须包含所有必要的信息。服务器不能在两次请求之间保存客户端的任何状态。

  3. 缓存

    服务器发出的响应可以标记为可缓存或不可缓存,这样处于优化目的,客户端(或客户端和服务器之间的中间服务)可以使用缓存。

  4. 接口统一

    客户端访问服务器资源时使用的协议必须一致、定义良好,且已经标准化。这是REST架构最复杂的一方面,涉及唯一的资源标识符、资源表述、客户端和服务器中间自描述的消息,以及超媒体(hypermedia)。

  5. 系统分层

    在客户端和服务器之间可以按需插入代理服务器、缓存或网关,以提高性能、稳定性和伸缩性。

  6. 按需编程

    客户端可以选择从服务器中下载代码,在客户端的上下文中执行。

2.1.1 资源就是一切

资源 是REST架构风格的核心概念。在REST结构中。资源是应用中你要着重关注的事物。

每个资源都要有唯一的URL表示。对HTTP协议来说,资源的标识符就是URL。

某一类资源的集合也要有一个URL。

API还可以为某一类资源的逻辑子集定义集合URL。

2.1.2 请求方法

客户端应用在建立起的资源URL上发送请求,使用请求方法表示期望的操作。

请求方法 目标 说明 HTTP状态码
GET 单个资源的URL 获取目标资源 200
GET 资源集合的URL 获取资源的集合(如果是服务器实现了分页,还可以是一叶中的资源) 200
POST 资源集合的URL 创建新资源,并将其加入目标集合。服务器为新资源指派URL,并在响应的Location首部中返回 201
PUT 单个资源的URL 修改一个现有资源。如果客户端能为资源指派URL,还可用来创建新资源 200或204
DELETE 单个资源的URL 删除一个资源 200或204
DELETE 资源集合的URL 删除目标集合中的所有资源 200或204
2.1.3 请求和响应主体

REST式Web服务常用的两种编码方式是Javascript对象表示方法(JSON,Javascript object notation)和可扩展标记语音(XML, extensible markup language)。

在设计良好的REST式API这,客户端只需要知道几个顶级资源的URL,其他资源的URL则从响应中包含的链接上发掘。

2.1.4 版本

在URL中加入Web服务的版本号有助于组织化管理新旧功能,让服务器能为新客户端提供新功能,同时继续支持旧版客户端。

提供多版本支持会增加服务器的维护负担,但在某些情况下,这是不破坏现有部署且能让应用不断发展的唯一方式。等到所有客户端都升级到新版之后,可以弃用旧版服务,待时机成熟后再把旧版完全删除。

2.2 使用Flask实现REST式Web服务

使用Flask创建REST式Web服务十分简单。使用少许细的route()装饰器及其methods可选参数可以声明服务器所提供资源URL的路由。处理JSON数据同样简单,请求中的JSON数据可以通过reques.get_json()转换成字典格式,而且可以使用Flask提供的辅助函数jsonify(),从Python字典中生成需要包含JSON的响应。

2.2.1 创建API蓝本

REST式API相关的路由式应用中一个自成一体的子集。因此,为了更好的组织代码、最好把这些路由放到一个独立的蓝本中。比如:

  • API蓝本结构:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    |- flasky
    |- app/
    |- api
    |- __init__flB.py
    |- users.py
    |- posts.py
    |- comments.py
    |- errors.py
    |- decorators.py
  • API蓝本的构造文件:

    1
    2
    3
    4
    from flask import Blueprint
    api = Blueprint('api', __name__)

    from . import posts, users, comments, errors
  • 注册API蓝本

    1
    2
    3
    4
    5
    def create_app(config_name):
    # ...
    from .api import api as api_blueprint
    app.register_blueprint(api_blueprint, url_prefix='/api/v1')
    # ...

注册API蓝本时指定了一个URL前缀,因此蓝本中所有路由器的URL都以/api/v1开头。注册蓝本时设置前缀是好主意,无需在每个路由中硬编码版本号。

2.2.2 错误处理

REST式Web服务讲请求的状态告知客户端时,会在响应中发送适当的HTTP状态码,并将额外信息放入响应主体。客户端从Web服务得到的常见状态码如下所示:

HTTP状态码 名称 说明
200 OK 请求成功
201 Created 请求成功,而且创建一个新资源
202 Accepted 请求已接收,但仍在处理中,将异步处理
204 No Content 请求处理成功,但是返回的响应没有数据
400 Bad Request 请求无效或不一致
401 Unauthorized 请求未包含身份验证信息,或者提供的凭证无效
403 Foridden 请求这发送的身份验证凭据无权访问目标
404 Not Found URL对应的资源不存在
405 Method Not Allowed 指定资源不支持请求使用的方法
500 Internal Server Error 处理请求的过程这发生意外错误