课程 10:Flask API 开发入门

本课程介绍 Flask,一个轻量级且灵活的 Python Web 框架,重点介绍其在构建应用程序编程接口 (API) 方面的应用。API 允许不同的软件应用程序以编程方式相互通信。

1. Flask 简介

Flask 是一个用 Python 编写的“微”Web 框架。之所以称为“微”,是因为其核心简单小巧,但同时具有高度的可扩展性。Flask 不会为您做太多决定,例如使用什么数据库或模板引擎(尽管 Jinja 是其默认且推荐的)。

什么是 Flask?

  • 微框架:Flask 提供了 Web 开发的基本要素,如路由和请求处理,但将许多其他选择留给了开发人员。
  • WSGI 兼容:它构建在 Werkzeug WSGI 工具包之上,该工具包处理 Web 服务器网关接口 (WSGI) 的细节——这是 Web 服务器和 Web 应用程序之间的标准 Python 接口。
  • 模板引擎:使用 Jinja 模板引擎渲染动态 HTML 页面,不过对于 API,我们将主要关注返回像 JSON 这样的结构化数据。

Flask 的优点:

  • 轻量级:核心极简,从而减少了应用程序的大小和样板代码。
  • 灵活性:为开发人员在应用程序结构和组件选择方面提供了很大的自由度。
  • 易于上手:简单的语法和概念使其对初学者很友好。
  • 可扩展性:庞大的扩展生态系统为数据库 (Flask-SQLAlchemy)、表单 (Flask-WTF)、身份验证 (Flask-Login) 等提供了支持。
  • 适用于 API:其简单性使其成为构建 RESTful API 和 Web 服务的绝佳选择。

基本 Flask 应用程序结构

一个最小的 Flask 应用程序如下所示:

# 1. 导入 Flask 类
from flask import Flask

# 2. 创建 Flask 类的实例
# __name__ 帮助 Flask 找到静态资源和模板
app = Flask(__name__)

# 3. 定义一个路由和一个视图函数
# @app.route('/') 是一个装饰器,它将 URL '/' 映射到 home() 函数。
@app.route('/')
def home():
    return "Hello, World! 这是主页。" # "Hello, World! This is the home page."

# 4. 运行应用程序服务器 (用于开发)
if __name__ == '__main__':
    # debug=True 启用对开发有用的功能,例如自动重新加载
    # 以及在发生错误时在浏览器中显示交互式调试器。
    # 切勿在生产环境中使用 debug=True!
    app.run(debug=True, host='0.0.0.0', port=5000)

说明:

  • from flask import Flask:导入必要的类。
  • app = Flask(__name__):创建 Web 应用程序的实例。__name__ 是一个特殊的 Python 变量,它获取当前模块的名称。
  • @app.route('/'):这是一个 Python 装饰器。它告诉 Flask,当 Web 浏览器或客户端请求服务器的根 URL (/) 时,应调用 home() 函数。
  • def home(): return "Hello, World!":这是一个视图函数。它返回将发送回客户端(例如 Web 浏览器)的响应。
  • if __name__ == '__main__': app.run(debug=True):此代码块确保仅在直接执行脚本时(而不是作为模块导入时)启动 Flask 开发服务器。
    • debug=True:激活调试器和重新加载器。在开发过程中非常有用。
    • host='0.0.0.0':使服务器可从任何 IP 地址访问,而不仅仅是 localhost(如果在 Docker 或虚拟机中运行并希望从主机访问,则很有用)。
    • port=5000:Flask 的默认端口。

2. 使用 Flask 构建简单 API

Flask 非常适合创建提供数据的 API,通常采用 JSON 格式。

使用 `jsonify` 返回 JSON 数据

API 通常以 JSON (JavaScript Object Notation) 格式返回数据,因为它轻量、易于人类阅读且易于机器解析。Flask 提供了 jsonify 函数来正确创建 JSON 响应。

from flask import Flask, jsonify

app = Flask(__name__)

@app.route('/api/info')
def get_info():
    data = {
        'version': '1.0',
        'status': 'OK',
        'message': '示例 API 端点数据' # 'Sample API endpoint data'
    }
    return jsonify(data) # 创建具有正确 Content-Type 头的 JSON 响应

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

处理 URL 参数 (动态路由)

您可以定义从 URL 中捕获可变部分的路由。然后,这些变量将作为参数传递给您的视图函数。

