Fork me on GitHub

FastAPI基础学习总结

一. 什么是FastAPI?

FastAPI Python 高性能 Web 框架,使用 Python 3.6+ 并基于标准的 Python 类型提示,fastapi 是python最快的web框架

二、安装模块

pip install fastapi
 # 依赖
pip install uvicorn[standard]

三、简单实例

1、实例main.py:

from fastapi import FastAPI

app = FastAPI()     # 这里的变量 app 会是 FastAPI 类的一个「实例」

@app.get("/")
async def root():
    return {"message": "Hello World"}

2、运行:

#  命令运行:
uvicorn main:app --reload
#  代码运行:
if __name__ == '__main__':
uvicorn.run(app=app, host="127.0.0.1", port=8000, workers=1)

3、运行成功后可以查看交互式api文档 http://127.0.0.1:8000/docs

总结-fastapi程序的步骤:
导入 FastAPI。
创建一个 app 实例。
编写一个路径操作装饰器(如 @app.get("/"))。
编写一个路径操作函数(如上面的 def root(): ...)。
运行开发服务器(如 uvicorn main:app --reload) 

四、fastapi知识点汇总

1、路径参数

@app.get("/phone/{phone}")
async def get_phone(phone:int): #在这个例子中,phone被声明为 int 类型。
return {"phone":phone}

运行结果:

路径参数 phone的值将作为参数phone传递给你的函数。

所以,如果你运行示例并访问 http://127.0.0.1:8000/phone/123,将会看到如下响应:

{
  "phone": 123
} 

2、查询参数

声明不属于路径参数的其他函数参数时,它们将被自动解释为"查询字符串"参数
查询字符串是键值对的集合,这些键值对位于 URL 的 ? 之后,并以 & 符号分隔。

fake_items_db = [{"item_name": "Foo"}, {"item_name": "Bar"}, {"item_name": "Baz"}]
@app.get("/items/")
async def read_item(skip: int = 0, limit: int = 10):
     return fake_items_db[skip : skip + limit]

所以,如果你运行示例并访问 http://127.0.0.1:8000/items/?skip=0&limit=1将会看到如下响应:

[
  {
    "item_name": "Foo"
  }
]

3、请求体参数

当你需要将数据从客户端(例如浏览器)发送给 API 时,你将其作为「请求体」发送。

请求体是客户端发送给 API 的数据。响应体是 API 发送给客户端的数据。

你的 API 几乎总是要发送响应体。但是客户端并不总是需要发送请求体。

1)请求体 + 路径参数 + 查询参数

from typing import Optional
from fastapi import FastAPI
from pydantic import BaseModel
#声明请求体-Pydantic 模型来声明请求体
class Item(BaseModel):
    name: str
    description: Optional[str] = None       #可选参数
    price: float
    tax: Optional[float] = None

app = FastAPI()

@app.put("/items/{item_id}")      #item_id路径参数
async def create_item(item_id: int, item: Item, q: Optional[str] = None):
    result = {"item_id": item_id, **item.dict()}       #result查询参数
    if q:
        result.update({"q": q})
    return result

运行示例并访问http://127.0.0.1:8000/items/111?q=222

body入参:

{
"name": "test",
"description": "string",
"price": 1,
"tax": 2
}

响应结果展示:

{
  "item_id": 111,
  "name": "test",
  "description": "string",
  "price": 1,
  "tax": 2,
  "q": "222"
}

4、字符串的校验Query

1)FastAPI 允许你为参数声明额外的信息和校验。

from fastapi import FastAPI, Query
from typing  import List,Optional
app = FastAPI()
@app.get("/items/")
def read(paword: str = Query(..., min_length=8,max_length=16)):                  #必须的参数做长度限制
    results = {"items": [{"oneid": "shanghai"}, {"two": "beijing"}]}
    if paword:
        results.update({"paword": paword})
    return results

if __name__ == '__main__':
    import uvicorn
    uvicorn.run(app="fast_06_main:app", host="127.0.0.1", port=8888)

运行示例并访问

http://127.0.0.1:8888/items/?paword=48910328

response出参:

{
  "items": [
    {
      "oneid": "shanghai"
    },
    {
      "two": "beijing"
    }
  ],
  "paword": "48910328"
}

》当你在使用 Query 且需要声明一个值是必需的时,可以将 ... 用作第一个参数值

》特定于字符串的校验:min_length、max_length

2)查询参数列表 / 多个值

例如,要声明一个可在 URL 中出现多次的查询参数 q

from typing import List, Union
from fastapi import FastAPI, Query
app = FastAPI()
@app.get("/items/")
async def read_items(q: Union[List[str], None] = Query(default=None)):
    query_items = {"q": q}
    return query_items

if __name__ == '__main__':
    import uvicorn
    uvicorn.run(app="fast_06_main:app", host="127.0.0.1", port=8888)

运行示例并访问:

http://127.0.0.1:8888/items/?q=foo&q=bar
response出参:
{
  "q": [
    "foo",
    "bar"
  ]
}

5、请求体--多个参数

1)声明多个请求体参数,例如 item 和 user

from typing import Union
import uvicorn
from fastapi import Body, FastAPI
from pydantic import BaseModel
app = FastAPI()

