杰瑞科技汇

Flask API开发如何快速上手?

目录

  1. Flask 简介:为什么选择 Flask?
  2. 环境准备:安装 Python、Flask 和虚拟环境。
  3. 第一个 "Hello World" API:创建最简单的 API 端点。
  4. 核心概念详解
    • 路由
    • 请求
    • 响应
    • 视图函数
  5. 构建一个功能完整的 RESTful API:一个简单的待办事项列表 API。
    • 设计 API 端点
    • 使用 Flask-RESTful 扩展简化开发
    • 数据存储(使用 Python 列表)
    • 实现增删改查操作
  6. 数据验证:使用 Flask-Requestmarshmallow
  7. 数据库集成:使用 Flask-SQLAlchemy 与 SQLite。
  8. 进阶主题
    • 项目结构(蓝图 Blueprints)
    • 部署(使用 Gunicorn)
  9. 总结与最佳实践

Flask 简介

Flask 是一个用 Python 编写的轻量级 Web 应用框架,它的核心非常简单,但通过强大的扩展生态系统,你可以轻松地为其添加各种复杂功能,如数据库集成、用户认证、表单处理等。

Flask API开发如何快速上手?-图1
(图片来源网络,侵删)

选择 Flask 的理由:

  • 轻量级:安装简单,核心代码少,学习曲线平缓。
  • 灵活:你只使用你需要的部分,不会被框架束缚。
  • 强大的扩展:社区活跃,有大量高质量的扩展(如 Flask-SQLAlchemy, Flask-Login, Flask-RESTful)。
  • 文档完善:官方文档清晰易懂,是学习的最佳资源。

环境准备

在开始之前,请确保你已经安装了 Python (推荐 3.8+)。

1 虚拟环境

为了隔离项目依赖,强烈建议使用虚拟环境。

# 创建一个名为 'venv' 的虚拟环境
python -m venv venv
# 激活虚拟环境
# Windows:
venv\Scripts\activate
# macOS/Linux:
source venv/bin/activate

激活后,你的终端提示符前会出现 (venv)

Flask API开发如何快速上手?-图2
(图片来源网络,侵删)

2 安装 Flask

在激活的虚拟环境中,使用 pip 安装 Flask。

pip install Flask

第一个 "Hello World" API

让我们创建一个最简单的 API,它返回一个 JSON 响应。

  1. 创建一个名为 app.py 的文件。
  2. 写入以下代码:
# app.py
from flask import Flask, jsonify
# 创建一个 Flask 应用实例
app = Flask(__name__)
# 定义一个路由和对应的视图函数
# @app.route 是一个装饰器,它告诉 Flask 哪个 URL 应该触发我们的函数
@app.route('/hello', methods=['GET'])
def hello_world():
    # jsonify 是一个辅助函数,用于将 Python 字典转换为 JSON 响应
    # 并设置正确的 Content-Type 头部
    return jsonify({'message': 'Hello, World!'})
# 运行应用
if __name__ == '__main__':
    # debug=True 会在代码修改后自动重启服务器,并在出错时显示详细的调试信息
    app.run(debug=True)

运行 API

在终端中运行 app.py

flask run

你会看到类似下面的输出:

Flask API开发如何快速上手?-图3
(图片来源网络,侵删)
 * Serving Flask app 'app'
 * Debug mode: on
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
 * Running on http://127.0.0.1:5000
Press CTRL+C to quit
 * Restarting with stat
 * Debugger is active!
 * Debugger PIN: ...

测试 API

打开你的浏览器或使用 API 客户端(如 Postman、Insomnia),访问 http://127.0.0.1:5000/hello

你会得到如下的 JSON 响应:

{
  "message": "Hello, World!"
}

核心概念详解

1 路由

路由负责将 URL 映射到视图函数。

@app.route('/user/<username>')
def show_user_profile(username):
    # 显示用户名的页面
    # <username> 是一个动态部分,它会作为参数传递给函数
    return f'User: {username}'
@app.route('/post/<int:post_id>')
def show_post(post_id):
    # 显示 id 为 post_id 的帖子,id 是整数
    return f'Post: {post_id}'

2 请求

当客户端发送请求时,Flask 会创建一个全局的 request 对象,你可以从中获取所有请求数据。

from flask import request
@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        # 获取 POST 请求中的表单数据
        username = request.form['username']
        password = request.form['password']
        return f'Processing login for {username}'
    else:
        # 这是一个 GET 请求,可能返回一个登录页面
        return 'This is a login page.'

3 响应

视图函数的返回值会自动转换为一个 HTTP 响应对象,最常用的方式是 jsonify

