一、Flask的使用

安装flask

pip install Flask

启动服务:

python app.py

服务将在 http://localhost:5000 运行

案例

from flask import Flask, request, jsonify
import time
# 创建 Flask 应用
app = Flask(__name__)

# 示例数据(模拟数据库)
users = [
    {"id": 1, "name": "Alice", "email": "alice@example.com"},
    {"id": 2, "name": "Bob", "email": "bob@example.com"}
]

@app.route('/cook_sync')
def cook_sync():
    print("开始做菜 A...")
    time.sleep(5) # 模拟做一个很慢的菜 (比如等大模型响应)
    print("菜 A 做好了!")
    return "菜 A 完成"

# 根路由 - 欢迎信息
@app.route('/')
def home():
    return "欢迎使用用户管理 API!请访问 /users 查看用户列表"


# GET 请求示例 - 获取所有用户
@app.route('/users', methods=['GET'])
def get_users():
    return jsonify({"users": users})


# GET 请求示例 - 获取单个用户
@app.route('/users/<int:user_id>', methods=['GET'])
def get_user(user_id):
    user = next((u for u in users if u["id"] == user_id), None)
    if user:
        return jsonify(user)
    return jsonify({"error": "用户不存在"}), 404


# POST 请求示例 - 创建新用户
@app.route('/users', methods=['POST'])
def create_user():
    # 从请求体中获取 JSON 数据
    data = request.get_json()

    if not data or 'name' not in data or 'email' not in data:
        return jsonify({"error": "缺少必要参数(name 和 email)"}), 400

    # 创建新用户
    new_user = {
        "id": len(users) + 1,
        "name": data['name'],
        "email": data['email']
    }
    users.append(new_user)

    return jsonify(new_user), 201


# 运行应用
if __name__ == '__main__':
    app.run(debug=True, host='0.0.0.0', port=5000)

二、FastAPI的使用

安装FastAPI和uvicorn:

 pip install fastapi uvicorn

主要特点:

  1. 自动文档:内置 Swagger UI 和 ReDoc 文档

  2. 数据验证:使用 Pydantic 模型验证输入数据

  3. 类型提示:Python 类型提示提供更好的开发体验

  4. 异步支持:原生支持 async/await

  5. 标准兼容:基于 OpenAPI 和 JSON Schema 标准

案例

from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from typing import List, Optional

# 创建 FastAPI 应用
app = FastAPI(
    title="用户管理API",
    description="简单的用户管理接口示例",
    version="1.0.0"
)


# 用户模型(使用Pydantic进行数据验证)
class User(BaseModel):
    id: int
    name: str
    email: str
    age: Optional[int] = None  # 可选字段


# 创建用户请求模型
class UserCreate(BaseModel):
    name: str
    email: str
    age: Optional[int] = None


# 模拟数据库
fake_db = {
    1: {"id": 1, "name": "Alice", "email": "alice@example.com", "age": 30},
    2: {"id": 2, "name": "Bob", "email": "bob@example.com"}
}


# 根路由 - 欢迎信息
@app.get("/", tags=["Root"])
def read_root():
    return {"message": "欢迎使用用户管理API!请访问 /docs 查看接口文档"}


# GET 请求示例 - 获取所有用户
@app.get("/users", response_model=List[User], tags=["Users"])
def get_all_users():
    return list(fake_db.values())


# GET 请求示例 - 获取单个用户
@app.get("/users/{user_id}", response_model=User, tags=["Users"])
def get_user(user_id: int):
    if user_id not in fake_db:
        raise HTTPException(status_code=404, detail="用户不存在")
    return fake_db[user_id]


# POST 请求示例 - 创建新用户
@app.post("/users", response_model=User, tags=["Users"], status_code=201)
def create_user(user: UserCreate):
    # 生成新ID
    new_id = max(fake_db.keys()) + 1 if fake_db else 1

    # 创建用户对象
    new_user = {
        "id": new_id,
        "name": user.name,
        "email": user.email
    }

    # 添加可选字段
    if user.age is not None:
        new_user["age"] = user.age

    # 保存到"数据库"
    fake_db[new_id] = new_user
    return new_user


# 运行应用(通过命令行执行)
if __name__ == "__main__":
    import uvicorn

    uvicorn.run(app, host="0.0.0.0", port=9999)

服务将在 http://localhost:9999 运行

FastAPI 自动生成交互式文档:

  • Swagger UI: http://localhost:9999/docs

  • ReDoc: http://localhost:9999/redoc

Swagger的界面如下:

 

三、FastAPI和Flask的区别和联系

想象一下你在经营一家餐厅:

Flask 的同步路由 (Synchronous): 就像只有一个厨师,而且他一次只能做一个菜。

  • 工作方式:

    • 第一个客人点单(一个请求来了)。
    • 厨师开始做这道菜(处理这个请求)。
    • 关键点: 在这道菜完全做好、端给客人之前,即使第二个客人已经点好单,厨师也不会开始做第二道菜。他必须等第一道菜完成。如果第一道菜是“佛跳墙”(一个很慢的操作,比如等待数据库、等待外部 API、或者等待大模型生成结果),那么后面所有的客人都要排队等着。
  • 代码示例 (简化示意):

# Flask (同步)
from flask import Flask
import time

app = Flask(__name__)

@app.route('/cook_sync')
def cook_sync():
    print("开始做菜 A...")
    time.sleep(5) # 模拟做一个很慢的菜 (比如等大模型响应)
    print("菜 A 做好了!")
    return "菜 A 完成"

