fastapi视频教程,fastapi安装

  fastapi视频教程,fastapi安装

  Python的第三大流行Web框架。在2020年Python开发者的调查结果中,有这样一段话:“FastAPI在本次调查迭代中第一次被引用为选项,这显示了Python的第三大流行Web框架。”

  FastAPI成立于2018年12月,两年内成为仅次于Flask和Django的第三大流行Web框架。又过了一年,到了2022年。虽然2021年Python开发者的调查结果还没出来,但是根据GitHub的星报,Flask 58.7k,Django 63.6k,FastAPI 44.2k的差距越来越小。

  FastAPI特性在这里不会被机器翻译。我们来看看原文:

  我来说一下我选择FastAPI的原因:首先,HttpRunner集成了FastAPI,有一个大老板背书。我相信这个框架足够优秀。其次,评论。用了更多的SpringBoot之后,越来越喜欢评论,层次分明。对于前端分离项目,Flask非常简单,但它附带了Jinja模板引擎。Django是百宝箱但是太重了,FastAPI介于两者之间,是纯后端应用。而且FastAPI是基于Starlette框架,集成了类型检查、OpenAPI(Swagger)等实用功能,和我做基于pytest框架的tep测试工具的思路非常相似。

  安装Python版本的要求是3.6。

  首先安装FastAPI:

  pip安装fastapi

  然后安装ASGI服务器,比如Uvicorn:

  pip安装 uvicon[标准]

  您也可以同时安装fastapi和uvicorn:

  运行pip fastapi [all]来编写main.py文件:

  从键入导入可选

  从fastapi导入FastAPI

  app=FastAPI()

  @app.get(/)

  def read_root():

  return {Hello: World}

  @app.get(/items/{item_id} )

  def read_item(item_id: int,q: Optional[str]=None):

  Return {item _ id: item _ id, q: q}在命令行输入以启动应用程序:

  Uvcorn main: app-reload main是Python模块名。

  是app=FastAPI()。

  - reload在代码更改时自动重启服务器。

  打开浏览器访问:

  http://127.0.0.1:8000/items/5?q=somequery

  您可以看到JSON的响应:

  {item_id: 5, q: somequery}访问:

  http://127 . 0 . 0 . 1:8000/份

  可以看到Swagger接口文档:

  Pydanticpydantic是一个用于数据验证的数据库,FastAPI用它来进行模型验证。例如:

  从键入导入可选

  从fastapi导入FastAPI

  从pydantic导入基本模型

  app=FastAPI()

  类别项目(基本模型):

  名称:str

  价格:浮动

  is_offer:可选[bool]=无

  @app.get(/)

  def read_root():

  return {Hello: World}

  @app.get(/items/{item_id} )

  def read_item(item_id: int,q: Optional[str]=None):

  返回{item_id: item_id, q: q}

  @app.put(/items/{item_id} )

  def update_item(item_id: int,item: Item):

  Return {item _ name: item.name, item _ id: item _ id} Item是参数模型,其名称必须是str类型,价格必须是float类型,is_offer是可选的,可以是bool类型,也可以不是。

  放http://127 . 0 . 0 . 1:8000/件/6

  {

  姓名:东方二,

  价格:2.3,

   is_offer: true

  }

  {

   item_name :东方二,

   item_id: 6

  }路径参数将路径参数传递给函数:

  从fastapi导入FastAPI

  app=FastAPI()

  @app.get(/items/{item_id} )

  异步定义读取项目(项目标识):

  Return {item_id: item_id}您还可以指定Python类型:

  从fastapi导入FastAPI

  app=FastAPI()

  @app.get(/items/{item_id} )

  异步定义read_item(item_id: int):

  Return {item_id: item_id}效果是访问http://127.0.0.1:8000/items/foo会返回{item_id:foo}。

  指定Python类型后,FastAPI将强制进行检查。例如,传递str将会报告一个错误:

  http://127.0.0.1:8000/items/foo

  {

  详细信息:[

  {

  loc: [

  路径,

   item_id

  ],

  msg :值不是有效的整数,

  类型: type_error.integer

  }

  ]

  }传递float也会报错:

  http://127 . 0 . 0 . 1:8000/项/4.2

  匹配序列

  定义的代码序列将决定匹配结果。例如,通常情况下,以下/users/me将返回{user_id :当前用户 }:

  从fastapi导入FastAPI

  app=FastAPI()

  @app.get(/users/me )

  异步定义阅读用户我():

  返回{ 用户标识:当前用户 }

  @app.get(/users/{user_id} )

  异步定义read_user(user_id: str):

  返回{ 用户标识:用户标识}假如这2个小路定义顺序反过来,那么/用户/我就会匹配到/users/{user_id}而返回{ 用户标识:我}了。

  枚举路径

  借助于环境不确定性类,可以实现枚举路径:

  从枚举导入枚举

  从fastapi导入FastAPI

  类别模型名称(字符串,枚举):

  alexnet=alexnet

  resnet=resnet

  lenet=lenet

  app=FastAPI()

  @app.get(/models/{model_name} )

  异步定义获取模型(模型名称:模型名称):

  if模型名==模型名。亚历克斯网:

  返回{ 模型名称:模型名称,消息:深度学习 FTW!}

  if model_name.value==lenet :

  return { 模型名称:模型名称,消息: LeCNN所有图像 }

  返回{ 模型名称:模型名称,消息:有一些剩余 }效果:

  小路匹配

  FastAPI提供了一个小路类型,可以用来对文件路径进行格式匹配:

  从fastapi导入FastAPI

  app=FastAPI()

  @ app。get(/files/{ file _ path:path } )

  异步定义读取文件(文件路径:字符串):

  返回{ 文件路径:文件路径}查询参数查询参数是跟在路径参数后面,用?分隔用连接的参数,比如http://127.0.0.1:8000/items/?跳过=0限制=10 .

  实现:

  从fastapi导入FastAPI

  app=FastAPI()

  fake _ items _ db=[{ item _ name : Foo },{item_name: Bar},{item_name: Baz}]

  @app.get(/items/)

  异步定义read_item(skip: int=0,limit: int=10):

  返回fake _ items _ db[跳过:跳过限制]参数是可选的并且设置了默认值:限制:int=10

  参数是可选的,无默认值:限制:可选[int]=无

  注意:是否可选是由没有人来决定的,而可选择的只是为编译器提供支持,跟FastAPI没有关系。

  参数是必填的:限制:整数

  请求体FastAPI的请求体借助于pydantic来实现:

  从键入导入可选

  从fastapi导入FastAPI

  从pydantic导入基本模型

  类别项目(基本模型):

  名称:str

  描述:可选[str]=无

  价格:浮动

  税:可选[浮动]=无

  app=FastAPI()

  @app.post(/items/)

  异步定义create_item(项目:项目):

  退货项目继承于基本模型来自定义型号,FastAPI会自动转换为JSON。

  Pydantic PyCharm插件插件提高编码体验:

  自动完成型检查修复搜索检查路径参数查询参数请求体

  总结一下,在函数参数中,网址路径中定义的叫做路径参数,没有定义的叫做查询参数,类型是pydantic模型的叫做请求体,FastAPI会根据这套规则来自动识别:

  从键入导入可选

  从fastapi导入FastAPI

  从pydantic导入基本模型

  类别项目(基本模型):

  名称:str

  描述:可选[str]=无

  价格:浮动

  税:可选[浮动]=无

  app=FastAPI()

  @app.put(/items/{item_id} )

  async def create _ Item(Item _ id:int,item: Item,q:可选[str]=无):

  result={item_id: item_id,**item.dict()}

  如果问:

  result.update({q: q})

  回送结果查询参数字符串校验FastAPI提供了询问来支持对入参的字符串校验,比如最小长度和最大长度:

  从键入导入可选

  从fastapi导入FastAPI,查询

  app=FastAPI()

  @app.get(/items/)

  异步定义已读项目(

  问:可选query(none,min_length=3,max_length=50,regex=^fixedquery$)

  ):

  results={ items :[{ item _ id : Foo },{item_id: Bar}]}

  如果问:

  results.update({q: q})

  返回结果甚至其中也能包含正则表达式:regex=^fixedquery$。

  用询问时指定默认值:

  从fastapi导入FastAPI,查询

  app=FastAPI()

  @app.get(/items/)

  异步定义read _ items(q:str=Query(固定查询,min_length=3)):

  results={ items :[{ item _ id : Foo },{item_id: Bar}]}

  如果问:

  results.update({q: q})

  返回结果用询问时必填:

  从fastapi导入FastAPI,查询

  app=FastAPI()

  @app.get(/items/)

  异步定义read_items(q: str=Query(.min_length=3)):

  results={ items :[{ item _ id : Foo },{item_id: Bar}]}

  如果问:

  results.update({q: q})

  返回结果查询参数传目录

  从输入导入列表,可选

  从fastapi导入FastAPI,查询

  app=FastAPI()

  @app.get(/items/)

  async def read _ items(q:Optional[List[str]]=Query(None)):

  query_items={q: q}

  返回查询_项目指定默认值:

  从输入导入列表

  从fastapi导入FastAPI,查询

  app=FastAPI()

  @app.get(/items/)

  async def read _ items(q:List[str]=Query([ foo , bar]):

  query_items={q: q}

  返回query_itemsurl就像这样:http://localhost:8000/items/?q=foo q=bar

  指定别名,比如http://127.0.0.1:8000/items/?item-query=foobaritems中的项目查询不是计算机编程语言变量命名,那么可以设置别名:

  从键入导入可选

  从fastapi导入FastAPI,查询

  app=FastAPI()

  @app.get(/items/)

  async def read _ items(q:Optional[str]=Query(None,alias=item-query ):

  results={ items :[{ item _ id : Foo },{item_id: Bar}]}

  如果问:

  results.update({q: q})

  返回结果路径参数数字校验查询参数用查询做字符串(字符串)校验,路径参数用路径做数字(数字)校验:

  从fastapi导入FastAPI,路径

  app=FastAPI()

  @app.get(/items/{item_id} )

  异步定义已读项目(

  *,

  item_id: int=Path(.title=要获取的项目的ID ,gt=0,le=1000),

  问:str,

  ):

  结果={ 项目标识:项目标识}

  如果问:

  results.update({q: q})

  返回结果路径参数永远都是必填的,因为它是全球资源定位器(统一资源定位器)一部分。表示必填,就算设置为没有人也没有用,仍然是必填。

  葛表示大于等于,更大的等于。

  乐表示小于等于,不相等。

  大型旅行车的表示大于,大于1 .

  它表示小于,不到10%。

  请求体-多参数一、如果请求体嵌套了多个JSON:

  {

  项目:{

  名称: Foo ,

  描述:伪装者,

  价格:42.0,

  税:3.2

  },

  用户:{

  用户名:戴夫,

  全名:大卫格鲁

  }

  }那么就需要在FastAPI中定义多参数:

  从键入导入可选

  从fastapi导入FastAPI

  从pydantic导入基本模型

  app=FastAPI()

  类别项目(基本模型):

  名称:str

  描述:可选[str]=无

  价格:浮动

  税:可选[浮动]=无

  类用户(基本模型):

  用户名:str

  全名:可选[str]=无

  @app.put(/items/{item_id} )

  async def update _ Item(Item _ id:int,item: Item,user: User):

  results={item_id: item_id, item: item, user: user}

  返回结果这里定义了2个型号:项目和用户。

  二、而如果多个参数中有个参数只是单个值,比如这里的重要性:

  {

  项目:{

  名称: Foo ,

  描述:伪装者,

  价格:42.0,

  税:3.2

  },

  用户:{

  用户名:戴夫,

  全名:大卫格鲁

  },

  "重要性":5

  }那么定义成变量并赋值=Body()即可:

  @app.put(/items/{item_id} )

  async def update _ Item(Item _ id:int,item: Item,user: User,importance: int=Body()):

  results={item_id: item_id, item :项目,用户:用户,重要性:重要性}

  返回结果三、在只有一个项目的时候,FastAPI默认会接收这样的正文:

  {

  名称: Foo ,

  描述:伪装者,

  价格:42.0,

  税:3.2

  }假如想把项目也放到数据中:

  {

  项目:{

  名称: Foo ,

  描述:伪装者,

  价格:42.0,

  税:3.2

  }

  }那么可以使用Body(embed=True)):

  从打字进口联盟

  从fastapi导入主体,FastAPI

  从pydantic导入基本模型

  app=FastAPI()

  类别项目(基本模型):

  名称:str

  描述:Union[str,None]=无

  价格:浮动

  税:Union[float,None]=无

  @app.put(/items/{item_id} )

  async def update _ Item(Item _ id:int,item: Item=Body(embed=True)):

  结果={ 项目标识:项目标识,项目:项目}

  返回结果请求体-字段Pydantic提供了字段来给身体中的字段添加额外校验:

  从打字进口联盟

  从fastapi导入主体,FastAPI

  从pydantic导入基本模型,字段

  app=FastAPI()

  类别项目(基本模型):

  名称:str

  描述:Union[str,None]=Field(

  默认值=无,标题=项目的描述,最大长度=300

  )

  price: float=Field(gt=0,description=价格必须大于零)

  税:Union[float,None]=无

  @app.put(/items/{item_id} )

  async def update _ Item(Item _ id:int,item: Item=Body(embed=True)):

  结果={ 项目标识:项目标识,项目:项目}

  返回结果跟FastAPI提供的查询、路径、正文作用类似。

  请求体-嵌套模型传列表:

  从输入导入列表,联合

  从fastapi导入FastAPI

  从pydantic导入基本模型

  app=FastAPI()

  类别项目(基本模型):

  名称:str

  描述:Union[str,None]=无

  价格:浮动

  税:Union[float,None]=无

  标签:List[str]=[]

  @app.put(/items/{item_id} )

  异步定义update_item(item_id: int,item: Item):

  结果={ 项目标识:项目标识,项目:项目}

  返回结果传设置,自动去重:

  从输入导入集,联合

  从fastapi导入FastAPI

  从pydantic导入基本模型

  app=FastAPI()

  类别项目(基本模型):

  名称:str

  描述:Union[str,None]=无

  价格:浮动

  税:Union[float,None]=无

  标签:Set[str]=set()

  @app.put(/items/{item_id} )

  异步定义update_item(item_id: int,item: Item):

  结果={ 项目标识:项目标识,项目:项目}

  返回结果传型号:

  从输入导入集,联合

  从fastapi导入FastAPI

  从pydantic导入基本模型

  app=FastAPI()

  类别图像(基本模型):

  url: str

  名称:str

  类别项目(基本模型):

  名称:str

  描述:Union[str,None]=无

  价格:浮动

  税:Union[float,None]=无

  标签:Set[str]=set()

  image: Union[Image,None]=无

  @app.put(/items/{item_id} )

  异步定义update_item(item_id: int,item: Item):

  结果={ 项目标识:项目标识,项目:项目}

  返回结果入参会像这样:

  {

  名称: Foo ,

  描述:伪装者,

  价格:42.0,

  税:3.2,

  标签:[摇滚,金属,酒吧],

  图像:{

  网址: http://example.com/baz.jpg ,

  名称:Foo直播

  }

  }对于url,pydantic提供了HttpUrl来做校验:

  类别图像(基本模型):

  url: HttpUrl

  名称:str

  传模型的列表:

  从键入导入列表、集合、联合

  从fastapi导入FastAPI

  从pydantic导入基本模型,HttpUrl

  app=FastAPI()

  类别图像(基本模型):

  url: HttpUrl

  名称:str

  类别项目(基本模型):

  名称:str

  描述:Union[str,None]=无

  价格:浮动

  税:Union[float,None]=无

  标签:Set[str]=set()

  图像:Union[列表[图像],无]=无

  @app.put(/items/{item_id} )

  异步定义update_item(item_id: int,item: Item):

  结果={ 项目标识:项目标识,项目:项目}

  返回结果入参像这样:

  {

  名称: Foo ,

  描述:伪装者,

  价格:42.0,

  税:3.2,

  标签:[

  摇滚,

  金属,

  酒吧

  ],

  图像:[

  {

  网址: http://example.com/baz.jpg ,

  名称:Foo直播

  },

  {

  网址: http://example.com/dave.jpg ,

  名称:巴兹

  }

  ]

  }添加示例请求通过配置和schema_extra添加示例请求:

  从打字进口联盟

  从fastapi导入FastAPI

  从pydantic导入基本模型

  app=FastAPI()

  类别项目(基本模型):

  名称:str

  描述:Union[str,None]=无

  价格:浮动

  税:Union[float,None]=无

  类别配置:

  schema_extra={

  示例:{

  名称: Foo ,

  描述:一个非常好的项目,

  价格:35.4,

  税:3.2,

  }

  }

  @app.put(/items/{item_id} )

  异步定义update_item(item_id: int,item: Item):

  结果={ 项目标识:项目标识,项目:项目}

  返回结果在使用以下任一时,都可以添加示例:

  path()Query()Header()Cookie()Body()Form()File()比如:

  从打字进口联盟

  从fastapi导入FastAPI

  从pydantic导入基本模型,字段

  app=FastAPI()

  类别项目(基本模型):

  名称:str=Field(示例=Foo )

  描述:Union[str,None]=Field(默认值=无,示例=非常好的项目)

  价格:浮点=字段(示例=35.4)

  税:Union[float,None]=字段(默认值=无,示例=3.2)

  @app.put(/items/{item_id} )

  异步定义update_item(item_id: int,item: Item):

  结果={ 项目标识:项目标识,项目:项目}

  从输入导入联合返回结果

  从fastapi导入主体,FastAPI

  从pydantic导入基本模型

  app=FastAPI()

  类别项目(基本模型):

  名称:str

  描述:Union[str,None]=无

  价格:浮动

  税:Union[float,None]=无

  @app.put(/items/{item_id} )

  异步定义更新项(

  item_id: int,

  项目:项目=正文(

  示例={

  名称: Foo ,

  描述:一个非常好的项目,

  价格:35.4,

  税:3.2,

  },

  ),

  ):

  结果={ 项目标识:项目标识,项目:项目}

  从输入导入联合返回结果

  从fastapi导入主体,FastAPI

  从pydantic导入基本模型

  app=FastAPI()

  类别项目(基本模型):

  名称:str

  描述:Union[str,None]=无

  价格:浮动

  税:Union[float,None]=无

  @app.put(/items/{item_id} )

  异步定义更新项(

  *,

  item_id: int,

  项目:项目=正文(

  示例={

  正常:{

  概要:一个正常的例子,

  描述:一个**正常* *项目正常工作。,

  值:{

  名称: Foo ,

  描述:一个非常好的项目,

  价格:35.4,

  税:3.2,

  },

  },

  已转换:{

  "摘要":"转换数据的示例",

  描述: FastAPI可以自动将价格字符串转换为实际数字,

  值:{

  名称:酒吧,

  价格: 35.4 ,

  },

  },

  无效的:{

  摘要:无效数据被拒绝,出现错误,

  值:{

  姓名:巴兹,

  价格:三十五点四,

  },

  },

  },

  ),

  ):

  结果={ 项目标识:项目标识,项目:项目}

  返回结果额外数据类型FastAPI除了支持常见的数据类型:

  整数浮点字符串布尔值还支持额外的数据类型:

  全球唯一标识符日期时间。日期时间日期时间。日期日期时间。时间日期时间。时间增量冻结集合十进制字节示例:

  从日期时间导入日期时间,时间,时间增量

  从打字进口联盟

  从全局唯一识别导入全球唯一标识符

  从fastapi导入主体,FastAPI

  app=FastAPI()

  @app.put(/items/{item_id} )

  异步定义已读项目(

  项目标识:UUID

  start_datetime: Union[datetime,None]=Body(默认值=无),

  end_datetime: Union[datetime,None]=Body(默认值=无),

  重复_at: Union[time,None]=Body(默认值=无),

  process_after: Union[timedelta,None]=Body(默认值=无),

  ):

  开始进程=开始日期时间进程之后

  持续时间=结束日期时间-开始进程

  返回{

  项目标识:项目标识,

  开始日期时间:开始日期时间,

  结束日期时间:结束日期时间,

  重复_at :重复_at,

  过程_之后:过程_之后,

  开始进程:开始进程,

  持续时间:持续时间,

  }Cookiefrom类型导入联合

  从fastapi导入饼干

  app=FastAPI()

  @app.get(/items/)

  async def read _ items(ads _ id:Union[str,None]=Cookie(default=None)):

  return {ads_id: ads_id}跟查询和路径用法类似。

  标题from打字输入联盟

  从fastapi导入FastAPI,标题

  app=FastAPI()

  @app.get(/items/)

  async def read _ items(user _ agent:Union[str,None]=Header(default=None)):

  返回{ 用户代理:用户代理}多重页眉用列表,比如:

  从打字进口联盟

  从fastapi导入FastAPI,标题

  app=FastAPI()

  @app.get(/items/)

  async def read _ items(user _ agent:Union[str,None]=Header(default=None)):

  返回{ 用户代理:用户代理}X令牌:foo

  X-Token: bar{

  x标记值:[

  酒吧,

  福

  ]

  }响应模型通过响应模型定义返回模型:

  从输入导入列表,联合

  从fastapi导入FastAPI

  从pydantic导入基本模型

  app=FastAPI()

  类别项目(基本模型):

  名称:str

  描述:Union[str,None]=无

  价格:浮动

  税:Union[float,None]=无

  标签:List[str]=[]

  @app.post(/items/,response_model=Item)

  异步定义create_item(项目:项目):

  返回项目响应_模型的作用是对函数返回值进行过滤,比如:

  从打字进口联盟

  从fastapi导入FastAPI

  从pydantic导入基本模型,EmailStr

  app=FastAPI()

  类用户(基本模型):

  用户名:str

  密码:str

  电子邮件:EmailStr

  全名:联合[字符串,无]=无

  类UserOut(基本型号):

  用户名:str

  电子邮件:EmailStr

  全名:联合[字符串,无]=无

  @app.post(/user/,response_model=UserOut)

  异步定义创建用户(用户:用户):

  返回用户函数返回值是UserIn模型的对象用户,而响应模型的值为用户输出(用户输出相比于UserIn来说,没有密码),那么FastAPI的响应,就是用用户输出对UserIn进行了过滤,返回的是没有密码的用户退出。

  响应模型可以返回默认值:

  从键入导入列表,联合

  从fastapi导入FastAPI

  从pydantic导入基本模型

  app=FastAPI()

  类别项目(基本模型):

  名称:str

  描述:Union[str,None]=无

  价格:浮动

  税:浮动=10.5

  标签:List[str]=[]

  项目={

  foo: {name: Foo , price: 50.2},

  酒吧:{ 名称:酒吧,描述:调酒师,价格:62,税:20.2},

  baz: { 名称: baz ,描述:无,价格:50.2,税金:10.5,标签:[]},

  }

  @app.get(/items/{item_id} ,response_model=Item,response _ model _ exclude _ unset=True)

  异步定义read_item(item_id: str):

  返回项目[item _ id]response _ model _ exclude _ unset=True不返回未显式设置的字段,响应_模型_排除_默认值不返回带默认值的字段,响应_模型_排除_无不返回没有人的字段。

  附加模型在上面的示例中,用户是入参,用户退出是出参,不包含密码,但是在实际情况中,还需要第三个模型UserInDB,在存入数据库时,把密码进行加密。

  代码实现如下:

  从打字进口联盟

  从fastapi导入FastAPI

  从pydantic导入基本模型,EmailStr

  app=FastAPI()

  类用户(基本模型):

  用户名:str

  密码:str

  电子邮件:EmailStr

  全名:联合[字符串,无]=无

  类UserOut(基本型号):

  用户名:str

  电子邮件:EmailStr

  全名:联合[字符串,无]=无

  类UserInDB(BaseModel):

  用户名:str

  哈希密码:字符串

  电子邮件:EmailStr

  全名:联合[字符串,无]=无

  def fake _ password _ hasher(raw _ password:str):

  返回"超级秘密“原始密码

  def fake_save_user(用户输入:用户输入):

  hashed _ password=fake _ password _ hasher(用户密码)

  user _ in _ db=UserInDB(* * user _ in。dict(),哈希密码=哈希密码)

  打印(用户已保存!不完全是)

  返回数据库中的用户

  @app.post(/user/,response_model=UserOut)

  异步定义创建用户(用户输入:用户输入):

  user_saved=fake_save_user(用户输入)

  返回用户_已保存重点是user _ in _ db=UserInDB(* * user _ in。dict(),哈希密码=哈希密码)里面的**user_in.dict()。

  用户输入是UserIn类的Pydantic模型,它有个字典()方法能返回字典。**是拆包,把字典拆成关键字值的形式,上面这行代码等价于:

  用户索引数据库(

  用户名=约翰,

   password="secret",

   email="john.doe@example.com",

   full_name=None,

   hashed_password=hashed_password

  )也相当于:

  UserInDB(

   username = user_dict["username"],

   password = user_dict["password"],

   email = user_dict["email"],

   full_name = user_dict["full_name"],

   hashed_password = hashed_password,

  )FastAPI的一大设计原则是尽量减少重复代码,所以对于UserIn、UserOut、UserInDB可以把里面的相同字段抽象为一个UserBase,其他Model继承即可:

  from typing import Union

  from fastapi import FastAPI

  from pydantic import BaseModel, EmailStr

  app = FastAPI()

  class UserBase(BaseModel):

   username: str

   email: EmailStr

   full_name: Union[str, None] = None

  class UserIn(UserBase):

   password: str

  class UserOut(UserBase):

   pass

  class UserInDB(UserBase):

   hashed_password: str

  def fake_password_hasher(raw_password: str):

   return "supersecret" + raw_password

  def fake_save_user(user_in: UserIn):

   hashed_password = fake_password_hasher(user_in.password)

   user_in_db = UserInDB(**user_in.dict(), hashed_password=hashed_password)

   print("User saved! ..not really")

   return user_in_db

  @app.post("/user/", response_model=UserOut)

  async def create_user(user_in: UserIn):

   user_saved = fake_save_user(user_in)

   return user_saved​​response_model​​除了定义一个Model以外,也能定义多个附加模型。

  比如Union:

  from typing import Union

  from fastapi import FastAPI

  from pydantic import BaseModel

  app = FastAPI()

  class BaseItem(BaseModel):

   description: str

   type: str

  class CarItem(BaseItem):

   type = "car"

  class PlaneItem(BaseItem):

   type = "plane"

   size: int

  items = {

   "item1": {"description": "All my friends drive a low rider", "type": "car"},

   "item2": {

   "description": "Music is my aeroplane, its my aeroplane",

   "type": "plane",

   "size": 5,

   },

  }

  @app.get("/items/{item_id}", response_model=Union[PlaneItem, CarItem])

  async def read_item(item_id: str):

   return items[item_id]比如List:

  from typing import List

  from fastapi import FastAPI

  from pydantic import BaseModel

  app = FastAPI()

  class Item(BaseModel):

   name: str

   description: str

  items = [

   {"name": "Foo", "description": "There comes my hero"},

   {"name": "Red", "description": "Its my aeroplane"},

  ]

  @app.get("/items/", response_model=List[Item])

  async def read_items():

   return items比如Dict:

  from typing import Dict

  from fastapi import FastAPI

  app = FastAPI()

  @app.get("/keyword-weights/", response_model=Dict[str, float])

  async def read_keyword_weights():

   return {"foo": 2.3, "bar": 3.4}参考资料:

  ​​https://fastapi.tiangolo.com/​​

  所有文章公众号【测试开发刚哥】首发!

  版权申明:本文为博主原创文章,转载请保留原文链接及作者。

   ©

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: