MK
摩柯社区 - 一个极简的技术知识社区
AI 面试

Python使用Flask构建RESTful API

2023-02-033.6k 阅读

一、Flask 简介

Flask 是一个轻量级的 Python Web 框架,它由 Armin Ronacher 开发并于 2010 年发布。Flask 基于 Werkzeug WSGI 工具包和 Jinja2 模板引擎,为 Python 开发者提供了一个简洁而灵活的方式来构建 Web 应用程序。

(一)Flask 的特点

  1. 轻量级:Flask 核心功能简单,没有过多的内置组件和复杂的架构,开发者可以根据项目需求自由选择和集成其他扩展库。例如,在构建小型的 API 服务时,无需处理庞大框架带来的冗余代码和复杂配置,能够快速实现功能。
  2. 灵活性:它允许开发者自由决定应用的架构和使用的组件。比如在数据库连接方面,开发者既可以选择 SQLite 用于简单项目,也可以无缝切换到 MySQL 或 PostgreSQL 等更强大的数据库,只需引入相应的数据库连接库并进行简单配置即可。
  3. 易于上手:对于初学者而言,Flask 的文档简洁明了,代码结构直观。通过简单的几行代码,就可以创建一个基本的 Web 应用,这使得快速搭建原型和学习 Web 开发变得容易。

(二)安装 Flask

在开始使用 Flask 构建 RESTful API 之前,需要先安装 Flask 库。假设你已经安装了 Python 和 pip(Python 的包管理工具),可以在命令行中执行以下命令进行安装:

pip install flask

如果使用的是 Python 虚拟环境(强烈推荐),可以先创建并激活虚拟环境,然后再进行安装。例如,使用 venv 模块创建虚拟环境:

python -m venv myenv
source myenv/bin/activate  # 在 Windows 上使用 `myenv\Scripts\activate`
pip install flask

二、RESTful API 基础

(一)什么是 RESTful API

REST(Representational State Transfer)是一种软件架构风格,由 Roy Fielding 在 2000 年的博士论文中提出。RESTful API 是遵循 REST 原则设计的 API,用于在网络中进行资源的传输和交互。

(二)RESTful API 的设计原则

  1. 资源:在 RESTful 架构中,一切皆为资源。资源可以是数据库中的一条记录、一个文件、一个图片等。每个资源都有唯一的标识符(URI)。例如,一个博客文章资源可以通过 /articles/1 这样的 URI 来表示,其中 1 是文章的唯一标识。
  2. 统一接口:RESTful API 使用统一的接口来操作资源,主要包括 GET(获取资源)、POST(创建资源)、PUT(更新资源)、DELETE(删除资源)等 HTTP 方法。以博客文章为例,使用 GET 方法获取文章内容,POST 方法创建新文章,PUT 方法更新文章,DELETE 方法删除文章。
  3. 状态转移:客户端通过 HTTP 请求与服务器进行交互,每次请求会导致服务器上资源状态的改变,即状态转移。例如,客户端发送一个 POST 请求创建新文章,服务器接收到请求后,文章资源从不存在变为存在,这就是状态的转移。

(三)为什么使用 RESTful API

  1. 可扩展性:RESTful 架构的设计原则使得 API 易于扩展。随着业务的增长,可以方便地添加新的资源和功能,而不会对现有 API 造成较大影响。例如,在一个电商 API 中,最初只有商品资源,随着业务发展需要添加订单资源,按照 RESTful 原则进行设计,很容易将订单资源融入到现有的 API 体系中。
  2. 跨平台和语言无关性:由于 RESTful API 基于 HTTP 协议,它可以被各种平台和编程语言的客户端访问。无论是 Web 应用、移动应用还是桌面应用,只要能够发送 HTTP 请求,就可以与 RESTful API 进行交互。

三、使用 Flask 构建 RESTful API

(一)创建基本的 Flask 应用

首先,创建一个简单的 Flask 应用,代码如下:

from flask import Flask

app = Flask(__name__)


@app.route('/')
def hello_world():
    return 'Hello, World!'


if __name__ == '__main__':
    app.run(debug=True)

