当前位置: 首页 > news >正文

FastApi学习

fastapi框架介绍

一个构建API的现代、快速(高性能) 的web框架——更适配于前后端分离

fastapi的两个核心组件

Starlette(负责web部分,Asyncio——python3.5之后开始支持异步)

是一个轻量级的ASGI框架 ,非常适合python构建web服务

Pydantic(负责数据部分,类型提示)

from datetime import datetime
from typing import List, Optional
from pydantic import BaseModel### 类似于js的弱类型语言
class User(Basemodel):###继承Basemodel类id:int  #必须是整型,必须字段name: "John" #必须是字符串,默认值,不是必填signup_ts: Optional[datetime] = None ### 有默认值friends: List[int] = [] ### 有默认值external_data = { ### 可以看做前后端分离时前端传给后端的数据'id': '123','signup_ts' '2019-0601 12:12','friends': [1,2,'3'],
}  ####当数据不匹配时,Pydantic会做类型转换,但是会转换失败比如字母字符串无法转换成数据user = User(**external_data)
print(user.id)
print(repr(user.signup_ts))
print(user.friends)

HTTP协议部分

不作详细笔记,可以看其他视频复习

DIY一个web应用程序测试http协议格式

# web应用程序:遵循http协议——基于请求响应
import socketsock = socket.socket()sock.bind(("127.0.0.1",8080))sock.listen(5)while 1:conn,addr = sock.accept() # 阻塞,等待连接data = conn.recv(1024)print(data)conn.send(b"HTTP/1.1 200 ok\r\nserver:yuan\r\n\r\n<div>111</div>") # 发送数据,"yuan"是服务器表示头,用于告诉运维人员服务器是什么环境conn.close()

tips:为什么响应没有content-type也能正常显示——因为当 HTTP 响应头 ​​没有 Content-Type​​ 时,浏览器会尝试 ​​自动猜测内容类型
在这里插入图片描述

DIY一个web应用程序测试content-type

下载安装postman——便利的测试软件

# web应用程序:遵循http协议——基于请求响应
import socketsock = socket.socket()sock.bind(("127.0.0.1",8080))sock.listen(5)while 1:conn,addr = sock.accept() # 阻塞,等待连接data = conn.recv(1024)print(data)### 增加格式conn.send(b"HTTP/1.1 200 ok\r\nserver:yuan\r\ncontent-type:text/html\r\n\r\n<div>111</div>") # 发送数据,"yuan"是服务器表示头,用于告诉运维人员服务器是什么环境conn.close()

什么是前后端分离模式 (职责分离)

  • 前后端不分离客户端看到的内容所有界面效果都是由服务端提供出来的
    在这里插入图片描述
    后端服务器,在返回页面之前,把数据嵌入到页面再把整个页面当作数据返回给客户端(模板语法)

  • 前后端分离【 把前端的界面效果分离到另一个服务器,python服务端只负责返回数据即可 】
    在这里插入图片描述
    前端形成一个独立的网站,服务端构成一个独立的网站

restful接口开发规范(restful | RPC)

应用程序编程接口(application programming interface,api接口),就是应用程序对外提供了一个操作数据的入口,这个入口可以是一个函数或类方法,也可以是一个url地址或者一个网络地址。当客户端调用这个这个入口时,应用程序则会执行对应的代码操作,给客户端完成相对应的功能。

restful是一种专门对web开发而定义api接口的设计风格,面向资源开发——基于不同的请求动作来表达对数据的增删改查。

在这里插入图片描述

quick start(开始fastapi吧qaq)

安装

pip install fastapi
pip install uvicorn

使用fastAPI写一个简单的后端

from fastapi import FastAPI
import uvicornapp = FastAPI()@app.get("/")  ###restful规范   路径操作装饰器
async def home():  ###async标识函数里面可以await异步  路径操作函数return {"message": "Hello, World!"}@app.get("/shop")
async def shop():return {"shop":"Welcome to the Shop!"}if __name__ == "__main__":  ###如果直接运行这个文件,则执行下面的代码uvicorn.run("testfast:app", port=8080, reload=True)  ###debug=True, reload=True 使得代码修改后自动重启

