From 4609cf19c08a03165b663eae22f93decd3c9f948 Mon Sep 17 00:00:00 2001 From: Windows <2659421572@qq.com> Date: Sat, 19 Sep 2026 15:07:02 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=97=A5=E5=BF=97=E6=96=87?= =?UTF-8?q?=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- log.py | 285 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 285 insertions(+) create mode 100644 log.py diff --git a/log.py b/log.py new file mode 100644 index 0000000..8d39a23 --- /dev/null +++ b/log.py @@ -0,0 +1,285 @@ +# '''stu = [ +# {'sid':3,'name':'庞崽子','age':18,'sex':'女','address':'广东省深圳市龙岗区'}, +# {'sid':1,'sex':'女','name':'pzz','age':20,'address':'广东省广州市'}, +# {'sid':2,'name':'啊崽','sex':'男','age':30,'address':'广东省深圳市龙岗区'} +# ] +# +# # 定义用户存储列表 +# user_passwd = [] +# +# from fastapi import FastAPI,Query,Path,Body,Form,File,UploadFile +# from pydantic import BaseModel,Field,HttpUrl +# from typing import Optional,Union,Literal +# from datetime import date,datetime +# from uuid import UUID +# +# ap=FastAPI() +# +# @ap.get('/',summary='测试接口',tags=['测试用']) +# def test(): +# return '测试成功...' +# +# @ap.get('/students/{sid}',tags=['学生'],summary='学生信息查询接口',description='接口更加详细的解释说明...') +# def get_students(sid:int = Path(ge=1,description='查询的id') ): +# return [i for i in stu if i['sid'] == sid] +# +# # 定义请求体模型 +# class Stu(BaseModel): +# sid:int|None|str = 1 +# name:str|None = Field(default='sz',min_length=2,max_length=50) +# age:int = Field(default=0,ge=0,le=150,description='年龄属性') +# sex:Literal['男','女'] # 限制sex属性只能是男、女 +# address:str|None = None +# birthday:date +# url:HttpUrl +# date_creat_date:datetime +# +# @ap.post('/students',tags=['学生'],summary='学生信息新增接口') +# def add_students(s:Stu): +# print( s ) +# print(type(s)) +# print('拿到类属性:',s.sid,s.name,s.address) +# print('将请求体模型的所有类属性解析成字典:',s.model_dump()) +# stu.append( s.model_dump() ) +# return s +# +# class StuUpdate(BaseModel): +# name:str|None = None +# age:int = None +# sex:Literal['男','女']|None = None +# address:str|None = None +# +# @ap.put('/students/{sid}',tags=['学生'],summary='学生信息更新接口') +# def update_students(sid:int,s:StuUpdate): +# d = s.model_dump(exclude_unset=True) +# print( d ) # exclude_unset=True 只解析前端输入的键值对,默认值不会解析 +# for i in stu: +# if i['sid'] == sid: +# for k,v in d.items(): +# i[k] = v +# return {'code':200,'detail':'OK'} +# +# @ap.delete('/students/{sid}',tags=['学生'],summary='学生信息删除接口') +# def delete_students(sid:int): +# for i in stu: +# if i['sid'] == sid: +# stu.remove(i) +# return {'code':200,'detail':'OK'} +# +# # 修改第二个新增接口,路径改成 /students/add 避免路由冲突 +# @ap.post('/students/add',tags=['新增学生请求体'],summary='添加') +# async def add_students2(stu:Stu): +# print('请求体:',stu,type(stu)) +# print('打印StuInfo的属性',stu.sid,stu.name,stu.age) +# print('通过属性字典来查看:', stu.__dict__) +# print('通过model_dump来解析成字典:',stu.model_dump(mode="json")) +# return stu +# +# @ap.get('/users',tags=['用户信息']) +# def get_students(user_passwd=None): +# return user_passwd +# +# class User(BaseModel): +# user:str +# passwd:str +# +# # 用户注册,改成JSON方式,移除Form() +# @ap.post('/users',tags=['用户注册']) +# def user_register(user:User): +# user_passwd.append({'user':user.user,'passwd':user.passwd}) +# return {'code':200,'detail':'OK'} +# @ap.post('/files1') +# def add_file(f:bytes=File(...)): +# print('打印二进制字符节:',f) +# print('将二进制字节码成utf-8字符集:',f.decode('utf-8')) +# with open('test.txt','wb') as file: +# file.write(f) +# @ap.post('/files2') +# async def add_file(f:UploadFile): +# print('uploadfile上传文件,读取该对象:',f) +# print('文件名称:',f.filename) +# text=await f.read() +# print('读取的二进制字节内容:', text) +# print('读取的正常字符内容:', text.decode('utf-8')) +# with open(f.filename,'wb') as file: +# file.write(text) +# +# if __name__ == '__main__': +# import uvicorn +# uvicorn.run("log:ap",host='127.0.0.1',port=12345) +# ''' +# 【day20作业】 +# 把课上的笔记内容理清,再做下面的作业! +from email.policy import default +from idlelib.query import Query + +import datetime + +# import File + +# 1.阐述下你对restful规范的理解 +'''①restful规范不是技术约束,而是一种开发习惯规范而已 +②restful面向资源开发,所以接口的路径名字要以资源的名字书写,见名知意,资源是复数时,要加上s代表单词是复数 +③restful规范不同方法的接口,定位不一样;''' +# 2.什么是路径参数?查询参数? +'''①路径参数:写在路径里面可变的变量参数!可以动态输入接收,用/students/{id} +②查询参数:用来查询获取资源的参数,在url里面是这么体现的:http://地址/路径?查询参数query''' +# 3.get接口跟post接口有什么区别? +'''①get接口是用来获取资源,接口可以直接在浏览器地址栏里访问,没有请求体 +②post接口是用来新增资源的,接口不能直接在浏览器地址栏访问,有请求体,请求体携带的数据不能直接看到''' +# 4.Path() Query() Field() 三者的区别和用途 +'''Path() 用来做路径参数的校验约束! +Query() 用来做查询参数的校验约束! +Field() 用来做请求体模型属性的校验约束!''' +# 5.根据要求完成如下接口 +# ①POST 接口 /login/{session_id},路径参数session_id要校验必须是字母跟数字组合,且长度要大于10字符 +# ②请求体是个Form表单类型,属性包含:username(字符串 3-20 位,字母开头)、passwd(字符串 6-20 位)、is_ok(布尔) +# ③功能函数还要有查询参数usertype,类型是 int +# ④返回登录 username属性、usertype参数值、跟is_ok的json格式 +'''from ai import FastAPI,Form,Path,Query +ap=FastAPI() +@ap.post('/login/{session_id}') +async def login_session( + session_id: str = Path(min_length=11, pattern='^[a-zA-Z0-9]+$'), + username: str = Form(..., min_length=3, max_length=10, pattern='^[a-zA-Z].*'), + password: str = Form(..., min_length=6, max_length=20), + is_ok: bool = Form(), + usertype: int = Query() +): + print('返回的打印有:',session_id,username,is_ok,usertype) + return {'username':username,'is_ok':is_ok,'usertype':usertype} +if __name__ == '__main__': + import uvicorn + uvicorn.run("log:ap",host='127.0.0.1',port=12345)''' + +# 6.根据要求完成如下接口 +# ①GET 接口 /users/{user_id} +# ②user_id 必须 ≥ 1 +# ③返回用户信息 +'''@ap.get( '/users/{user_id}' ) +async def get_users(user_id:int = Path(...,ge=1)): + return {"user_id":user_id}''' +# 7.创建商品的接口POST请求 +# 需求: + +# ①商品名属性:2-50 字符, +# ②价格属性:≥ 0 +# ③库存属性:≥ 0 +# ④分类属性:非空 +# ⑤返回值是该商品的全部信息 +'''from fastapi import FastAPI,Form,Path +from pydantic import BaseModel +from datetime import datetime,date +ap=FastAPI() +class Product(BaseModel): + product_id:int=Path(min_length=2,max_length=50), + product_price:float=Form(...,ge=0), + product_num:str=Form(...,ge=0), + product_type:str +@ap.post( '/products' ) +async def add_products(p:Product): + return p +if __name__ == '__main__': + import uvicorn + uvicorn.run("log:ap",host='127.0.0.1',port=12345)''' + +# 8.定义一个学生列表的全局变量 stu=[] 来存放学生信息,teac = [] 来存老师信息,老师跟学生的信息都是字典的形式存再列表里,要求完成以下接口需求 +# ①定义一个请求体student模型,用来创建新增学生的信息到stu里,包含属性sid(int,默认值none)、sname(str)、age(默认值none,大于等于0)、sex(性别,只能是'男''女') +# 、hobby(set类型,元素是str,多个爱好)、create_data(数据创建时间,datetime类),编写post请求的接口,传入数据,返回学生属性json +'''from FastApi import FastAPI, Query +from pydantic import BaseModel, Field +from typing import Literal +from datetime import datetime, date +from enum import Enum +Stu = [ + {'sid': 3, 'sname': '庞崽子', 'age': 18, 'sex': '女', 'address': '广东省深圳市龙岗区'}, + {'sid': 1, 'sname': 'pzz', 'age': 20, 'sex': '女', 'address': '广东省广州市'}, + {'sid': 2, 'sname': '啊崽', 'age': 30, 'sex': '男', 'address': '广东省深圳市龙岗区'}, +] +stu = [] # 新增学生存这里 +teac = [] # 老师存这里 +ap = FastAPI() +from enum import Enum + +class SexEnum(str, Enum): + f = '女' + m = '男' + +class Student(BaseModel): + sid: int | None = None + sname: str = Field(..., min_length=1, max_length=20) + age: int | None = Field(None, ge=0) + sex: SexEnum | None = None + hobby: set[str] + create_date: date +# ②基于stu学生列表查询,编写一个get请求,可以通过名字、性别(只能男或女)、 +# 年龄(要有范围,0-120)来查询stu里的学生信息,返回值是查询命中的学生信息。如果没有任何的参数,那么就返回所有的学生信息 +@ap.get('/',summary='测试接口',tags=['测试用']) +def test(): + return '测试成功...' +@ap.post('/students') +def add_students(s:Student): + print(s.model_dump()) + stu.append(s.model_dump()) +@ap.get("/students") +async def get_students( + sname: str | None = None, + sex: SexEnum | None = None, + age: int |None= Query(default=None,ge=0,le=None), +): + stu_tmp = [] + for i in Stu: + if sname and sname not in i["sname"]: + continue + if sex and i["sex"] != sex.value: + continue + if age is not None and i["age"] : + continue + stu_tmp.append(i) + return stu_tmp +# ③定义一个请求体teacher模型,用来创建添加老师信息的到teac列表里, +# 有属性name(str或none)、salary(float)、hiredate(date 入职时间)、 +# stu(使用如上的student类模型,嵌套,表示所带的学生),返回值是teac列表的所有信息 +class teacher(BaseModel): + sname:str|None=None + salary:float + hiredate:date + stu:Student +@ap.post('/teachers', summary='新增老师') +async def add_teachers(t: teacher): + teac.append(t.model_dump()) + return teac +if __name__ == '__main__': + import uvicorn + uvicorn.run("log:ap",host='127.0.0.1',port=12345)''' +# 9.编写两个文件上传的接口 +# ①利用bytes字节流类型上传文件,实现多文件上传,并将文件的内容保存到当前目录,保存的文件名字自定义 +# ②利用uploadfile类型上传文件,实现多文件上传,并将文件保存到当前目录,文件名字原来叫什么名字,保存就叫什么名字 +# ③总结下bytes跟uploadfile两种文件上传的区别 +'''from fastapi import FastAPI, Query, UploadFile, File +ap = FastAPI() +@ap.post("/files/bytes") +async def add_bytes_files(f:list[bytes]=File()): + for i in range( len(f) ): + print('解码 :',f[i].decode('utf-8') ) + with open( f'第{i+1}个文件.txt','wb' ) as e: + e.write(f[i]) + return e +@ap.post("/files/uploadfile") +async def add_uploadfile(f:list[UploadFile]): + print(f) + for i in f: + print('文件名字:',i.filename) + text = await i.read() + print( '文件的内容:',text.decode('utf-8') ) + with open(i.filename,'wb') as ff: + ff.write(text) + return f +if __name__ == '__main__': + import uvicorn + uvicorn.run("log:ap",host='127.0.0.1',port=12345)''' +# 10.请总结下fastapi接口编写时,使用pydantic请求体模型的流程 +'''①导入pydantic里的BaseModel基类 +②编写自定义的请求体模型,继承BaseModel基类 +③定义模型的类属性,使用Field()来约束校验属性的数据 +④引用时直接 形参:请求体模型''' \ No newline at end of file