FastAPI代码片段-03-认识响应

105 阅读7分钟

案例三

#ShowAllSeaGoods.py
from fastapi import FastAPI
from fastapi.responses import HTMLResponse
import uvicorn
app = FastAPI()

html_content = """
    <html>
        <head>
            <title>浏览器顶部的标题</title>
        </head>
        <body>
            <h3>三酷猫海鲜店</h3>
            <table border="1">
              <tr>
                 <th> 品   名 </th>
                 <th> 数量 </th>
                 <th> 单位</th>
                 <th> 单价(元)</th>
              </tr>
              <tr>
                 <td>野生大黄鱼</td>
                 <td>20</td>
                 <td>斤</td>
                 <td>168</td>
               </tr>
               <tr>
                 <td>对虾</td>
                 <td>100</td>
                 <td>斤</td>
                 <td>48</td>
               </tr>
               <tr>
                 <td>比目鱼</td>
                 <td>200</td>
                 <td>斤</td>
                 <td>69</td>
               </tr>
               <tr>
                 <td>黄花鱼</td>
                 <td>500</td>
                 <td>斤</td>
                 <td>21</td>
               </tr>
            </table>
        </body>
    </html>
    """
@app.get("/html/", response_class=HTMLResponse)  # 设置响应类为HTML响应
async def read_items1():                                         # 直接返回HTML文本
    return html_content

if __name__ == '__main__':
    uvicorn.run(app=app)

实验三

# 第三章 实验代码 exam03.py
from fastapi import FastAPI
import uvicorn
from typing import Optional
from pydantic import BaseModel
class FishBase(BaseModel):
    name: str = '三纹鱼'
    amount: int = 10
    unit: str = '斤'

class CreateFish(FishBase):
    price: float = 9.0

class Fish(FishBase):
    pass

app = FastAPI()
@app.post("/additem/", response_model=Fish)
async def additem(name: str, fish: CreateFish):
    return fish

if __name__ == "__main__":
    uvicorn.run(app=app)

基础代码

# 【示例3.1】 第三章 第3.2节 code3_1.py
from typing import Optional
import uvicorn
from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()

class UserIn(BaseModel):                   # 定义数据模型
    username: str                        # 定义字段用户名,类型str
    password: str                        # 定义字段密码,类型str
    email: str                            # 定义邮箱邮箱,类型str
    full_name: Optional[str] = None         # 定义可选字段全名,类型str

# 不要在生产环境下这样使用!
@app.post("/user/", response_model=UserIn)  # 注册路由路径,定义响应数据模型为UserIn
async def create_user(user: UserIn):          # 定义请求数据模型为UserIn
    return user                          # 返回请求数据

if __name__ == '__main__':
    uvicorn.run(app=app)
# 【示例3.2】 第三章 第3.2节 code3_2.py
from typing import Optional
import uvicorn
from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()

class UserIn(BaseModel):                   # 定义数据模型
    username: str                        # 定义字段用户名,类型str
    password: str                        # 定义字段密码,类型str
    email: str                            # 定义邮箱邮箱,类型str
    full_name: Optional[str] = None         # 定义可选字段全名,类型str

class UserOut(BaseModel):                 # 定义数据模型
    username: str                       # 定义字段用户名,类型str
    email: str                              # 定义邮箱邮箱,类型str
    full_name: Optional[str] = None     # 定义可选字段全名,类型str

@app.post("/user/", response_model=UserOut)  # 注册路由路径,定义响应模型为UserOut
async def create_user(user: UserIn):         # 定义请求模型为UserIn
    return user  # 返回请求数据

if __name__ == '__main__':
    uvicorn.run(app=app)
# 【示例3.3】 第三章 第3.2节 code3_3.py
from typing import List, Optional
import uvicorn
from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()

class Data(BaseModel):                      # 定义数据模型
    name: str                              # 定义字段,无默认值
    description: Optional[str] = None          # 定义可选字段,默认值为None
    price: float                            # 定义字段,无默认值
    tax: float = 10.5                        # 定义字段,默认值为10.5
    tags: List[str] = []                       # 定义字段,默认值为[]

