Python从入门到精通1:FastAPI

embedded/2025/3/11 2:36:39/

引言

在现代 Web 开发中,API 是前后端分离架构的核心。FastAPI 凭借其高性能、简洁的语法和自动文档生成功能,成为 Python 开发者的首选框架。本文将从零开始,详细讲解 FastAPI 的核心概念、安装配置、路由设计、请求处理以及实际应用案例,助你快速掌握这一高效工具。

一、FastAPI 概述与安装

1.1 什么是 FastAPI?

FastAPI 是一个基于 Python 3.8+ 的现代 Web 框架,专注于构建高性能 RESTful API。其核心特点包括:

  • 基于 Starlette 和 Pydantic:提供异步支持和严格的数据验证。
  • 自动生成 API 文档:内置 Swagger UI 和 ReDoc,开发者无需手动维护文档。
  • 类型提示(Type Hints):利用 Python 的类型系统实现输入参数验证和代码提示。

1.2 FastAPI 的优势

特性说明
高性能异步处理能力(ASGI)支持高并发,性能媲美 Node.js 和 Go。
开发效率高通过类型提示和自动文档生成,减少代码冗余和调试时间。
生态完善可无缝集成 SQLAlchemy、OAuth2、JWT 等常用库。

1.3 安装与环境配置及第一个FastApi应用

1.3.1、安装与环境配置

python">步骤 1:安装依赖库
pip install fastapi # FastAPI 依赖 Python 3.8 及更⾼版本
步骤 1:安装uvicorn服务器
pip install "uvicorn[standard]"  # 安装 ASGI 服务器

 

1.3.2、第一个FastApi应用

创建 test_one.py:

python">from fastapi import FastAPI # 导⼊FastAPI,⽤于定义APIapp = FastAPI() # 创建FastAPI实例# http请求方式类型:get、post、put、update、delete
# 浏览器默认访问的是get类型,如果使用其他形式访问
# 出现405的提示(请求的方式不匹配)# 不带参数的访问形式:
# 访问地址:http://127.0.0.1:8000
@app.get("/")
async def test_one():return {"message": "My first fastapi project"}# 带一个参数的时候的访问形式:
# 访问地址:http://127.0.0.1:8000/hello/小宁
@app.get("/hello/{name}")
async def hello(name: str):return {"hello": f"fastapi {name}"}# 带一个参数的时候的访问形式:
# 访问地址:http://127.0.0.1:8000/my/小宁,21/长沙
@app.get("/my/{name},{age}/{addr}")
async def test_one(name: str, age: int, addr: str):return {"name": name, "age": age, "addr": addr}

启动uvicorn服务器:

python"># 在Terminal中输入:
# 语法:uvicorn 文件的相对路径:实例名 --reload
# reload:表示热启动,后端代码改变时,前端页面也会随之改变
uvicorn csdn.test_one:app --reload
运行结果:

注意事项:

1、传入参数的时候不能多传,也不能少传。

2、传入的参数一定要满足自己设置的http网址的层级格式。

3、传入的参数要满足函数设置的参数类型。

二、快速入门案例解析

2.1、union的可选参数

 创建 test_two.py:

python">from typing import Union  # 导⼊Union, ⽤于定义可选类型
from fastapi import FastAPI # 导⼊FastAPI,⽤于构建RESTful APIapp = FastAPI()# 创建FastAPI实例# 访问地址:http://127.0.0.1:8000/items/100?q=小宁
@app.get("/items/{item_id}")
# 定义路由,访问根路径调⽤read_item函数,传⼊item_id参数,并返回该参数对应的数据
# q: Union[str, None] = None ⽤于定义q的可选类型为str或int或None
# 如果http没有传入参数时候,默认为None,避免用户没传入参数,网页就跑不出来的情况
async def  read_item(item_id: int, q: Union[str,int, None] = None):return {"item_id": item_id, "q": q}
代码解析
  1. 路径参数{item_id} 动态匹配 URL 中的值,自动转换为整数类型。
  2. 查询参数q 通过 Union[str, None] 声明为可选参数。
  3. 自动验证:若传入非整数 item_id,FastAPI 返回 HTTP 422 错误。