class Item(BaseModel):
    name: str
    description: Union[str, None] = None
    price: float
    tax: Union[float, None] = None

class User(BaseModel):
    username: str
    full_name: Union[str, None] = None

@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": item, "user": user, "importance": importance}
    return results

if __name__ == '__main__':
    uvicorn.run(app=app, host="127.0.0.1", port=8000, workers=1)

 运行实例并访问:http://127.0.0.1:8000/items/123

入参body:

{
"item": {
"name": "test",
"description": "描述",
"price": 0,
"tax": 0
},
"user": {
"username": "test2",
"full_name": "xxx"
},
"importance":1
}

response出参:
{
  "item_id": 123,
  "item": {
    "name": "test",
    "description": "描述",
    "price": 0,
    "tax": 0
  },
  "user": {
    "username": "test2",
    "full_name": "xxx"
  },
  "importance": 1
}

2)嵌入单个请求体参数

例如期望一个拥有 item 键并在值中包含模型内容的 JSON,就像在声明额外的请求体参数时所做的那样,则可以使用一个特殊的 Body 参数 embed

item: Item = Body(embed=True)

from typing import Union
import uvicorn
from fastapi import Body, FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
    name: str
    description: Union[str, None] = None
    price: float
    tax: Union[float, None] = None

@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Item = Body(...,embed=True)):
    results = {"item_id": item_id, "item": item}
    return results

if __name__ == '__main__':
    uvicorn.run(app=app, host="127.0.0.1", port=8000, workers=1)

 运行实例并访问:http://127.0.0.1:8000/items/1

入参body:

{
"item": {
"name": "string",
"description": "string",
"price": 0,
"tax": 0
}
}

response出参:
{
  "item_id": 1,
  "item": {
    "name": "string",
    "description": "string",
    "price": 0,
    "tax": 0
  }
}

6、请求体 - 字段

与使用 QueryPath 和 Body 在路径操作函数中声明额外的校验和元数据的方式相同,你可以使用 Pydantic 的 Field 在 Pydantic 模型内部声明校验和元数据。

from typing import Union

from fastapi import Body, FastAPI
from pydantic import BaseModel, Field

app = FastAPI()


class Item(BaseModel):
    name: str
    description: Union[str, None] = Field(
        default=None, title="The description of the item", max_length=300
    )
    price: float = Field(gt=0, description="The price must be greater than zero")
    tax: Union[float, None] = None


@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Item = Body(embed=True)):
    results = {"item_id": item_id, "item": item}
    return results

注意,Field 是直接从 pydantic 导入的,而不是像其他的(QueryPathBody 等)都从 fastapi 导入。  

7、请求体 - 嵌套模型

使用 FastAPI,你可以定义、校验、记录文档并使用任意深度嵌套的模型(归功于Pydantic)

from typing import Set, Union
import uvicorn
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Image(BaseModel):
    url: str
    name: str

class Item(BaseModel):
    name: str
    description: Union[str, None] = None
    price: float
    tax: Union[float, None] = None
    tags: Set[str] = set()
    image: Union[Image, None] = None

@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Item):
    results = {"item_id": item_id, "item": item}
    return results

if __name__ == '__main__':
    uvicorn.run(app=app, host="127.0.0.1", port=8000, workers=1)

 运行实例并访问:http://127.0.0.1:8000/items/1234

入参body:

{
"name": "名称",
"description": "描述",
"price": 1,
"tax": 10,
"tags": [],
"image": {
"url": "test01",
"name": "test02"
}
}

出参respone

{
  "item_id": 1234,
  "item": {
    "name": "名称",
    "description": "描述",
    "price": 1,
    "tax": 10,
    "tags": [],
    "image": {
      "url": "test01",
      "name": "test02"
    }
  }
}

8、请求体-枚举(Enum)方式限定参数

#可以使用枚举的方式来限定参数为某几个值之内才通过
import uvicorn
from fastapi import FastAPI
from enum import Enum

class ModelName(str,Enum):
    alexnet='alexnet'
    resnet='resnet'
    lenet='lenet'
app=FastAPI()

#使用枚举来限定参数
@app.get('/model/{model_name}')
async def get_model(model_name:ModelName): # 限定参数必须是ModelName枚举中的
    if model_name==ModelName.alexnet:  #枚举判断方法1
        return {"model_name":model_name}
    if model_name.value=="lenet":   #枚举判断方法2
        return {"model_name": model_name}
    return {"model_name": model_name}

  respone出参:

 9、Form表单传参(关键字传参)

import uvicorn
from fastapi import FastAPI, Form
app=FastAPI()

@app.post("/login")
async  def login(*,name: str=Form(...),pwd: str = Form(...)):  # 函数的接受参数第一个是 * 代表此函数只接受关键字传参
    return {
        "name": name,
        "pwd": pwd
    }

if __name__ == '__main__':
    uvicorn.run(app=app, host="127.0.0.1", port=8000, workers=1)

  运行实例并访问:http://127.0.0.1:8000/login

  

  参考地址:https://fastapi.tiangolo.com/zh/

  

  

 

 

  

 

  

  

posted @ 2022-05-15 18:24  橘子偏爱橙子  阅读(248)  评论(0编辑  收藏  举报