from flask import jsonify, make_response
@app.route('/custom_response')
def custom_response():
    response_data = {'status': 'success', 'data': [1, 2, 3]}
    # 使用 jsonify 创建一个带有正确 JSON 头部的响应
    return jsonify(response_data)
@app.route('/manual_response')
def manual_response():
    # 你也可以手动创建响应对象
    response = make_response('This is a manual response.', 201)
    response.headers['X-Custom-Header'] = 'MyValue'
    return response

构建一个功能完整的 RESTful API

我们将创建一个简单的待办事项 API,支持对任务的增删改查操作。

1 设计 API 端点

方法 URL 描述
GET /tasks 获取所有任务列表
GET /tasks/<int:id> 获取单个任务详情
POST /tasks 创建一个新任务
PUT /tasks/<int:id> 更新一个现有任务
DELETE /tasks/<int:id> 删除一个任务

2 使用 Flask-RESTful 扩展

为了更轻松地构建 RESTful API,我们使用 Flask-RESTful 扩展。

pip install flask-restful

3 完整代码 (app.py)

我们将使用一个 Python 列表作为临时的内存数据库。

# app.py
from flask import Flask
from flask_restful import Api, Resource, reqparse, abort
# 1. 创建 Flask 应用和 API 对象
app = Flask(__name__)
api = Api(app)
# 2. 模拟数据库
tasks = {}
task_id_counter = 1
# 3. 请求解析器
# 用于验证和解析请求数据
task_post_args = reqparse.RequestParser()
task_post_args.add_argument("content", type=str, help="Content of the task is required", required=True)
task_put_args = reqparse.RequestParser()
task_put_args.add_argument("content", type=str)
task_put_args.add_argument("completed", type=bool)
# 4. 定义资源
class Task(Resource):
    def get(self, task_id):
        if task_id not in tasks:
            abort(404, message="Task not found")
        return tasks[task_id]
    def put(self, task_id):
        args = task_put_args.parse_args()
        if task_id not in tasks:
            abort(404, message="Task not found, cannot update")
        if args['content']:
            tasks[task_id]['content'] = args['content']
        if args['completed'] is not None:
            tasks[task_id]['completed'] = args['completed']
        return tasks[task_id]
    def delete(self, task_id):
        if task_id not in tasks:
            abort(404, message="Task not found")
        del tasks[task_id]
        return '', 204 # No Content
class TaskList(Resource):
    def get(self):
        return tasks
    def post(self):
        global task_id_counter
        args = task_post_args.parse_args()
        task = {
            "id": task_id_counter,
            "content": args["content"],
            "completed": False
        }
        tasks[task_id_counter] = task
        task_id_counter += 1
        return task, 201 # Created
# 5. 将资源添加到 API
# <int:task_id> 表示 URL 中的 task_id 部分会被转换成整数
api.add_resource(TaskList, '/tasks')
api.add_resource(Task, '/tasks/<int:task_id>')
# 6. 运行应用
if __name__ == '__main__':
    app.run(debug=True)

4 测试 API

使用 curl 或 Postman 等工具来测试你的 API。

获取所有任务 (GET /tasks)

curl http://127.0.0.1:5000/tasks
# 返回: {} (空)

创建一个新任务 (POST /tasks)

curl -X POST -H "Content-Type: application/json" -d '{"content": "Learn Flask"}' http://127.0.0.1:5000/tasks
# 返回:
{
  "completed": false,
  "content": "Learn Flask",
  "id": 1
}

获取单个任务 (GET /tasks/1)

curl http://127.0.0.1:5000/tasks/1
# 返回:
{
  "completed": false,
  "content": "Learn Flask",
  "id": 1
}

更新任务 (PUT /tasks/1)

curl -X PUT -H "Content-Type: application/json" -d '{"completed": true}' http://127.0.0.1:5000/tasks/1
# 返回:
{
  "completed": true,
  "content": "Learn Flask",
  "id": 1
}

删除任务 (DELETE /tasks/1)

curl -X DELETE http://127.0.0.1:5000/tasks/1
# 返回: (空响应,状态码 204)

数据验证

在上面的例子中,reqparse 已经做了基本的验证,对于更复杂的验证,推荐使用 marshmallow 库。

pip install marshmallow

marshmallow 允许你定义数据模式,用于序列化(对象 -> JSON)和反序列化(JSON -> 对象)以及验证。


数据库集成

使用内存列表存储数据在应用重启后会丢失,对于真实项目,你需要一个数据库。Flask-SQLAlchemy 是一个流行的 ORM(对象关系映射)扩展,可以让你用 Python 类来操作数据库。