启动uvicorn服务器:

python"> uvicorn csdn.test_two:app --reload

运行结果: 

2.2、uvicorn.run和pydantic类结合Apifox

在前面的课堂案例中,我们启动服务器都要打开终端Timinal中输入启动服务器的语句,那么每次启动都要输出启动的语句,那就很麻烦了,有没有什么办法可以要启动服务器和和之前一样只要点击运行就能够启动呢?所以我们接下来就会讲到uvicorn.run启动服务器。

在前面的内容我们讲过,浏览器默认的请求方式是get,那么假如我们的http请求方式是post等其他类型的时候怎么办呢,那么就需要使用Apifox软件了,这个大家可以直接官网直接下载。

创建 test_three.py:

python">from fastapi import FastAPI # 引⼊FastAPI类,⽤于创建⼀个应⽤
import uvicorn  # 引⼊uvicorn,⽤于启动服务
from typing import Union  #引⼊Union类,⽤于类型注解
from pydantic import BaseModel # 引⼊pydantic类,⽤于定义数据结构app = FastAPI() # 创建⼀个应⽤,app是⼀个FastAPI实例class Item(BaseModel):# 定义⼀个Item类,继承⾃BaseModel,⽤于定义请求体中的数据结构# 定义⼀个name属性,类型为strname: str# 定义⼀个price属性,类型为floatprice: float# 定义⼀个is_offer属性,类型为Union[bool, None],默认为Noneis_offer:Union[bool, None] = None@app.get("/") # 装饰器,表示定义⼀个根路径的get请求
# 定义⼀个根路径的get请求,返回⼀个字典,键值分别为Hello和World
# async 表示异步请求,可以提⾼性能
# 测试访问:http://127.0.0.1:8000/
async def read_root():return {"Hello": "World"}@app.get("/items/{item_id}")
# 定义⼀个路径参数为item_id的get请求,返回⼀个字典,键值分别为item_id和q
# Union[str, None] 表示q可以为str类型或者None类型,默认为None
# 测试访问:http://127.0.0.1:8000/items/3?q=abc
async def read_item(item_id: int, q: Union[str, None] = None):return {"item_id": item_id, "q": q}@app.put("/items/{item_id}")
# 测试访问:http://127.0.0.1:8000/items/3
async def update_item(item_id: int, item:Item):# 定义⼀个路径参数为item_id的put请求,返回⼀个字典,键值分别为item_name和item_idreturn {"item_name": item.name, "item_id": item_id,"item_price": item.price,"is_offer": item.is_offer}
# Item类类型传参数的时候要使用apidox中的body中的json格式(字典格式)if __name__ == "__main__":# 启停⽅式:# 1.⽅式1指令式:# 服务器启动指令 uvicorn main:app --reload# fastDemo1:app 表示main.py⽂件中的app实例# 服务器停⽌指令 ctrl+c# 2.⽅式2界⾯式:# ⿏标右键启动----》run main.py# 界⾯右上⻆的停⽌按钮# 启动服务,host指定主机地址,port指定端⼝号,reload=True表示当代码发⽣变化时,⾃动重启服务# main:app---- 表示main.py⽂件中的app实例uvicorn.run("bbb:app", host="127.0.0.1", port=8080, reload=True)

运行结果:

 

这里是Apifox的操作截图:

三、路由分发

3.1、为什么需要路由分发?

在小型项目中,所有路由都写在 main.py 中尚可接受。但随着项目规模扩大(如构建包含用户、订单、商品等多个模块的电商系统),将所有路由集中在一个文件会导致:

  • 代码臃肿:数千行代码堆积,难以阅读和维护。
  • 协作困难:多人同时修改同一文件容易引发冲突。
  • 复用性差:相同功能的路由无法快速移植到其他项目。

