〇、写在前面
1. FastAPI简介
FastAPI是一种基于Python高性能Web框架。其高性能得益于Starlette和Pydantic。
2. 预备知识
在学习FastAPI之前,你需要了解的知识包括但不限于(请问AI或者度娘):
- python中的装饰器是什么
- 什么是json
- 什么是http协议
- http请求协议的格式是什么
- 什么是url
- 什么是restful接口开发规范
- 什么是前后端
3. 参考资料
FastAPI官方文档:
一、第一次使用FastAPI
1. 环境搭建
创建conda环境后(可选),使用以下命令获取FastAPI:
pip install fastapi[standard]
2. 第一段代码与演示
创建文件main.py并输入以下代码:
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
async def root():
return {"message": "Hello World"}
在终端中输入以下指令运行程序:
fastapi dev main.py
运行成功后会出现以下内容(稍后解释)

分别打开以下两个连接,你就可以看到服务器和自动生成的API文档了!
http://127.0.0.1:8000
http://127.0.0.1:8000/docs
3. 代码解释
# 导入fastapi
from fastapi import FastAPI
# 创建fastapi实例
app = FastAPI()
# 路径操作装饰器
@app.get("/")
# 路径操作函数
async def root():
return {"message": "Hello World"}
其中@app.get("/")中的get方法,属于http四种请求之一,详见:
修饰root方法的async关键字,表示并发函数,详见:
root方法的返回值可以是int、str这样的单值;也可以是list、dict这样的多值;还可以是json和Pydantic 模型
二、路径参数与查询参数
1. 路径参数
路径参数储存在url中,利用url传输数据。代码如下:
from fastapi import FastAPI
app = FastAPI()
@app.get("/{num}")
async def double(num: int):
return num*2
在终端中输入fastapi dev main.py运行程序,接着你在浏览器中输入(“111”可以换成任意整数):
127.0.0.1:8000/111
网页会返回你输入数字的2倍。在fastapi中,大括号“{}”就是路径参数的标志,你可以在输入地址时加上任意路径参数,路径参数传输给后端,经过处理后在返回给你。
2. 查询参数
查询参数也储存在url中。代码如下:
from fastapi import FastAPI
app = FastAPI()
# 用字典模拟一个储存用户名及其编号的数据库
users = {"rock": 7, "jewel": 13 , "anna": 23, "": 89}
# 注意这里和路径参数不一样的地方:路径里没有大括号
@app.get("/")
async def search(name: str, isPrintNum: bool = False):
# 下面这个算法的目的是判断用户是否存在
if name in users:
# 如果用户存在,根据isPrintNum的值决定是否打印用户编号
if isPrintNum:
return {"name": name, "num": users[name]}
else:
return users[name]
else:
# 如果用户不存在,返回错误信息
return {"error": "user not found"}
在终端中输入fastapi dev main.py运行程序,接着在浏览器中输入:
http://127.0.0.1:8000/?name=rock&isPrintNum=true
如果返回以下字符串,则运行成功:

再次观察一下我们在浏览器中输入的地址http://127.0.0.1:8000/?name=rock&isPrintNum=true,问号?后面紧跟的就是查询参数,如果有多个查询参数,用&分割。
三、请求体与表单
1. 请求体
如果我们要传输比较复杂的数据结构,比如较长的字典,直接把数据放在url里就不合适了,这样做有两个缺点:①url太长,不优雅;②数据暴露在外,不安全。这时候我们可以通过请求体传输数据。
在fastapi中,我们要使用pydantic来创建请求体,这个库可以帮我们自动验证数据,进行类型转换。
如果要发送请求体,就必须使用post方法代替原来的get方法
输入以下代码后运行服务器:
from fastapi import FastAPI, Form
from pydantic import BaseModel
app = FastAPI()
# 请求体必须继承pydantic库中的BaseModel类
class User(BaseModel):
name: str
num: int
# 我们可以发送一个json数据,pydantic会自动解析成请求体对象
@app.post("/")
async def add_user(user: User):
return {"name": user.name, "num": user.num}
由于请求体不储存在url中,此时我们就不能通过url传输数据了。可以用以下三种方法向服务器发送包含请求体的请求:
① 使用requests库编写发送请求的测试程序
② 在postman软件中发送请求
③ 在fastapi自动生成的api文档中测试
下面介绍第③种方法:
在浏览器中输入以下url(其实就是在你的url末尾加上/docs路径):
http://127.0.0.1:8000/docs
依次点击:

更改json的内容后点击Exexute测试发送请求:

然后你可以在Response中查看服务器回应的详细信息了!

2. 表单
表单常用于搜集用户信息、账号登录注册。我们可以用表单改进之前的查询函数,做一个用户登录的请求。
# 记得从fastapi中导入Form
from fastapi import FastAPI, Form
app = FastAPI()
users = {"rock": 7, "jewel": 13 , "anna": 23, "": 89}
# 发送表单使用post请求(表单数据封装在请求体里)
@app.post("/")
async def login(name: str = Form(), num:int = Form()):
# 下面这个算法用来判断用户名和编号是否输入正确
if name in users and users[name] == num:
# 如果输入正确,则登陆成功
return {"message":"Welcome, "+name+"!"}
else:
# 如果输入不正确,返回错误信息
return {"error": "Incorrect name or num"}
测试方法同请求体,推荐使用fastapi生成的文档测试。
四、文件
1. 小文件单文件上传
文件一般比较大,肯定不能放在url传输,得封装在请求体里。下面是一个最简单的文件上传请求,将文件转化为字节码进行传输:
from fastapi import FastAPI, File
app = FastAPI()
@app.post("/")
async def upload(file: bytes = File()):
# 返回文件大小
return {
"size": len(file),
}
运行后使用docs进行测试。
2. 小文件多文件上传
输入以下代码(记得导入List用于类型标注):
from fastapi import FastAPI, File
from typing import List
app = FastAPI()
@app.post("/")
async def upload(files: List[bytes] = File()):
# 依次返回文件大小
return [len(file) for file in files]
运行后使用docs进行测试。
3. 大文件单文件上传
字节码适合传输一些小文件,文件储存在内存中一次性传输完成。如果遇到那种以GB为单位的文件,极易导致内存爆炸,用字节码就不合适了。我们可以使用UploadFile来上传文件:
from fastapi import FastAPI, UploadFile
app = FastAPI()
@app.post("/")
async def upload(file: UploadFile):
# 这里添加处理文件数据的代码,比如打印文件的前10个字节
print(file.file.read(10)) # 会显示在终端里而非浏览器
return {"filename": file.filename, "size": file.size}
UploadFile文件对象不会直接包含要传输的数据,你可以根据需要多次少量获取你想要的数据。
4. 大文件多文件上传
多文件上传同理:
from fastapi import FastAPI, UploadFile
from typing import List
app = FastAPI()
@app.post("/")
async def upload(files: List[UploadFile]):
# 分别返回文件名
return {"filename": [file.filename for file in files]}
五、Request对象
有些功能的实现已经不满足于客户端主动向服务端发送请求索取信息,有时候服务端也需要主动向客户端发送请求获取信息。输入以下代码:
from fastapi import FastAPI, Request
app = FastAPI()
@app.post("/")
async def request(r:Request):
# 返回客户端信息
return r.client
你可以直接获得客户端的IP地址和端口号。
1606

被折叠的 条评论
为什么被折叠?



