文章目录
- 前言
- 一、FastAPI是什么
-
- [1.1 FastAPI与其他Python Web框架对比](#1.1 FastAPI与其他Python Web框架对比)
- [1.2 异步与同步的区别](#1.2 异步与同步的区别)
- [1.3 FastAPI的两大核心组件](#1.3 FastAPI的两大核心组件)
- 二、如何测试API
-
- [2.1 如何测试API](#2.1 如何测试API)
- [2.2 FastAPI自动生成文档](#2.2 FastAPI自动生成文档)
-
- [2.2.1 PyCharm中运行.py](#2.2.1 PyCharm中运行.py)
- [2.2.2 浏览器测试API](#2.2.2 浏览器测试API)
- 三、路由
-
- 3.1为什么要分包
- [3.2 路由的基本用法](#3.2 路由的基本用法)
-
- [3.2.1 创建路由对象](#3.2.1 创建路由对象)
- [3.2.2 定义路由和处理函数](#3.2.2 定义路由和处理函数)
- [3.2.3 应用(包)路由](#3.2.3 应用(包)路由)
- 四、请求和相应
-
- [4.1 路径参数](#4.1 路径参数)
- [4.2 请求体](#4.2 请求体)
- [4.3 查询参数](#4.3 查询参数)
- [4.4 表单提交](#4.4 表单提交)
- [4.5 文件上传](#4.5 文件上传)
-
- [4.5.1 方式一:使用bytes(适合小文件)](#4.5.1 方式一:使用bytes(适合小文件))
- [4.5.2 方式二:使用UploadFile(适合大文件,推荐)](#4.5.2 方式二:使用UploadFile(适合大文件,推荐))
- 五、其他请求信息
-
- [5.1 Header(请求头)](#5.1 Header(请求头))
- [5.2 Cookie](#5.2 Cookie)
- 结语
前言
学习Web开发,选对工具事半功倍。FastAPI以其简洁的设计和强大的性能,正成为Python后端开发的新选择。本文从环境搭建讲起,带你一步步掌握路由设计、参数处理、文件上传等核心技能,助你快速上手现代Web开发。
一、FastAPI是什么
FastAPI是一个用来写网站后端的Python框架。框架就是别人写好的代码库,可以直接拿来用,不用从零开始。
1.1 FastAPI与其他Python Web框架对比
Python有几个主流的Web框架:
- Django:这是一个"重量级"框架。它什么都已经准备好了,其中数据库、后台管理、用户系统都有。但是问题也在这里------哪怕只是想做一个小功能,也得把整套系统都启动起来。这也是高耦合的一大痛点。
- Flask:这是一个"轻量级"框架,比Django简单很多,但是需要自己搭配各种组件。
- FastAPI:也是轻量级的,但设计理念是"高内聚,低耦合"。换句话你来说就是,FastAPI本身只负责核心功能,其他功能可以自由选择第三方库来搭配。这就像乐高积木,需要什么拼什么,很灵活。
相比于Django与Flask来说FastAPI还有一大优势就是支持异步编程。
1.2 异步与同步的区别
可以简单理解的:同步就是一件事做完再做下一件事。异步就是可以同时做几件事,不用等。FastAPI支持异步操作,这样处理请求更快。
1.3 FastAPI的两大核心组件
Starlette :负责网络通信部分。它是一个轻量级的ASGI框架,适合用来搭建高性能的异步服务。
Pydantic:负责数据部分。它主要是进行数据检验操作,利用Python的类型提示功能来检查数据是否符合要求。比如你希望接收一个数字,但用户传了文字,Pydantic会自动报错并给出清晰的错误信息。
二、如何测试API
2.1 如何测试API
写好API后,你需要测试它是否正常工作。我推荐了几个工具:
- Postman:最经典的API测试功能,功能齐全。
- Apifox、ApiPost、Yaak:这些都是国内的API测试工具,界面友好,有些还支持中文
注:现在主要用的还是Postman,所以在下面的下面演示中我主要还是用的Postman。
2.2 FastAPI自动生成文档
FastAPI有一个很实用的功能:它会自动给你生成API文档。你不需要额外写文档,访问方式就是先在PyCharm中运行.py文档,再浏览器中输入http://localhost:+你的端口号/docs就能看到Swagger界面。这个界面可以显示所有接口,还能直接在上面测试。
2.2.1 PyCharm中运行.py
再PyCharm中的左下角找到服务(service),再点击添加服务,接着点运行配置,再选择FastAPI即可,你的FastAPI项目名就会显示在这里,再你的FAstAPI项目鼠标右键点击,再点击运行或调试(如果需要的话)即可。






2.2.2 浏览器测试API
默认端口号一般是8000,但是如果不改端口话可能在运行的时候会出现端口占用,运行出错的情况,这是可以修改端口,点击编辑所选配置,按照我下面标出的操作步骤操作。


在再浏览器中输入对应的访问地址即可。

三、路由
3.1为什么要分包
在实际开发中,一个项目通常有很多功能模块,比如用户管理、角色管理、权限管理等。如果把所有的代码文件都堆在项目根目录下,很快就会乱成一团,找文件很费劲。所以,我们需要"分而治之"------把不同功能的代码放到包里,比如:

3.2 路由的基本用法
路由就是URL和处理函数的对应关系。FAstAPI使用APIRouter来创建路由。
3.2.1 创建路由对象
python
from fastapi import APIRouter
# 创建一个路由对象
user_router = APIRouter()
3.2.2 定义路由和处理函数
python
@user_router.get("/users/{id}")
async def get_user(id: int):
# {id} 是路径参数,用户访问 /users/123 时,id 就是 123
print(id)
return {"id": id, "name": "Alice", "age": 30}
这里的@user_router.get("/users/{id}") 是装饰器,它告诉FAstAPI:当有人用get方法访问/user/{id} 这个地址时,就执行下面的get_user 函数。{id} 是一个变量,可以是任何数字。
3.2.3 应用(包)路由
python
from fastapi import FastAPI
app = FastAPI()
# 把user_router注册到app
# prefix="" 表示URL前缀,tags=[] 用于文档分类
app.include_router(user_router, prefix="", tags=["用户"])
@app.get("/")
async def say_hello(name: str):
return {"message": f"Hello {name}"}
prefix是前缀,比如你想让所有用户相关的地址都以/api开头,就可以写prefix="/api"
四、请求和相应
获取数据的方式有下列5种:
4.1 路径参数
路径参数是URL中的一部分,用花括号{} 表示。比如/user/{id} 中的id 就是路径参数。
python
# 路径参数
# Union 联合类型
@user_router.get("/detail/{name}", description="根据用户名查询用户", summary="获取用户信息")
async def get_user_by_name(name: Union[str, None] = None):
print(name)
return {"name": name}
其中Union 联合类型是指name这个参数在传参时可以为str或None类型的数据,当然也可以利用Union联合类型给出默认参数,只需要改为name: Union[str, None] = None。
4.2 请求体
请求体式客户端发送给服务器的完整数据,通常是post或put请求时携带的JSON数据。FAstAPI用Pydantic模型来定义请求体的结构。
python
# 请求体
class User(BaseModel):
id: int
name: str = Field(default="张三", max_length=20, min_length=6)
age: int = Field(default=10, gt=0, lt=150)
birthday: Union[date, None] = None
# 简写:
# birthday: Optional[date] = None
friends: List[int] = []
# restful 风格的api
@user_router.post("/")
async def add_user(user: User):
print(user)
return {"user": user}
在这个示例中应用到了Pydantic来对数据进行验证,这种用法在实际开发中是应用很多的。
在这个代码中Field(default="张三", max_length=20, min_length=6) 意思是默认值(default)是张三,字符串的最大长度(max_length)为20,最小长度(min_length)为6。Field(default=10, gt=0, lt=150) 意思是默认值(default)是10,数据必须要是0~150之间的数值。friends: List[int] = [] 是定义了一个列表,要传入的参数要是int类型的数据。
4.3 查询参数
查询参数跟在URL的问号后面,比如 /users?name=Tom&age=20。
特别提醒:路径后面一定要加斜杠 /。
python
@user_router.get("/info/")
async def get_user_info(name: str, age: int):
# name 和 age 是查询参数
# 用户访问 /info/?name=Tom&age=20 时,这两个参数会自动解析
print(name)
print(age)
return {"name": name, "age": age}
注意:如果不加斜杠写成 /info,访问 /info?name=Tom 时可能会出问题。
4.4 表单提交
要处理表单数据,需要先安装一个库:
shell
pip install python-multipart
安装好之后就可以处理提交的表单数据了。
python
@user_router.post("/login/")
async def login(name: str = Form(...), password: str = Form(...)):
print(name)
print(password)
return {"name": name, "password": password}
4.5 文件上传
文件上传有两种方式:bytes 与UploadFile
4.5.1 方式一:使用bytes(适合小文件)
python
# 文件上传
@user_router.post("/upload/")
async def upload(file: bytes = File(...)):
"""
单文件上传
:param file:
:return:
"""
print(f"文件上传成功,大小为:{len(file)}")
return {"file_size": len(file)}
@user_router.post("/uploads/")
async def upload_multiple_files(files: List[bytes] = File(...)):
"""
多文件上传
:param file:
:return:
"""
for file in files:
print(f"文件上传成功,大小为:{len(file)}")
return {
"size": [len(file) for file in files]
}
4.5.2 方式二:使用UploadFile(适合大文件,推荐)
对于大文件,用 bytes 会导致内存占用过高。UploadFile 提供了更友好的接口,它不会一次性把文件读入内存。
python
@user_router.post("/file/upload/")
async def file_upload(file: UploadFile):
"""
单文件上传
:param file:
:return:
"""
if file:
print(file.filename, file.content_type)
# 上传文件
with open(file.filename, "wb") as f:
f.write(await file.file.read())
return {"filename": file.filename, "content_type": file.content_type}
@user_router.post("/file/uploads/")
async def file_uploads(files: List[UploadFile] = File(...)):
"""
UploadFile实现多文件上传
:param files:
:return:
"""
for file in files:
print(file.filename, file.content_type)
# 上传文件
with open(file.filename, "wb") as f:
f.write(await file.file.read())
return {"filename": [file.filename for file in files], "content_type": [file.content_type for file in files]}
五、其他请求信息
5.1 Header(请求头)
请求头包含了很多元信息,比如用户的浏览器类型、认证令牌等。
5.2 Cookie
Cookie是服务器保存在用户浏览器里的小段数据。它常用于识别用户身份,比如"记住登录状态"。当用户再次访问时,浏览器会自动带上Cookie,服务器就能认出这个用户。
python
@user_router.get("/request/")
async def get_request(request: Request):
# 获取请求头 headers Mapping(K-V)
content_type = request.headers.get("Content-Type")
print(content_type)
print("-" * 20)
# 获取 cookie 字典
print(request.cookies)
# URL对象,有很多属性 hostname(主机) path(路径) port(端口)
print(request.url.path)
print(request.url.port)
print(request.url.hostname)
# 获取到请求方式(get/post)
print(request.method)
在上述所有的代码中能用到的模块,包括:
python
from datetime import date
from typing import Union, List
from fastapi import APIRouter, Form, File, Request, UploadFile
from pydantic import BaseModel, Field
注:不要从库中导错模块了。
结语
掌握FastAPI只是开始。异步编程的思维、模块化的设计理念,这些能力会伴随你的整个编程生涯。希望本文能成为你技术路上的一块垫脚石,助你写出更优雅、更高效的代码。