在上述代码中:

  1. 导入 Flask 类,它是 Flask 应用的核心。
  2. 创建一个 Flask 实例 app__name__ 是 Python 中的一个特殊变量,用于标识模块名,Flask 用它来确定应用的根路径。
  3. 使用 @app.route 装饰器定义一个路由,这里 '/' 表示根路径,当客户端访问根路径时,会执行 hello_world 函数并返回 'Hello, World!'
  4. if __name__ == '__main__': 确保只有当该脚本直接运行时,才启动 Flask 应用。app.run(debug=True) 以调试模式运行应用,这样在代码修改后应用会自动重启,方便开发调试。

(二)定义 RESTful API 路由

接下来,我们开始定义 RESTful API 的路由。假设我们要构建一个简单的用户管理 API,包含获取所有用户、获取单个用户、创建用户、更新用户和删除用户的功能。

  1. 获取所有用户
from flask import Flask, jsonify

app = Flask(__name__)

# 模拟用户数据
users = [
    {'id': 1, 'name': 'Alice'},
    {'id': 2, 'name': 'Bob'}
]


@app.route('/users', methods=['GET'])
def get_all_users():
    return jsonify(users)


if __name__ == '__main__':
    app.run(debug=True)

在上述代码中:

  • 导入 jsonify 函数,它用于将 Python 数据结构转换为 JSON 格式并作为 HTTP 响应返回。
  • 定义了一个 users 列表来模拟用户数据。
  • 使用 @app.route('/users', methods=['GET']) 装饰器定义了一个路由,当客户端使用 GET 方法访问 /users 路径时,会执行 get_all_users 函数,该函数返回所有用户数据的 JSON 表示。
  1. 获取单个用户
@app.route('/users/<int:user_id>', methods=['GET'])
def get_user(user_id):
    user = next((user for user in users if user['id'] == user_id), None)
    if user is None:
        return jsonify({'message': 'User not found'}), 404
    return jsonify(user)

这里使用了动态路由,<int:user_id> 表示接受一个整数类型的参数 user_idnext 函数用于在 users 列表中查找匹配 user_id 的用户,如果找不到则返回 None,此时返回一个包含错误信息的 JSON 响应,状态码为 404(表示资源未找到)。如果找到用户,则返回该用户的 JSON 表示。

  1. 创建用户
from flask import request

@app.route('/users', methods=['POST'])
def create_user():
    data = request.get_json()
    new_user = {
        'id': len(users) + 1,
        'name': data.get('name')
    }
    users.append(new_user)
    return jsonify(new_user), 201

导入 request 对象,它用于获取客户端发送的请求数据。当客户端使用 POST 方法访问 /users 路径时,create_user 函数通过 request.get_json() 获取 JSON 格式的请求数据,创建一个新用户并添加到 users 列表中,然后返回新创建用户的 JSON 表示,状态码为 201(表示资源已创建)。

  1. 更新用户
@app.route('/users/<int:user_id>', methods=['PUT'])
def update_user(user_id):
    user = next((user for user in users if user['id'] == user_id), None)
    if user is None:
        return jsonify({'message': 'User not found'}), 404
    data = request.get_json()
    user['name'] = data.get('name', user['name'])
    return jsonify(user)

当客户端使用 PUT 方法访问 /users/<user_id> 路径时,先查找对应的用户。如果找到用户,获取请求中的 JSON 数据并更新用户的 name 字段(如果请求数据中没有 name 字段,则保持原有的 name),最后返回更新后的用户 JSON 表示。

  1. 删除用户
@app.route('/users/<int:user_id>', methods=['DELETE'])
def delete_user(user_id):
    user = next((user for user in users if user['id'] == user_id), None)
    if user is None:
        return jsonify({'message': 'User not found'}), 404
    users.remove(user)
    return jsonify({'message': 'User deleted'})

当客户端使用 DELETE 方法访问 /users/<user_id> 路径时,查找并删除对应的用户,然后返回一个表示用户已删除的 JSON 响应。

(三)请求和响应处理

  1. 请求处理
    • 获取请求数据:如前面创建用户和更新用户的示例中,使用 request.get_json() 来获取 JSON 格式的请求数据。如果客户端发送的是表单数据,可以使用 request.form 来获取。例如:
@app.route('/submit', methods=['POST'])
def submit_form():
    username = request.form.get('username')
    password = request.form.get('password')
    return jsonify({'username': username, 'password': password})