路由分发(Route Distribution)通过 模块化拆分路由,将不同功能的路由分散到多个文件中,最终通过统一入口集成,完美解决上述问题。

3.2、图书管理系统

cbs.py源码
python"># 出版社分发路由配置
from fastapi import APIRouterapi_cbs = APIRouter()@api_cbs.get("/get")
async def get_test():return {"methods": "出版社分发路由get方法"}@api_cbs.post("/post")
async def post_test():return {"methods": "出版社分发路由post方法"}@api_cbs.put("/put")
async def put_test():return {"methods": "出版社分发路由put方法"}@api_cbs.delete("/delete")
async def delete_test():return {"methods": "出版社分发路由delete方法"}
ts.py源码
python"># 图书分发路由配置
from fastapi import APIRouterapi_ts = APIRouter() # 创建路由@api_ts.get("/get")
async def get_test():return {"methods": "图书分发路由get⽅法"}@api_ts.post("/post")
async def post_test():return {"methods": "图书分发路由post⽅法"}@api_ts.put("/put")
async def put_test():return {"methods": "图书分发路由put⽅法"}@api_ts.delete("/delete")
async def delete_test():return {"methods": "图书分发路由delete⽅法"}

zz源码

python"># 图书分发路由配置
from fastapi import APIRouterapi_ts = APIRouter() # 创建路由@api_ts.get("/get")
async def get_test():return {"methods": "图书分发路由get⽅法"}@api_ts.post("/post")
async def post_test():return {"methods": "图书分发路由post⽅法"}@api_ts.put("/put")
async def put_test():return {"methods": "图书分发路由put⽅法"}@api_ts.delete("/delete")
async def delete_test():return {"methods": "图书分发路由delete⽅法"}

main源码

python">from fastapi import FastAPI
from csdn.ts import api_ts
from csdn.cbs import api_cbs
from csdn.zz import api_zz
app = FastAPI()#include_router()⽅法,⽤于将分发路由添加到app中,prefix参数为路由前缀,tags参数为标签
app.include_router(api_ts, prefix="/ts", tags=["图书"])
app.include_router(api_cbs, prefix="/cbs", tags=["出版社"])
app.include_router(api_zz, prefix="/zz", tags=["作者"])

运行结果:

提示:其他的需要访问的时候要使用Apifox来访问,因为其他的http的请求方式都不是get不能使用浏览器直接访问。

四、request对象的入门

在实际开发过程中,有些时候我们需要通过Request对象直接获取⼀些信息,如:我们希望获取客户端的 IP等信息,此时我们在路由操作函数中直接定义类型为Request的对象参数,就可以在代码中使⽤Request对象进⾏数据的获取。
假设在路由函数中定义了request:Request,那么该对象可以获取到哪些信息呢?

 

 代码示例:

python">from fastapi import FastAPI,Request
@app.put("/req/")
async def req(request: Request):req_method = request.method #请求的方式req_url = request.base_url # 请求的路径req_port = request.url.port  #请求的端口res_json = request.json() # 请求json数据res_arg1 = request.url.query # 请求查询参数1res_arg2 = request.query_params # 请求查询参数2print(f"请求的方式:{req_method},请求的路径:{req_url},#请求的端口:{req_port},请求json数据:{res_json}"f"请求查询参数1:{res_arg1},请求查询参数2:{res_arg2}")

在Aifox中发送请求:

参数:

json参数: 

运行结果:

五、总结

FastAPI 凭借其高性能和开发效率,已成为构建现代 API 的首选框架。通过本文的学习,你已经掌握了:

  1. 基础路由设计与参数验证
  2. 模块化路由管理(APIRouter)
  3. 请求元数据处理(Request 对象)
  4. 异步编程与高级功能
  5. 常见的http状态码提示的意思:
      200:请求成功的状态码404:页面找不到422:请求体中数据有问题(格式不正确,名字匹配不对)405:请求的方式不匹配(如路径是get形式,但是函数上面写的是其他的请求类型)500:后台服务器程序出错d