datas = {                                  # 模拟数据,包含3个对象的字典
    "min": {"name": "最小化", "price": 50.2},  # 仅设置了无默认值字段,其他字段均为默认值
    "max": {"name": "最大化", "description": "都有值", "price": 62, "tax": 20.2},  # 设置了字段值,与默认值不同
    "same": {"name": "默认", "description": None, "price": 50.2, "tax": 10.5, "tags": []},  # 设置了与默认值相同的字段
}

@app.get("/data/{data_id}",                 # 定义路径参数
         response_model=Data,              # 定义响应模型
         response_model_exclude_unset=True  # 使用属性忽略默认值
        )
async def read_item(data_id: str):
    return datas[data_id]                    # 返回模型数据中的某个对象

if __name__ == '__main__':
    uvicorn.run(app=app)
# 【示例3.4】 第三章 第3.2节 code3_4.py
import uvicorn
from fastapi import FastAPI
from pydantic import BaseModel
from typing import Optional
app = FastAPI()

class UserIn(BaseModel):                   # 定义请求模型,用于接收请求数据
    username: str
    password: str
    phone: Optional[str]
    email: Optional[str]
    address: Optional[str]

class UserOut(BaseModel):                  # 定义响应模型,用于输出响应数据
    username: str
    phone: Optional[str]
    email: Optional[str]
    address: Optional[str]

class UserDB(BaseModel):                # 定义业务模型,用于逻辑处理
    username: str
    password_md5: str
    phone: Optional[str]
    email: Optional[str]
    address: Optional[str]

def get_md5(raw_password: str):            #生成密码哈希的模拟函数
    return "密码md5值" + raw_password

def save_user_logic(user_in: UserIn):          # 保存用户的逻辑处理
    password_md5 = get_md5(user_in.password)  # 生成模拟密码
    user_db = UserDB(**user_in.dict(), password_md5=password_md5) # 将请求模型的数据转换为业务模型
    print("此处应该是将user_db保存到数据库的操作代码")
    return user_db

@app.post("/user/", response_model=UserOut)   # 定义响应数据模型为UserOut
async def create_user(user_in: UserIn):         # 定义请求数据模型为UserIn
    user_saved = save_user_logic(user_in)    # 调用逻辑处理函数,执行数据保存动作
    return user_saved

if __name__ == '__main__':
    uvicorn.run(app=app)
# 【示例3.5】 第三章 第3.2节 code3_5.py
import uvicorn
from fastapi import FastAPI
from pydantic import BaseModel
from typing import Optional
app = FastAPI()
class UserBase(BaseModel):              # 定义数据模型基类,包含公用字段
    username: str
    phone: Optional[str]
    email: Optional[str]
    address: Optional[str]

class UserIn(UserBase):                   # 定义请求模型,用于接收请求数据
    password: str

class UserOut(UserBase):                  # 定义响应模型,用于输出响应数据
    pass

class UserDB(UserBase):                # 定义业务模型,用于逻辑处理
    password_md5: str

def get_md5(raw_password: str):            #生成密码哈希的模拟函数
    return "密码md5值" + raw_password

def save_user_logic(user_in: UserIn):          # 保存用户的逻辑处理
    password_md5 = get_md5(user_in.password)  # 生成模拟密码
    user_db = UserDB(**user_in.dict(), password_md5=password_md5) # 将请求模型的数据转换为业务模型
    print("此处应该是将user_db保存到数据库的操作代码")
    return user_db

@app.post("/user/", response_model=UserOut)   # 定义响应数据模型为UserOut
async def create_user(user_in: UserIn):         # 定义请求数据模型为UserIn
    user_saved = save_user_logic(user_in)    # 调用逻辑处理函数,执行数据保存动作
    return user_saved

if __name__ == '__main__':
    uvicorn.run(app=app)
# 【示例3.6】 第三章 第3.2节 code3_6.py
from typing import Union
import uvicorn
from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()

class BaseItem(BaseModel):      # 定义数据模型基类,包含公用的字段
    description: str
    type: str

class Cat(BaseItem):         # 定义数据模型
    type = "cat"                # 定义字段type,默认值为cat

class Dog(BaseItem):       # 定义数据模型
    type = "dog"              # 定义字段type,默认值为dog
    color: str                 # 定义字段color

items = {                      # 模拟数据,分别对应两个数据模型
    "item1": {
        "description": "三酷猫",
        "type": "cat"
    },
    "item2": {
        "description": "中华田园犬",
        "type": "dog",
        "color": "yellow",
    },
}