- **请求参数验证**:在实际应用中,需要对请求数据进行验证。可以使用第三方库如 `wtforms` 或自定义验证逻辑。例如,验证创建用户时 `name` 字段是否为空:
@app.route('/users', methods=['POST'])
def create_user():
    data = request.get_json()
    if not data or 'name' not in data:
        return jsonify({'message': 'Name is required'}), 400
    new_user = {
        'id': len(users) + 1,
        'name': data['name']
    }
    users.append(new_user)
    return jsonify(new_user), 201
  1. 响应处理
    • 状态码设置:如前面示例中,根据不同的操作结果设置合适的状态码。200 表示成功,201 表示资源已创建,400 表示客户端请求错误,404 表示资源未找到等。
    • 响应格式:通常使用 JSON 格式作为 API 的响应格式,通过 jsonify 函数可以方便地将 Python 数据结构转换为 JSON 响应。如果需要返回其他格式,如 XML,可以使用相应的库进行转换。例如,使用 xmltodictflask 结合返回 XML 响应:
import xmltodict
from flask import Flask, Response

app = Flask(__name__)


@app.route('/xml')
def get_xml():
    data = {'message': 'This is an XML response'}
    xml_data = xmltodict.unparse(data)
    return Response(xml_data, mimetype='application/xml')

四、Flask 扩展

(一)Flask - SQLAlchemy

  1. 简介:Flask - SQLAlchemy 是 Flask 应用中操作数据库的扩展库,它为 Flask 提供了 SQLAlchemy 的集成。SQLAlchemy 是一个强大的数据库抽象层库,支持多种数据库,如 SQLite、MySQL、PostgreSQL 等。使用 Flask - SQLAlchemy 可以方便地进行数据库模型定义、查询、插入、更新和删除等操作。

  2. 安装与配置

    • 安装:
pip install flask - sqlalchemy
- 配置:在 Flask 应用中,需要对 Flask - SQLAlchemy 进行配置。假设使用 SQLite 数据库,配置如下:
from flask import Flask
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] ='sqlite:///test.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

db = SQLAlchemy(app)

这里设置了数据库 URI 为 sqlite:///test.db,表示使用 SQLite 数据库并将数据存储在 test.db 文件中。SQLALCHEMY_TRACK_MODIFICATIONS 设置为 False 以关闭对模型修改的跟踪,减少内存消耗。

  1. 定义数据库模型:以用户管理为例,定义用户模型如下:
class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(50))


    def __repr__(self):
        return f'<User {self.name}>'

在上述代码中,User 类继承自 db.Model,定义了 idname 两个字段,id 是主键,name 是字符串类型,最大长度为 50。__repr__ 方法用于定义对象的字符串表示形式,方便调试。

  1. 数据库操作
    • 创建数据库
with app.app_context():
    db.create_all()

在应用上下文环境中,使用 db.create_all() 方法创建数据库表。 - 插入数据

new_user = User(name='Charlie')
with app.app_context():
    db.session.add(new_user)
    db.session.commit()

创建一个新的 User 对象,然后将其添加到数据库会话中并提交会话,将数据插入到数据库。 - 查询数据

with app.app_context():
    users = User.query.all()
    for user in users:
        print(user.name)

使用 User.query.all() 查询所有用户,并遍历输出用户的名字。 - 更新数据

with app.app_context():
    user = User.query.filter_by(name='Charlie').first()
    if user:
        user.name = 'Charlie Updated'
        db.session.commit()

先查询名字为 Charlie 的用户,然后更新其名字并提交会话。 - 删除数据

with app.app_context():
    user = User.query.filter_by(name='Charlie Updated').first()
    if user:
        db.session.delete(user)
        db.session.commit()

查询并删除名字为 Charlie Updated 的用户。

(二)Flask - CORS

  1. 简介:CORS(Cross - Origin Resource Sharing)即跨域资源共享,是一种机制,它使用额外的 HTTP 头来告诉浏览器允许跨域请求。在开发 API 时,经常会遇到前端应用和 API 部署在不同域名下的情况,这时就需要处理跨域问题。Flask - CORS 是 Flask 应用中处理 CORS 的扩展库。

  2. 安装与配置

    • 安装:
pip install flask - cors
- 配置:在 Flask 应用中,简单配置如下:
from flask import Flask
from flask_cors import CORS

app = Flask(__name__)
CORS(app)

上述代码使用 CORS(app) 对整个 Flask 应用启用 CORS,允许所有来源的跨域请求。如果需要更精细的控制,可以设置 CORS 的参数。例如,只允许特定来源的请求:

