当前位置: 首页 > news >正文

FastAPI简单使用

FastAPI简单使用

1 介绍

FastAPI是一个高性能的Web框架,支持自动数据验证**、**自动文档生成和异步。

https://fastapi.tiangolo.com/

Uvicorn是一款基于ASGI协议的高性能Python Web服务器,专为异步框架设计,支持FastAPI、Starlette等现代Web框架。

1.1 异步编程

在Python中异步编程中,关键字async 和 await很重要:

async 的作用

  • 用于定义一个协程函数(coroutine function)。
  • 调用 async 函数时,不会立即执行函数体,而是返回一个 协程对象(coroutine object),需要被事件循环调度执行。

await的作用

  • 用于暂停当前协程,等待一个 awaitable 对象(如另一个协程、asyncio.sleep()asyncio.Future 等)完成。
  • 不会阻塞事件循环,而是让出控制权,允许其他协程运行。
  • await 只能在 async def 函数中使用。

示例

import asyncio# 异步调用数据
async def fetch_data():print("Hello")await asyncio.sleep(5)print("World")# 调用不会执行,而是返回协程对象
coro = fetch_data()
print(type(coro))async def main():# 等待 fetch_data() 完成result = await fetch_data()print("获取到的结果:", result)asyncio.run(main())

1.2 异步和多线程的区别

在 Python 中,异步(asyncio)多线程(threading) 都可以实现“同时干多件事”,但它们的底层机制、性能表现和适用场景完全不同。下面用一句话总结:

异步是“单线程内协作式并发”,多线程是“操作系统级抢占式并发”。

IO 高并发用 async,简单并发用 thread,CPU 密集用 process

