FastAPI框架

FastAPI 是一个用于构建 API 的现代、快速(高性能)的 web 框架,天生的支持异步(async)

它的主要优势在于,高效,几乎可与NodeJS和Go比肩的极高性能,自动生成交互式的文档,省去了开发之后写文档的步骤

安装

好了话不多说,我们从头开始,边学边补充吧,争取细到不能再细

首先是安装,安装非常的简单

pip install fastapi
pip install uvicorn

好啦,完成之后,做一个基础的API吧

创建py文件

from fastapi import FastAPI
    app = FastAPI()
    @app.get("/")
async def root():
    return {"message": "Hello World"}
  • from fastapi import FastAPI这是一个python类,提供了API的所有功能

  • app=FastAPI()将该类实例化

  • @app.get('/')定义路径操作装饰器,告诉FastAPI是正下方的功能负责处理该请求,可用的其他方式:

     @app:get()
    @app.post()
    @app:put()
    @app:delete()
    @app.options()
    @app:head()
    @app:patch()
    @app:trace()
  • async def root():定义路径操作功能,带有async功能的函数

  • return {"message": "Hello World"{返回内容,默认是一个json格式,还可以返回dict、list、str、int等类型,还可以返回Pydantic模型

运行项目

在终端中输入uvicorn main:app --reload

``main:main.py文件 appapp = FastAPI()实例化的FastAPI对象 –reload`:在代码更改后重新启动服务器

第二种方法:

程序入口直接运行:

import uvicorn

if __name__ == '__main__':
    uvicorn.run(app=app)
    #还可以指定host,port等

声明类型

FastAPI的类型声明使用的是 :

做个例子:

from typing import str
def get_full_name(first_name,last_name):
    full_name = first_name.title() + " " + last_name.title()
    return full_name
# 上面这是没加类型提示的
def get_full_name(first_name: str, last_name: str):
# 这事加了类型提示的,添加了这个类型提示不会改变原来的运行结果

这个呢,大家把它当做习惯就好了,无论是否使用这个框架的人 ,都能看懂传参需要什么类型

Optional:可选类型,例:q:Optional[str] = None
q类型可以为str也可以为None

不只是str,能够声明所有标准python类型

比如:int float bool bytes

或者是:dict list set tuple

统统可以使用typing库来声明

from typing import List

而,在List这些嵌套类型中,也可以声明其元素的类型,比如:

def process_items(items:List[str]):

Dict的key和value都可以各自声明

Optional:可选类型,例:q:Optional[str] = None
q类型可以为str也可以为None

哦对,差点忘了,类,也是可以作为类型传递的

class Person:
    def __init__(selfm,name:str):
        self.name = name
def get_person_name(one:Person):
    return one_person.name

交互式文档

交互式文档,在你启动的项目路径的docs下

127.0.0.1:8000/docs

在网页:

这就是交互式文档的所在了,注意交互二字

可以清楚的看到,传参,传的什么参,是否路径参数,一目了然

也可以进入redoc来进入标准的API文档


查询参数和字符串验证

要注意,到目前,我们在函数参数中传的,都只是params,也就是路径上的那种

Query(查询参数)
Query第一个参数用来定义默认值

可用于限制长度或者正则表达式

举个栗子:

#q参数必须为字符串,默认值为None,如果为...,则这个参数必须给值,最小长度3,最大长度50
async def reds(q:str = Query(None,min_length=3,max+length=50)

注意!!!!此处只是参数,如果路径与参数一致,则不会生效

正则表达式

添加regex参数

async def reds(q:str = Query(None,min_length=3,max+length=50,regex='^nice'))

别名(alias)

async def reds(q:str = Query(None,alias = 'asd'))

此时,参数名不再是q,而是asd,函数内部仍使用q

弃用参数(deprecated)

# 我自己测试得出结论,只是提醒作用,并不是不可写入
# 写入Query中,可以改为弃用参数
    deprecated = True

路径参数(path)

首先导入path
from fastapi import path

#和Query使用方法类似,在参数定义之后添加
@app.get("/items/{item_id}")
async def read_items(item_id: int = Path(..., title="The ID of the item to get"))

#注意,由于是路径参数,所以不能为空,所以,应该用...声明
ge代表大于等于,le代表小于等于,gt代表大于,lt代表小于

#将*作为函数第一个参数的话,那么这个函数内所有参数都是关键字参数kwargs,即便没有默认值
举个例子,参数q不带默认值,而it参数带了path
async def re(*,q:str,it:int = path(..., title="The ID of the item to get"))

传递 * 作为函数的第一个参数。

Python 不会对该 * 做任何事情,但是它将知道之后的所有参数都应作为关键字参数(键值对),也被称为 kwargs,来调用。即使它们没有默认值。


pydantic

FastAPI内置的数据模型

from pydantic import BaseModel
class Item(BaseModel):
    name:str
    price:float
    tax:float = None

from pydantic import EmailStr
#还提供了EmailStr类型,邮件地址类型

类似Django内的Model

请求参数

参数中,如果参数=body(…),则这个参数不会在url中,而是会出现在请求体中

栗子:

class Item(BaseModel):
    name:str
    age:int
    price:float


@app.post("/items/ss")
async  def root(a:Item=Body(...,embed=True)):
     
    return {'item':a{
嵌套请求体参数embed=True
参数A=body(...,embed=True)
则可以将参数A当做一个字典的键嵌套进请求体中,例:
    A = body(...,embed=True)
    {
        A:{
            q:1
            w:2
            e:3
        {
    {
    不加embed效果:
    {
        q:1
        w:2
        e:3
    {

响应模型

response_model=**参数,此参数写在路径中,而不是函数**

response_model_exclude_unset = True,返回数据模型中有的字段,没有的字段不返回

response_model_exclude = {某字段{,返回时排除了某个字段

response_model_include = [某字段1,某字段2],返回时只包含其中的某字段

**是解包的意思
假如有多个BaseModel,数据类型有相同的情况下,可以使用.dict形式相互传输数据
但是,前边加了**

响应状态码

from fastapi import status
#如果报错的话,则使用starlette引入
from starlette import status
#可使用HTTP状态码

#错误处理:
from fastapi import HTTPException

#在路径中
@post(/itmes/, status_code=***)