路径操作装饰器方法参数简介

路径操作修饰器:

@app.get()
@app.post()
@app.put()
@app.patch()
@app.delete()
@app.options()
@app.head()
@app.trace()

参数:

tags=["这是一个***测试接口"]  ###影响自动化文档
summary=""  ###总结
description=""  ###描述
response_description=""  ###响应的描述
deprecated=True/False  ###是否废弃

fastapi 的路由分发 include_router

from typing import Unionfrom fastapi import FastAPI
import uvicorn
from apps.app01.urls import shop
from apps.app02.urls import userapp = FastAPI()app.include_router(shop,prefix="/shop",tags=["shop"])
app.include_router(user,prefix="/user",tags=["user"])if __name__ == "__main__" :uvicorn.run("include_router路由:app", host="127.0.0.1", port=8000, reload=True)

请求与响应

路径参数

@app.get("/user/{id}")
def get_user(id: int): ### 类型转换return {"user_id": id}

查询参数(请求参数)

post也可以有查询参数(?号后面的数据)

from fastapi import FastAPI
from typing import Unionapp02 = FastAPI()@app02.get("/jobs/{kd}")
async def get_jobs(kd,xk=None,gj:Union[str,None] = None): ### kd是路径参数,其他是查询参数,有默认参数可填可不填,无默认参数则必填### Union[str,None] = None  可以写成 Optional[str] = None# 基于kd,xl,gj数据库查询岗位信息return {"kd": kd,"xl": xl,"gj": gj,}

请求体

from fastapi import FastAPI, APIRouter
import uvicornapp03 = APIRouter()@app03.get("/user")
def get_user():return {"user":"Welcome to the Shop!"}
from fastapi import FastAPI
import uvicorn
from apps.app03 import app03app = FastAPI()app.include_router(app03,tags=["app03 请求体数据"])if __name__ == "__main__":uvicorn.run("路径操作装饰器:app", host="127.0.0.1", port=8080, reload=True)
### 扩展,类型限制可以使用Field
from pydantic import BaseModel, Fieldclass User(BaseModel):name: str = Field(..., min_length=2, max_length=50, example="Alice")email: str = Field(..., regex=r"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$")price: float = Field(..., gt=0, description="价格必须大于0")age: int = Field(..., ge=18, le=100, example=25)### ......### @validator 用于对模型字段进行​​自定义验证​​,适用于 Field 无法直接满足的复杂逻辑(如跨字段校验、条件判断等)### 类可以嵌套使用限制类型

form表单数据

@app04.post("/regin")
def reg(username: str=Form(),password: str=Form()):print(f"username: {username}, password: {password}")# 这里可以添加注册逻辑,比如存储到数据库等return {"username": username}

存储在请求体里面
后端只会去x-www-form-urlencoded文件里面找

文件上传

from fastapi import APIRouter, File, UploadFile
import uvicornapp04 = APIRouter()@app04.post("/file")
def get_file(file: bytes = File()):# 适合小文件return {"file_size": len(file)}@app04.post("/files")
def get_files(files: list[bytes] = File()):# 适合小文件return {"file_size": len(files)}@app04.post("/uploadFiles")
def get_uploadFiles(file: UploadFile):# 适合小文件return {"file": file.filename}
File和UploadFile的区别

在这里插入图片描述
何时选择?​

​用 File(bytes)当:​​

  • 文件很小(如 < 1MB)。
  • 只需文件内容,无需元数据。
  • 追求极简代码。

​​用 UploadFile 当:​​

  • 文件较大(如 > 1MB)。
  • 需要文件名、MIME 类型等信息。
  • 需流式处理(如保存到云存储或数据库)。
  • 需要支持暂停/恢复上传。

Request对象

request对象封装了当前HTTP请求的所有信息