from flask import Flask, jsonify

app = Flask(__name__)

@app.route('/api/greet/<name>') # <name> 是一个 URL 参数
def greet_user(name): # 捕获的 'name' 在此处传递
    return jsonify(greeting=f"你好, {name}!", personalized=True) # "Hello, {name}!"

# 示例:对 /api/greet/Alice 的请求将调用 greet_user(name='Alice')

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

您还可以为 URL 参数指定转换器,例如 <int:user_id> 以捕获整数。

处理查询参数

查询参数是 URL 中跟在 ? 后面的部分(例如 /api/search?q=flask&limit=10)。Flask 使用全局 request 对象来访问它们。

from flask import Flask, jsonify, request # 导入 request

app = Flask(__name__)

@app.route('/api/items')
def get_items():
    # 使用 request.args.get('param_name') 访问查询参数
    category = request.args.get('category', default='all', type=str)
    limit = request.args.get('limit', default=5, type=int)
    
    # 模拟基于参数获取项目
    items_data = [f"类别 '{category}' 中的项目 {i}" for i in range(1, limit + 1)] # "Item {i} in category '{category}'"
    
    return jsonify({
        'category_requested': category,
        'limit_applied': limit,
        'items': items_data
    })

# 示例:对 /api/items?category=books&limit=3 的请求

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

3. 完整的可运行 Flask 应用程序示例

这是一个完整的 Python 脚本(例如,另存为 `app.py`),它将上述概念组合成一个简单的 API。

`app.py`

from flask import Flask, jsonify, request

app = Flask(__name__)

# 1. 根端点
@app.route('/')
def index():
    return "欢迎来到简单的 Flask API!请尝试访问 /api/info 或 /api/greet/YourName。" # "Welcome to the Simple Flask API! Try accessing /api/info or /api/greet/YourName."

# 2. 基本 JSON API 端点
@app.route('/api/info')
def api_info():
    return jsonify({
        'application_name': '简单 Flask API', # 'Simple Flask API'
        'version': '0.1.0',
        'description': '一个用于演示 Flask 功能的基本 API。' # 'A basic API to demonstrate Flask capabilities.'
    })

# 3. 带有 URL 参数的 API 端点
@app.route('/api/greet/<name>')
def api_greet_name(name):
    return jsonify(greeting=f"你好, {name}!欢迎来到 API。") # "Hello there, {name}! Welcome to the API."

# 4. 使用查询参数的 API 端点
@app.route('/api/custom_query')
def api_custom_query():
    param1 = request.args.get('param1', default='default_p1_value', type=str)
    param2 = request.args.get('param2', default=100, type=int)
    
    return jsonify({
        'received_param1': param1,
        'received_param2_plus_10': param2 + 10,
        'message': '查询参数处理成功。' # 'Query parameters processed successfully.'
    })

if __name__ == '__main__':
    app.run(debug=True, host='0.0.0.0', port=5000)

运行和测试 Flask 应用

  1. 保存代码:将以上代码保存到名为 `app.py` 的文件中。
  2. 安装 Flask:如果您尚未安装 Flask,请安装:
    pip install Flask
  3. 运行应用程序:打开终端或命令提示符,导航到保存 `app.py` 的目录,然后运行:
    python app.py

    您应该会看到指示服务器正在运行的输出,类似于:
    * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
    * Restarting with stat
    * Debugger is active!
    * Debugger PIN: xxx-xxx-xxx

  4. 使用 Web 浏览器测试:
  5. 使用 `curl` 测试 (从另一个终端):
    # 测试 /api/info
    curl http://127.0.0.1:5000/api/info
    
    # 测试 /api/greet/<name>
    curl http://127.0.0.1:5000/api/greet/Developer
    
    # 测试带参数的 /api/custom_query
    curl "http://127.0.0.1:5000/api/custom_query?param1=hello_curl¶m2=77"

    `curl` 命令会将 JSON 响应直接打印到您的终端。

结论

Flask 提供了一种简单而强大的方法来用 Python 构建 Web 应用程序和 API。其微框架的特性意味着您可以从基本要素开始,并根据需要添加组件,这使其非常适合快速开发外部编程接口、Web 服务或功能齐全的 Web 应用程序。掌握了路由、视图函数和 JSON 响应,您就可以创建强大的 API 来提供数据或为其他应用程序提供功能。