@app.get("/items/{item_id}",
         response_model=Union[Dog, Cat]  # 使用Union返回多个数据模型
         )
async def read_item(item_id: str):
    return items[item_id]

if __name__ == '__main__':
    uvicorn.run(app=app)
# 【示例3.7】 第三章 第3.3节 code3_7.py
from fastapi import FastAPI
from fastapi.responses import PlainTextResponse  # 导入响应类
import uvicorn
app = FastAPI()

@app.get("/", response_class=PlainTextResponse)  # 设置响应类为纯文本
async def main():
    return "Hello World"
if __name__ == '__main__':
    uvicorn.run(app=app)
# 【示例3.8】 第三章 第3.3节 code3_8.py
from fastapi import FastAPI
from fastapi.responses import HTMLResponse
import uvicorn
app = FastAPI()

html_content = """
    <html>
        <head>
            <title>浏览器顶部的标题</title>
        </head>
        <body>
            <h1>三酷猫</h1>
        </body>
    </html>
    """
@app.get("/html/", response_class=HTMLResponse)  # 设置响应类为HTML响应
async def read_items1():
    # 直接返回HTML文本
    return html_content

@app.get("/default/")  # 未设置响应类
async def read_items2():
    # 使用HTMLResponse对象返回数据
    return HTMLResponse(content=html_content)
if __name__ == '__main__':
    uvicorn.run(app=app)
# 【示例3.9】 第三章 第3.3节 code3_9.py
from fastapi import FastAPI
from fastapi.responses import RedirectResponse  # 导入重定向类
import uvicorn
app = FastAPI()

@app.get("/three")
async def read_three():
    return RedirectResponse("https://github.com/threecoolcat")  # 返回重定向响应
if __name__ == '__main__':
    uvicorn.run(app=app)
# 【示例3.10】 第三章 第3.3节 code3_10.py
from datetime import datetime
from typing import Optional
from fastapi import FastAPI
from fastapi.encoders import jsonable_encoder
from fastapi.responses import JSONResponse
from pydantic import BaseModel
import uvicorn

class Item(BaseModel):  # 定义数据模型
    title: str
    timestamp: datetime
    description: Optional[str] = None

app = FastAPI()

@app.post("/item/")  # 注册路由路径
def update_item(item: Item):
    json_compatible_item_data = jsonable_encoder(item)  # 使用jsonable_encoder转换数据模型
    return JSONResponse(content=json_compatible_item_data)  # 直接返回JSONResponse对象

if __name__ == '__main__':
    uvicorn.run(app=app)
# 【示例3.11】 第三章 第3.3节 code3_11.py
from fastapi import FastAPI, Response
from typing import Optional
import uvicorn
app = FastAPI()

@app.get("/document/")                   # 注册路由路径路径
def get_legacy_data(id: Optional[int] = None):  # 定义可选查询参数
    data = """<?xml version="1.0" encoding="utf-8" ?>
    <Document>
        <Header>
            这里是页头
        </Header>
        <Body>
            这里是内容
        </Body>
        <Footer>
            这里是页脚
        </Footer>
    </Document>
    """
    # 直接返回Response对象,并指定media_type="application/xml"
    return Response(content=data, media_type="application/xml")

if __name__ == '__main__':
    uvicorn.run(app=app)
# 【示例3.12】 第三章 第3.3节 code3_12.py
from fastapi import FastAPI
from fastapi.responses import StreamingResponse  # 导入流响应
import uvicorn
some_file_path = "large-video-file.mp4"  # 运行代码时请替换成真实的视频文件路径
app = FastAPI()

@app.get("/")                                   # 注册路由路径
def main():
    file_like = open(some_file_path, mode="rb")  # 打开文件
    return StreamingResponse(file_like, media_type="video/mp4")  # 返回流并指定媒体类型
if __name__ == '__main__':
    uvicorn.run(app=app)
# 【示例3.13】 第三章 第3.3节 code3_13.py
from fastapi import FastAPI
from fastapi.responses import FileResponse  # 导入文件响应
import uvicorn
some_file_path = "large-video-file.mp4"  # 运行代码时请替换成真实的视频文件路径
app = FastAPI()

@app.get("/")                            # 注册路由路径
async def main():
    return FileResponse(some_file_path)  # 直接使用文件名参数返回文件响应
if __name__ == '__main__':
    uvicorn.run(app=app)