我们先讨论POST请求的content-type 为 application/json的情况,json是比较流行和通用的API接口交互数据的格式。
FastAPI解析json格式数据,使用的是Pydantic,它是一种常用的用于数据接口schema定义与检查的库,你需要定义数据的Model
from typing import Optional
from pydantic import BaseModel
from fastapi import FastAPI
app = FastAPI()
class User(BaseModel):
name: str # 姓名
age: int # 年龄
address: Optional[str] = None # 住址 可选字段
@app.post('/users')
def add_user(user: User):
return {'msg': f'recv user info ,name is {user.name}'}
pydantic 会根据你定义的User类,对POST请求里的json数据进行格式检查,包括字段的类型,是否可选,这需要你对python的类型标注有一定的掌握。
在add_user函数里,你可以通过attribute-style 的方式获取user的属性,想以字典的形式得到user对象的全部属性,可以使用user.json() 方法,它是pydantic对象转字典的方法。
通过测试代码对服务是否可用进行检查
import requests
data = {
'name': 'lili',
'age': 20,
'address': '北京'
}
res = requests.post("http://127.0.0.1:8000/users", json=data)
print(res.text)
得到返回结果
{"msg":"recv user info ,name is lili"}
这说明POST请求发送的json数据被正确解析,且通过了schema验证。
在第一小节里所举的例子过于简单了,真实的项目开发中,提交的json数据往往都是很复杂的,是信息之间具有嵌套关系,比如下面的post请求
import requests
data = {
'name': '小明',
'age': 20,
'address': '北京',
'family': {
'father': '小明爸爸',
'mother': '小明妈妈'
},
'school':{
'name': '育英中学',
'address': '育英路'
},
'course': [{'name': '语文', 'score': 100}, {'name': '数学', 'score': 100}]
}
res = requests.post("http://127.0.0.1:8000/users", json=data)
print(res.json())
family 和 school 是嵌套的字典,course是一个列表,对于着这样的json数据,在服务端,你需要这样来定义schema
from typing import Optional,List
from pydantic import BaseModel
from fastapi import FastAPI
app = FastAPI()
class SchoolInfo(BaseModel):
name: str # 学校名称
address: str # 学校地址
class FamilyInfo(BaseModel):
father: str # 父亲姓名
mother: str # 母亲姓名
class Course(BaseModel):
name: str # 课程名称
score: float # 分数
class User(BaseModel):
name: str # 姓名
age: int # 年龄
address: Optional[str] = None # 住址 可选字段
family: FamilyInfo # 家庭信息
school: SchoolInfo # 学校信息
course: List[Course] # 课程信息
@app.post('/users')
def add_user(user: User):
return user.json()
除了PSOT请求,PATCH,PUT请求同样可以携带请求体,对于他们可以使用相同的方法来处理。
想要解析post请求提交的form表单,需要先安装python-multipart
pip install python-multipart
我们先编写一段测试代码
from urllib import parse
import requests
data = {
'username': 'lili',
'password': 'pd'
}
data = parse.urlencode(data)
headers = {"Content-Type":"application/x-www-form-urlencoded"}
res = requests.post("http://127.0.0.1:8000/login", data=data, headers=headers)
print(res.json())
想要发送form表单,需要指定Content-Type的类型是application/x-www-form-urlencoded, 对data进行url编码,转成字符串,其内容为
username=lili&password=pd
接下来,完成服务端的编写
from fastapi import FastAPI, Form
app = FastAPI()
@app.post('/login')
def login(username: str = Form(...), password: str = Form(...)):
return {'username': username, 'password': password}
username和password参数必须在声明时显示的使用Form,这样才不会被解析成请求参数。
QQ交流群: 211426309