4. Flask 框架入门:Flask 安装与 Hello World、路由与视图函数、请求对象与响应对象

在精算模型 API 的发布流程中,Flask 是构建轻量级 Web 服务最常用的 Python 框架。本章将带领你从零搭建 Flask 环境,理解其核心的路由与视图机制,并掌握请求与响应对象的操作——这些是后续将精算模型封装为 API 的基础。

4.1 Flask 安装与 Hello World

Flask 是一个微框架,核心简洁但扩展丰富。安装前请确保 Python 版本 ≥ 3.8。

安装步骤

  1. 创建虚拟环境(推荐):python -m venv actuarial_env
  2. 激活虚拟环境:
    • Windows: actuarial_env\Scripts\activate
    • macOS/Linux: source actuarial_env/bin/activate
  3. 安装 Flask:pip install flask
  4. 验证安装:python -c "import flask; print(flask.__version__)"

Hello World 示例

创建一个 app.py 文件,写入以下代码:

from flask import Flask

app = Flask(__name__)

@app.route('/')
def hello():
    return "Hello, Actuarial API World!"

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

在终端运行 python app.py,访问 http://127.0.0.1:5000/,浏览器将显示问候信息。这是 Flask 应用的最小原型。

精算实践提示: 在精算模型开发中,debug=True 模式便于调试,但生产环境必须关闭,避免敏感信息泄露。

4.2 路由与视图函数

路由(Route)将 URL 映射到 Python 函数(视图函数)。Flask 使用 @app.route() 装饰器定义路由。

基本路由规则

路由定义 URL 示例 视图函数
@app.route('/') / 首页
@app.route('/model') /model 模型列表
@app.route('/model/<id>') /model/123 单个模型详情
@app.route('/calc', methods=['POST']) /calc 精算计算接口

动态路由与类型转换器

Flask 支持在 URL 中嵌入变量,并指定类型:

from flask import Flask

app = Flask(__name__)

# 字符串类型(默认)
@app.route('/user/<username>')
def show_user(username):
    return f'User: {username}'

# 整数类型
@app.route('/policy/<int:policy_id>')
def show_policy(policy_id):
    return f'Policy ID: {policy_id}'

# 浮点数类型
@app.route('/premium/<float:amount>')
def show_premium(amount):
    return f'Premium Amount: {amount}'
精算风险注意: 动态路由中的参数必须做类型校验和边界检查。例如 <int:policy_id> 应确保 policy_id 在有效保单编号范围内,防止恶意输入导致服务异常。

路由与视图函数的关系

下图展示了客户端请求、路由匹配、视图函数处理、响应返回的完整流程:

Flask 路由与视图函数处理流程 客户端 路由匹配 视图函数 HTTP 响应 核心说明 1. 客户端发起 HTTP 请求(GET/POST 等)到指定 URL。 2. Flask 根据 @app.route() 注册的路由表匹配 URL 和 HTTP 方法。 3. 匹配成功后调用对应的视图函数,处理业务逻辑并返回响应对象。

4.3 请求对象与响应对象

Flask 的 request 和 response 对象是 API 开发的核心工具。精算模型 API 通常需要从请求中提取参数,并将计算结果封装为结构化响应。

请求对象(request)

Flask 的 request 对象封装了客户端发送的所有数据。常用属性如下:

属性/方法 说明 精算场景示例
request.method HTTP 方法(GET/POST 等) 判断是查询还是计算请求
request.args URL 查询参数(GET) /model?name=life
request.form 表单数据(POST) 提交精算假设参数
request.json JSON 数据(POST) 批量保单数据输入
request.headers HTTP 头部信息 API 密钥验证
request.cookies Cookie 数据 会话保持

响应对象(response)

视图函数可以返回字符串、元组或 Response 对象。推荐使用 jsonify() 返回 JSON 格式数据,便于精算系统集成。

from flask import Flask, request, jsonify

app = Flask(__name__)

# 精算模型:简单保费计算示例
def calculate_premium(age, coverage):
    # 模拟精算计算逻辑
    base_rate = 0.05
    risk_factor = 1 + (age - 30) * 0.02
    premium = coverage * base_rate * risk_factor
    return round(premium, 2)

@app.route('/api/premium', methods=['POST'])
def premium_calculation():
    # 从请求中提取 JSON 数据
    data = request.json
    
    # 参数校验
    if not data or 'age' not in data or 'coverage' not in data:
        return jsonify({'error': 'Missing required parameters: age, coverage'}), 400
    
    age = data['age']
    coverage = data['coverage']
    
    # 业务逻辑校验
    if not isinstance(age, (int, float)) or age < 18 or age > 100:
        return jsonify({'error': 'Age must be between 18 and 100'}), 400
    if not isinstance(coverage, (int, float)) or coverage <= 0:
        return jsonify({'error': 'Coverage must be a positive number'}), 400
    
    # 调用精算模型
    premium = calculate_premium(age, coverage)
    
    # 构建响应
    response = {
        'status': 'success',
        'data': {
            'age': age,
            'coverage': coverage,
            'premium': premium,
            'currency': 'USD'
        }
    }
    return jsonify(response), 200

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

请求与响应对象交互流程

下图展示了精算 API 中请求解析、参数校验、模型计算、响应构建的完整数据流:

精算 API 请求与响应数据流 HTTP 请求 request 解析 参数校验 返回 400 错误 精算模型 jsonify 响应 HTTP 响应返回 精算 API 最佳实践 始终在请求解析后做参数校验,校验失败立即返回 4xx 错误;成功则调用精算模型,最后用 jsonify 构建结构化响应。

响应状态码与自定义响应

精算 API 应合理使用 HTTP 状态码表达处理结果:

  • 200 OK:请求成功,返回计算结果
  • 400 Bad Request:参数缺失或格式错误
  • 404 Not Found:请求的资源不存在
  • 422 Unprocessable Entity:业务逻辑校验失败(如年龄超出精算模型支持范围)
  • 500 Internal Server Error:服务器内部异常
精算模型 API 开发要点:
  • 使用 request.json 接收结构化输入,避免使用表单数据传递复杂精算参数。
  • 响应统一使用 jsonify 返回 JSON 格式,包含 status、data 或 error 字段。
  • 在视图函数中捕获异常,返回 500 状态码并记录日志,避免将 Python 堆栈信息暴露给客户端。