from fastapi import Form, APIRouter, Request
from pydantic import BaseModel
from datetime import date
import uvicornapp05 = APIRouter()@app05.post("/items")
def get_items(request: Request):print("url",request.url)print("method",request.method)print("headers",request.headers)print("cookie",request.cookies)print("client",request.client.host)return {"message": "Items received"}

请求静态文件

在web开发中,需要请求很多静态资源文件(不是由服务器生成的的文件),如csss/js和图片文件等。

###导入
from fastapi import FastAPI,StaticFiles###挂载开放的文件夹
app.mount("/static",StaticFiles(directory="statics"))

响应模型相关参数

(1)response_model

@app.post("/items",response_model=Item) ### 路径操作参数

(2)response_model_exclude_unset
响应时排除没有设置的值

(3)INCLUDE和EXCLUDE
response_model_exclude 排除,其他的都包含
response_model_include 除了包含的,都排除

from fastapi import Form, APIRouter, Request
from pydantic import BaseModel,EmailStr
from typing import Union
from datetime import date
import uvicornapp06 = APIRouter()class UserIn(BaseModel):username: strpassword: stremail: strfull_name: Union[str, None] = Noneclass UserOut(BaseModel):username: stremail: EmailStrfull_name: Union[str, None] = Noneclass Item(BaseModel):name: strpric: Union[float, None] = Nonetax: Union[float, None] = Noneitems = {"foo": {"name": "foo", "tax": 0.1},"bar": {"name": "bar", "tax": 0.2},"baz": {"name": "baz", "tax": 0.3},
}@app06.post("/user", response_model=UserOut)
def create_user(user: UserIn):#存到数据库return user# @app06.get("/itemss/{item_id}", response_model=Item, response_model_exclude_none=True)
# def get_item(item_id: str):
#     return items[item_id]# @app06.get("/itemss/{item_id}", response_model=Item, response_model_exclude={"tax"})
# def get_item(item_id: str):
#     return items[item_id]# @app06.get("/itemss/{item_id}", response_model=Item, response_model_include={"tax"})
# def get_item(item_id: str):
#     return items[item_id]@app06.get("/itemss/{item_id}", response_model=Item, response_model_exclude_unset=True)
def get_item(item_id: str):return items[item_id]

Jinja2模板

Jinja2 是一个现代化的、功能丰富的 ​​Python 模板引擎​​,广泛用于生成动态 HTML、XML、JSON 等文本内容

模板简单来说就是一个其中包含占位变量表示动态部分的文件,模板文件在经过动态赋值后,返回给用户

jinja2是flask作者开发的一个模板系统,起初是模仿django模板的一个模板引擎,为flask提供模板支持,由于其灵活,快速和安全等优点被广泛使用。

类似于

"姓名:%s,年龄:%d"%(name,age)  ###模板字符串

jinja2的变量

在这里插入图片描述

