Python从入门到精通1:FastAPI

引言

在现代 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,⽤于定义API

app = 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 API

app = 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属性,类型为str
    name: str
    # 定义⼀个price属性,类型为float
    price: float
    # 定义⼀个is_offer属性,类型为Union[bool, None],默认为None
    is_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_id
     return {"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 APIRouter

api_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 APIRouter

api_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 APIRouter

api_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 # 请求查询参数1
    res_arg2 = request.query_params # 请求查询参数2
    print(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 或分布式任务队列的集成,进一步提升项目复杂度。

延伸阅读

相关推荐
笨鸟先飞,勤能补拙6 小时前
AI 赋能网络安全:技术全景、成熟度评估与实战案例
人工智能·python·安全·web安全·网络安全·sqlite·github
长和信泰光伏储能7 小时前
京津冀光伏发电:绿色能源的未来之路
python·能源
浦信仿真大讲堂7 小时前
从重复操作到自动化闭环:如何让 CST 与 Python 真正协同起来
python·自动化·cst·仿真软件·达索软件
Gu Gu Study8 小时前
ScoutLoop开放域深度研究引擎(agent的初步设计想法)
人工智能·python
卷无止境8 小时前
写代码这件事,到底该讲究点什么?
后端·python
卷无止境9 小时前
循环复杂度到底在算什么,Python 代码怎么才能写得让人一看就懂
后端·python
lpfasd1239 小时前
MediaCrawler 项目深度分析
chrome·python·chrome devtools
Dxy12393102169 小时前
Python项目打包成EXE完整教程(PyInstaller实战避坑)
开发语言·python
bamb0010 小时前
一个项目带你入门AI应用开发01
python
05664610 小时前
Python康复训练——常用标准库
开发语言·python·学习