CORS(app, origins=['http://localhost:3000'])

这里只允许 http://localhost:3000 来源的跨域请求。

五、API 测试与部署

(一)API 测试

  1. 使用 Postman 测试:Postman 是一款流行的 API 测试工具。安装并打开 Postman 后:

    • 获取所有用户:在 Postman 中,设置请求方法为 GET,URL 为 http://127.0.0.1:5000/users(假设 Flask 应用在本地 5000 端口运行),点击 Send 按钮,即可看到返回的所有用户数据。
    • 获取单个用户:设置请求方法为 GET,URL 为 http://127.0.0.1:5000/users/1(假设用户 id 为 1),发送请求查看返回的单个用户数据。
    • 创建用户:设置请求方法为 POST,URL 为 http://127.0.0.1:5000/users,在 Body 选项卡中选择 JSON 格式,并输入创建用户的数据,如 {"name": "David"},点击 Send 按钮,查看创建用户的响应。
    • 更新用户:设置请求方法为 PUT,URL 为 http://127.0.0.1:5000/users/1,在 Body 选项卡中输入更新的数据,发送请求查看更新后的用户数据。
    • 删除用户:设置请求方法为 DELETE,URL 为 http://127.0.0.1:5000/users/1,发送请求查看删除操作的响应。
  2. 使用 Python 代码测试:可以使用 requests 库在 Python 代码中进行 API 测试。例如:

import requests


# 获取所有用户
response = requests.get('http://127.0.0.1:5000/users')
print(response.json())


# 创建用户
data = {'name': 'Eva'}
response = requests.post('http://127.0.0.1:5000/users', json=data)
print(response.json())


# 获取单个用户
response = requests.get('http://127.0.0.1:5000/users/3')  # 假设新创建用户 id 为 3
print(response.json())


# 更新用户
data = {'name': 'Eva Updated'}
response = requests.put('http://127.0.0.1:5000/users/3', json=data)
print(response.json())


# 删除用户
response = requests.delete('http://127.0.0.1:5000/users/3')
print(response.json())

(二)API 部署

  1. 部署到 Heroku:Heroku 是一个云平台即服务(PaaS),可以方便地部署 Flask 应用。
    • 创建 Heroku 账号:访问 Heroku 官网并注册账号。
    • 安装 Heroku CLI:根据操作系统安装 Heroku 命令行工具。
    • 准备项目:在项目根目录下创建一个 requirements.txt 文件,列出项目依赖的库,例如:
Flask==2.0.1
Flask - SQLAlchemy==2.5.1

可以使用 pip freeze > requirements.txt 命令自动生成。同时,创建一个 Procfile 文件,内容如下:

web: gunicorn app:app

这里假设 Flask 应用的入口文件是 app.py,应用实例名为 app。如果应用入口文件或实例名不同,需相应修改。 - 初始化 Git 仓库:如果项目还没有初始化 Git 仓库,在项目根目录下执行 git init,然后添加文件并提交:

git add.
git commit -m "Initial commit"
- **部署到 Heroku**:登录 Heroku CLI,执行 `heroku login` 并输入账号密码。然后执行 `heroku create` 创建一个 Heroku 应用,得到应用的 URL。最后执行 `git push heroku main`(如果使用的是主分支)将代码推送到 Heroku 进行部署。

2. 部署到 AWS Elastic Beanstalk:AWS Elastic Beanstalk 是亚马逊云服务提供的一个易于使用的云平台,用于部署、扩展和管理应用程序。 - 创建 AWS 账号:访问 AWS 官网并注册账号。 - 安装 AWS CLI:根据操作系统安装 AWS 命令行工具,并配置 AWS 凭证。 - 创建 Elastic Beanstalk 环境:在 AWS 管理控制台中,找到 Elastic Beanstalk 服务,创建一个新的环境。选择 Python 平台,并上传项目代码压缩包(或关联 Git 仓库)。按照向导完成环境创建,Elastic Beanstalk 会自动部署应用并提供访问 URL。

通过以上步骤,我们可以使用 Flask 构建功能齐全的 RESTful API,并进行测试和部署,使其能够在实际应用中提供服务。在实际开发中,还需要考虑安全性、性能优化等更多方面的问题,以确保 API 的可靠性和稳定性。