# 当一个请求访问 /cook_sync 时,服务器会卡住 5 秒,
# 这期间无法处理其他请求(除非你开了多个服务员/进程)。
  • 特点: 简单直接,符合我们通常的编程思路(一步接一步)。但是,如果某个步骤很慢(等待 I/O 操作),整个流程就会被阻塞,效率不高,无法同时处理很多“等待中”的任务。

FastAPI 的异步路由 (Asynchronous): 就像一个很厉害的厨师,他可以同时处理多个任务。

  • 工作方式:

    • 第一个客人点单(请求 1)。厨师开始做菜 A,比如先把米饭放进电饭煲(开始一个需要等待的操作,比如请求大模型)。
    • 关键点: 在等待米饭煮熟(等待大模型响应)的时候,厨师**不会闲着**。他会立刻去看有没有其他客人的订单(处理请求 2)。
    • 第二个客人点单(请求 2)。厨师开始处理菜 B,比如开始洗菜(执行一些快代码)。
    • 如果菜 B 也需要等待(比如等水烧开),厨师又会去看有没有其他事做(处理请求 3 或查看米饭是否熟了)。
    • 一旦米饭煮熟了(大模型的响应回来了),厨师就会回来继续完成菜 A 的后续步骤。

代码示例 (简化示意):

# FastAPI (异步)
from fastapi import FastAPI
import asyncio # Python 的异步库

app = FastAPI()

@app.get('/cook_async')
async def cook_async(): # 注意这里的 async
    print("开始做菜 A (异步)...")
    await asyncio.sleep(5) # 模拟做一个很慢的菜,但这里用 await
                           # 表示“在这里等待,但允许服务器去做别的事”
    print("菜 A (异步) 做好了!")
    return "菜 A (异步) 完成"

# 当一个请求访问 /cook_async 时,服务器在 `await asyncio.sleep(5)` 这里
# 会“暂停”这个任务,转而去处理其他进来的请求。5秒后,当等待结束,
# 服务器会回来继续执行这个任务。这使得服务器能同时处理很多“等待中”的请求。
  • 特点: 需要使用 async 和 await 关键字。特别擅长处理那些包含等待时间(I/O 密集型,如网络请求、读写文件、数据库查询、等待大模型响应)的任务。同一个厨师(服务器进程)可以同时“照看”很多道菜,大大提高了效率(并发能力)。

联系和区别总结:

特性Flask (同步)FastAPI (异步)
核心机制 同步阻塞 (一步接一步) 异步非阻塞 (利用等待时间处理其他事)
比喻 单任务厨师 多任务厨师
代码风格 标准 Python 函数 (def) 使用 async def 和 await
擅长场景 CPU 密集型任务 (需要持续计算) I/O 密集型任务 (大量等待时间,如网络、磁盘、LLM)
并发能力 较低 (依赖多进程/多线程) 非常高 (单个进程能处理大量并发连接)
性能 对于 I/O 密集场景,性能较低 对于 I/O 密集场景,性能非常高
学习曲线 相对平缓 (同步逻辑易理解) 稍陡峭 (需要理解 async/await 和事件循环)
数据校验 需额外库 (如 Flask-WTF, Marshmallow) 内置 Pydantic,自动数据校验和文档生成

联系:

  • 它们都是 Python Web 框架,用来创建 API 或 Web 应用。
  • 它们都能接收 HTTP 请求,根据 URL 路由到相应的处理函数,然后返回 HTTP 响应。
  • Flask 也可以通过一些方式(比如使用 gevent 或 asyncio 扩展)实现类似异步的功能,但不是其天生设计。FastAPI 也可以运行同步代码(它会自动在线程池里运行,避免阻塞主循环)

在利用大模型(LLM)部署时怎么选择?

强烈推荐使用 FastAPI (异步)。

原因:

  1. LLM 调用是典型的 I/O 密集型操作: 当你的 API 调用一个大模型(无论是本地部署的还是云上的 API),你的程序需要等待模型进行计算并返回结果。这个等待时间可能从几百毫秒到几秒甚至更长。
  2. 异步能极大提高并发处理能力:
    • 使用 Flask (同步),当一个请求在等待 LLM 响应时,处理这个请求的那个服务器进程/线程就完全卡住了,不能为其他用户服务。如果你想同时服务 100 个用户,你可能需要启动 100 个(甚至更多)Flask 工作进程,这会消耗大量内存和 CPU 资源。
    • 使用 FastAPI (异步),当一个请求 await LLM 的响应时,服务器会把这个任务暂时挂起,然后立即去处理其他用户的请求。当 LLM 的响应回来后,服务器再继续处理之前挂起的任务。这样,一个 FastAPI 进程就能同时处理成百上千个“等待 LLM 响应”的并发请求,资源利用率极高。
  3. FastAPI 的内置特性很方便: FastAPI 基于 Pydantic 进行自动的数据校验和文档生成(Swagger UI / ReDoc)。这对于定义清晰的 LLM 输入(如 prompt、参数)和输出结构非常有帮助,能减少很多模板代码,提高开发效率和接口质量。

简单来说:

  • 如果你希望你的 LLM 应用能够同时服务很多用户,并且高效地利用服务器资源,FastAPI 的异步特性是巨大的优势
  • 如果你只是做一个内部小工具,用户量极少,或者你的团队完全不熟悉异步编程且不愿意学习,用 Flask 也能实现功能,但性能和并发能力会差很多,需要更多服务器资源来弥补。

结论: 对于需要调用大模型的场景,FastAPI 的异步模型几乎是必然的选择,因为它能更好地应对 LLM 调用带来的等待时间,实现高并发、高性能的服务。

 

posted on 2025-07-09 09:55  周文豪  阅读(84)  评论(0)    收藏  举报