pip install Flask-SQLAlchemy

1 修改 app.py 以使用 SQLAlchemy

# app.py
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_restful import Api, Resource, reqparse, abort
app = Flask(__name__)
api = Api(app)
# --- 数据库配置 ---
# 使用 SQLite 数据库,文件名为 app.db
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///app.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)
# --- 数据库模型 ---
class TaskModel(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    content = db.Column(db.String(200), nullable=False)
    completed = db.Column(db.Boolean, default=False)
    def __repr__(self):
        return f"Task(id={self.id}, content='{self.content}', completed={self.completed})"
# --- 请求解析器 (保持不变) ---
task_post_args = reqparse.RequestParser()
task_post_args.add_argument("content", type=str, help="Content of the task is required", required=True)
# --- 资源类 (修改为使用数据库) ---
class Task(Resource):
    def get(self, task_id):
        task = TaskModel.query.get(task_id)
        if not task:
            abort(404, message="Task not found")
        return task.to_dict()
    def put(self, task_id):
        args = task_put_args.parse_args()
        task = TaskModel.query.get(task_id)
        if not task:
            abort(404, message="Task not found, cannot update")
        if args['content']:
            task.content = args['content']
        if args['completed'] is not None:
            task.completed = args['completed']
        db.session.commit()
        return task.to_dict()
    def delete(self, task_id):
        task = TaskModel.query.get(task_id)
        if not task:
            abort(404, message="Task not found")
        db.session.delete(task)
        db.session.commit()
        return '', 204
class TaskList(Resource):
    def get(self):
        tasks = TaskModel.query.all()
        return [task.to_dict() for task in tasks]
    def post(self):
        args = task_post_args.parse_args()
        new_task = TaskModel(content=args['content'])
        db.session.add(new_task)
        db.session.commit()
        return new_task.to_dict(), 201
# --- 添加资源到 API (保持不变) ---
api.add_resource(TaskList, '/tasks')
api.add_resource(Task, '/tasks/<int:task_id>')
# --- 初始化数据库 ---
@app.before_first_request
def create_tables():
    db.create_all()
if __name__ == '__main__':
    app.run(debug=True)

注意to_dict() 方法是 db.Model 的一个辅助方法,可以方便地将模型实例转换为字典。

首次运行:你需要先创建数据库表,可以在 Python 交互式环境中运行:

from app import app, db
with app.app_context():
    db.create_all()

或者,在 app.py 中添加 @app.before_first_request 装饰器(如上所示),它会自动在第一个请求前创建表。


进阶主题

1 项目结构(蓝图 Blueprints)

当应用变大时,将所有代码放在 app.py 中会变得混乱,Flask 的蓝图功能允许你将应用拆分成多个模块。

/my_api
  /app
    /__init__.py      # 创建 Flask 应用实例
    /api
      /__init__.py    # 创建 API 实例
      /tasks.py       # 任务相关的路由和资源
    /models.py        # 数据库模型
  /venv
  /app.py            # 启动文件

2 部署(使用 Gunicorn)

Flask 自带的服务器仅用于开发,在生产环境中,你需要一个专业的 WSGI 服务器,如 Gunicorn。

  1. 安装 Gunicorn:

    pip install gunicorn
  2. 运行应用:

    # 格式: gunicorn -w [worker数] -b [地址:端口] [模块名:应用实例名]
    gunicorn -w 4 -b 127.0.0.1:8000 app:app

    这会启动 4 个 worker 进程,监听在 8000 端口上。

  3. 反向代理:Gunicorn 不应该直接暴露在公网上,你应该在它前面放一个 Nginx 或 Apache 作为反向代理,处理静态文件和 SSL 终止。


总结与最佳实践

  • 使用虚拟环境:始终保持项目依赖隔离。
  • 保持简单:Flask 的优势在于其简洁性,不要过度设计。
  • 使用扩展:优先使用成熟的社区扩展,而不是自己造轮子。
  • 编写清晰的代码:遵循 PEP 8 风格指南,使用有意义的变量名。
  • 重视测试:学习使用 pytest 为你的 API 编写单元测试和集成测试。
  • 安全性:在生产环境中,务必关闭 debug 模式,并考虑使用 Flask 的扩展来处理 CSRF、XSS 等安全问题。

这份指南为你提供了使用 Flask 开发 API 的坚实基础,从简单的端点开始,逐步构建更复杂的功能,并探索 Flask 丰富的扩展生态,你将能够构建出强大而可维护的 Web API。

分享:
扫描分享到社交APP
上一篇
下一篇