无论是构建微服务、实时应用还是数据处理接口,FastAPI 都能提供强大的支持。下一步可探索其与 SQL 数据库、WebSocket 或分布式任务队列的集成,进一步提升项目复杂度。

延伸阅读

  • 官方文档:FastAPI Documentation
  • 实战项目:FastAPI + SQLAlchemy 用户管理系统


http://www.ppmy.cn/embedded/171646.html

相关文章

Scikit-learn库中用于特征缩放的类MinMaxScaler用法详细介绍并举例说明

Scikit-learn库中用于特征缩放的类MinMaxScaler用法详细介绍并举例说明 目录 Scikit-learn库中用于特征缩放的类MinMaxScaler用法详细介绍并举例说明1.类MinMaxScaler介绍1.1 转换公式(1) 核心转换公式(2)转换公式举例 1.2 MinMaxScaler参数(1) feature_…

STM32常见外设的驱动示例和代码解析

以下是针对STM32常见外设的驱动示例和代码解析,基于HAL库实现,适用于大多数STM32系列(如F1/F4/H7等),可根据具体型号调整引脚和时钟配置。 1. GPIO驱动 应用场景:控制LED、按键检测、继电器开关等。 示例代码: // 初始化LED(推挽输出) void LED_Init(void) {GPIO_In…

【3】VS Code 新建上位机项目---C#窗体与控件开发

【3】VS Code 新建上位机项目---C#窗体与控件开发 1 窗体1.1 新建窗体1.2 windows程序与窗口的关系1.3 windows程序的事件1.3.1 定义事件与处理事件1.3.2 关联事件1.3.3 Windows窗体对象创建与显示(show与ShowDialog())2 控件与容器2.1 常用容器2.1.1 Groupbox2.1.2 Pannel2.1.…

模型压缩技术(二),模型量化让模型“轻装上阵”

一、技术应用背景 在人工智能蓬勃发展的浪潮下,大模型在自然语言处理、计算机视觉等诸多领域大放异彩,像知名的GPT以及各类开源大语言模型,其规模与复杂度持续攀升。然而,这一发展也带来了挑战,模型越大,对…

1.3 使用Scala集成开发环境

本次实战学习如何在 IntelliJ IDEA 中搭建 Scala 开发环境并完成相关任务。首先,安装 IDEA 2024.1.4 版本,并确保 JDK 为 8 或 11。接着,安装 Scala 插件并重启 IDE。创建 Scala 项目时,需设置项目名称、位置、构建系统、JDK 和 S…

中国嵌入式单片机就业形势分析

此博客分析中国嵌入式单片机的就业形势,包括行业趋势、技能需求,以及不同技能水平的薪资情况。会重点探讨裸机开发与RTOS(如FreeRTOS、TTR等)的市场需求差异,以及如何提升竞争力。 行业趋势 嵌入式单片机&#xff08…

tauri-plugin-shell插件将_blank的a标签用浏览器打开了,,,解决办法

不要使用这个插件,这个插件默认会将网页中a标签为_blank的使用默认浏览器打开,但是这种做法在我的程序里不是很友好,我需要自定义这种行为,当我点击我自己的链接的时候,使用默认浏览器打开,当点击别的链接的…

Java数据结构第十九期:解构排序算法的艺术与科学(一)

专栏:Java数据结构秘籍 个人主页:手握风云 目录 一、排序的概念及引用 1.1. 排序的概念 1.2. 排序的应用 1.3. 常见的排序算法 二、常见排序算法的实现 2.1. 直接插入排序 2.2. 希尔排序 一、排序的概念及引用 1.1. 排序的概念 所谓排序&#xf…