from fastapi import FastAPI, Request
import uvicorn
from fastapi.templating import Jinja2Templatesapp = FastAPI()templates = Jinja2Templates(directory="templates")@app.get("/index")
def index(request: Request):name = "root"age = 20books = ["金瓶梅", "红楼梦", "西游记", "三国演义"]user = {"name": "liju","age": age,"books": books}return templates.TemplateResponse("index.html",##模板文件{"request": request, ##请求对象"name":name,"age": age,"books": books,"user": user}, ##上下文对象)if __name__ == "__main__":uvicorn.run("test:app", port=8080, reload=True)

jinja2的过滤器

在这里插入图片描述
在html模板文件中

<p> {{ user|upper }} </p>
<p> {{ pi|round(3) }} </p>

jinja2的控制结构

分支控制
{% if age > 18 %}<div>是否显示1</div>
{% else %}<div>是否显示2</div>
{% endif %}
循环
<ul>{% for book in books %}<li>{{ book }}</li>{% endfor %}
</ul>

ORM操作(Object Relational Mapper)

即用原生python语言去映射一个sql操作

创建模型

from tortoise.models import Model
from tortoise import fields# 选课系统
class Student(Model):id = fields.IntField(pk=True)name = fields.CharField(max_length=32, description="姓名")pwd = fields.CharField(max_length=32, description="密码")sno = fields.IntField(description="学号")##一对多的关系clas = fields.ForeignKeyField("models.Clas",related_name="students")##多对多的关系courses = fields.ManyToManyField("models.Course", related_name="students", through="student_course")### through参数显性展示一个多对多的关系class Course(Model):id = fields.IntField(pk=True)name = fields.CharField(max_length=32, description="课程")class Clas(Model):id = fields.IntField(pk=True)name = fields.CharField(max_length=32,description="班级")class Teacher(Model):id = fields.IntField(pk=True)name = fields.CharField(max_length=32, description="姓名")pwd = fields.CharField(max_length=32, description="密码")tno = fields.IntField(description="教师编号")

ORM的迁移命令

tips
aerich init-db ###命令做数据迁移时无响应
  1. 数据库端口配置不正确——默认端口是3306

api接口与restful规范

简单来说,REST的含义就是客户端与web服务器之间进行交互的时候,使用HTTP协议中的4个请求方法代表不同的动作(面向资源开发,不在url中提现动作)

GET 获取资源
POST 新建资源
PUT 更新资源
DELETE 删除资源get
/students  查看所有学生post
/students  添加学生put
/students/1  更新id=1学生delete
/students/1  删除id=1的学生get
/students/1  查看id=1的学生

ORM查询操作

要用异步标记函数

from models import *students = await  Student.all() #携程并发
print (students[0].name)### 过滤查询filter
students = await Student.filter(name="rain")
print (students[0].name)### 过滤查询get
stu = await Student.get(id=6)
print(stu.name) ### 模糊查询
stu = await Student.filter(sno__gt=2001)
print(stu[0])### value查询
stus = await Student.all().values("name")
print(stus)
http://www.xdnf.cn/news/700993.html

相关文章:

  • AMBA-AHB的控制信号
  • jenkins部署slave动态节点
  • java 开发中 nps的内网穿透 再git 远程访问 以及第三放支付接口本地调试中的作用
  • 使用 find 遍历软链接目录时,为什么必须加 -L
  • 华为OD最新机试真题-按单词下标区间翻转文章内容-OD统一考试(B卷)
  • 【案例95】“小”问题引发的“大”发现---记一次环境修复
  • 十六进制数据转换为对应的字符串
  • Python 如何让自动驾驶的“眼睛”和“大脑”真正融合?——传感器数据融合的关键技术解析
  • Java+POI+EXCEL导出柱形图(多列和单列柱形图)
  • 外骨骼驾驶舱HOMIE——3500元让人形机器人1:1复刻人类动作:类似Mobile ALOHA主从臂的主从分离版
  • 深度学习入门:从零搭建你的第一个神经网络
  • Vue3对接deepseek实现ai对话
  • 系统性学习C语言-第十讲-操作符详讲
  • javascript中运算符的优先级
  • 如何把示例数据0.617、0.229、0.174保留两位小数,并在后面添加%处理,处理后的结果如下:61.7%、22.9%、17.4%
  • Java | 韩顺平 循序渐进学Java自用笔记---OOP高级(二)
  • Kaggle-基于xgboost的销量预测
  • Java基础 Day23
  • ROC和生存曲线的绘制-spss
  • 精准监测,健康无忧--XC3576H工控主板赋能亚健康检测仪
  • 数据库相关面试
  • 74道TypeScript高频题整理(附答案背诵版)
  • Python解析DOC文档表格
  • Ovito建模并正交化方法
  • 删除队列中整数
  • 股票收益率的计算
  • 新能源工厂环境监控系统如何提升电池生产洁净度
  • C# async/await 完全指南:从入门到实践
  • API 与 SPI
  • iframe三方页面嵌入