维度异步(asyncio)多线程(threading)
核心机制事件循环 + 协程(用户态调度)操作系统线程(内核态调度)
线程数单线程(默认)多线程
切换开销极低(用户态切换)较高(内核态上下文切换)
GIL 影响不受影响(单线程)受 GIL 限制(CPU 密集任务无法并行)
适合任务高并发 I/O 密集(如爬虫、API 请求)少量 I/O 密集或简单并发任务
编程难度较高(需写 async/await较低(同步代码即可)
数据竞争无(单线程)有(需加锁、同步)

1.3 异步≠立即响应客户端

假设你有这样一个异步路径操作函数:

from fastapi import FastAPI
import asyncioapp = FastAPI()@app.get("/")
async def read_root():# 模拟一个耗时的 I/O 操作,比如数据库查询await asyncio.sleep(2)return {"message": "Hello World"}

当一个请求 GET / 到来时,会发生以下步骤:

  1. 接收请求:FastAPI 从客户端接收到 HTTP 请求。
  2. 创建任务:FastAPI 创建一个任务来执行你的 read_root 函数。
  3. 事件循环接管:FastAPI 将你的函数(一个协程)交给 ASGI 服务器(如 Uvicorn 或 Hypercorn)内部的事件循环。
  4. 执行直到第一个 await:事件循环开始执行 read_root 函数。
  5. 遇到 await(关键点!)
    • 当执行到 await asyncio.sleep(2) 时,函数会说:“我要睡眠 2 秒,在这期间我什么都不做,你去忙别的吧!”
    • 此时,事件循环会立即挂起这个函数
    • 事件循环不会阻塞等待,它会立刻去处理其他正在排队的任务(可能是另一个来自客户端的请求,或者是其他异步操作)。
  6. 等待完成:2 秒后,睡眠操作完成。
  7. 恢复执行:事件循环在适当的时机(当它轮询到睡眠完成的事件时)重新唤醒 read_root 函数,并从 await 之后的地方继续执行。
  8. 返回响应:函数执行到最后,返回 {"message": "Hello World"}
  9. 发送响应:FastAPI 将这个 Python 字典转换为 JSON,并通过 HTTP 响应发送回客户端。

1.4 同步 vs 异步

为了更好地理解,我们看一个同步的例子:

import time@app.get("/sync")
def read_root_sync():# 模拟一个耗时的 I/O 操作time.sleep(2)  # 注意:这里是同步的 sleepreturn {"message": "Hello World Sync"}

对于这个同步端点:

  • 当执行到 time.sleep(2) 时,整个工作线程被彻底阻塞 2 秒
  • 在这 2 秒内,这个线程不能做任何其他事情,即使有新的请求进来,它也无法处理。
  • 如果并发请求数超过了工作线程数,新请求就必须排队等待,导致性能急剧下降。

1.5 FastAPI的特点

  • FastAPI 的异步机制并不能让你的业务逻辑执行得更快。一个需要 2 秒的数据库查询,在异步函数里仍然需要 2 秒才能拿到结果。
  • 它的巨大优势在于提升服务器的并发吞吐量。通过在等待 I/O 时释放线程,让有限的服务器资源可以同时服务更多的客户端连接。
  • 你“立即”得到的是事件循环的解放,而不是给客户端的最终响应

因此,你应该将异步用于那些主要是 I/O 密集型 的操作(如网络请求、数据库查询、文件读写),而不是 CPU 密集型 的操作(如复杂的数学计算)。对于 CPU 密集型任务,你应该使用 def 定义普通函数,并让 FastAPI 在单独的线程池中运行它们。

2 简单使用

2.1 安装依赖环境

pip install "fastapi[standard]"
pip install uvicorn

2.2 简单使用FastAPI

import asyncio
from typing import Unionimport uvicorn
from fastapi import FastAPI, BackgroundTasks, Query
from pydantic import BaseModel, Fieldapp = FastAPI()"""
FastAPI中参数校验的关键字有Field、Query、Path。
其中Field和Query的作用相似,不同点是字段 Field,参数 Query/Path,写在模型里 → Field;写在函数签名里 → Query/Path。
三个点 (...) 被称为 Ellipsis(省略号),它是一个内置常量,主要作为占位符和切片工具使用。
"""class Item(BaseModel):name: strprice: floatis_offer: Union[bool, None] = Noneclass TaskInfo(BaseModel):task_id: int = Field(..., ge=1, le=120, description="任务编号")@app.get("/read")
def read_item(item_id: int = Query(..., ge=1, le=120, description="数据编号"), data: Union[str, None] = None):return {"item_id": item_id, "data": data}@app.post("/update/{item_id}")
async def update_item(item_id: int, item: Item):# time.sleep(10)await asyncio.sleep(4)return {"item_id": item_id, "item_name": item.name}async def long_running_task(task_id: int):# 模拟耗时操作await asyncio.sleep(10)print(f"任务 {task_id} 完成")@app.post("/task")
async def create_task(task_info: TaskInfo, background_tasks: BackgroundTasks):# 将任务添加到后台执行background_tasks.add_task(long_running_task, task_info.task_id)return {"status": "任务已接收","task_id": task_info.task_id,"message": "任务正在后台处理"}if __name__ == '__main__':uvicorn.run(app, host="127.0.0.1", port=3000)

2.3 返回值

(1)接口文档地址

http://127.0.0.1:3000/docs

(2)读取数据地址

http://127.0.0.1:3000/read

(3)更新数据,不会立刻返回值

http://127.0.0.1:3000/update/1

参数

{"name": "张三","price": 0.12,"is_offer": true
}

(4)异步任务,立刻返回值。

http://127.0.0.1:3000/task

http://www.dtcms.com/a/442884.html

相关文章:

  • 长宁区网站建设网站制微博的网站连接是怎么做的
  • 网站开发流程原理网站开发项目管理文档模板
  • 个人免费建网站网站模版保护域名跳转
  • 做百度手机网站关键词wordpress网店适合
  • ✅阿里云-对象存储OSS-配置和使用(Java)
  • Go语言入门(19)-指针(下)
  • 做国际网站有补贴吗国家企业公示信息系统全国
  • 生物化学Learning Track(13)核酸的性质和研究方法
  • 如何建个使用自己帐户的网站报关做业务可以上哪些网站
  • 游戏币交易平台代理东莞网站优化方法
  • 怎样优化手机网站wordpress oyester
  • phpcms v9网站搬站之后掉出来的文章链接显示为以前网站域名一个人如何注册公司
  • 软件系统核心关系全解析:除聚合外的 6 大关键类型与应用场景
  • 在哪请人做网站国内免费crm系统
  • 龙华做网站公司新网站如何做seo
  • Ubuntu 14.04更换阿里云源,设置系统字体
  • 什么网站广告做多水果网站怎么做
  • 火车票网站建设海口模板建站哪家好
  • int最大值2的次幂
  • 6.3 排序、RMQ
  • 合肥做微网站建设做网站和做程序一样吗
  • 【OpenCV】图像处理实战:边界填充与阈值详解
  • 泉州网站排名哈尔滨seo优化大家
  • Upgrade Win11 subsystem Ubuntu22.04 to ubuntu24.04
  • Ubuntu 24.04 LTS 发行说明
  • 做网站需要网站负责人网站企业模板
  • 《构建可靠 Python 项目:测试金字塔的实践指南与工具解析》
  • 做医药商城网站的公司网站开发角色分配权限
  • 旅游网站建设的建议信阳网站设计
  • 技术驱动增长:赋能您的电竞体育平台快速启航与商业成功