FastAPI学习

架构组成

1.Starlette:他是负责web端(请求路由,并发),他需要一个ASGI(Asynchronous server Gateway Interface,是一个Python的Web服务器和应用程序服务器之间的接口规范。它允许开发者使用异步编程模型来处理HTTP请求和响应,以提高服务器的性能和可扩展性。)

2.Pydantic:他是负责传入数据校验部分,具体运用到的地方就是类似于参数校验。

功能介绍

验证

Python数据类型

  • JSON集合,对应的就是dict()

  • JSON数组(list)

  • 字符串,最小最大长度,正则匹配,默认值

  • 数字(int,float)这里python没有Long的概念,直接合并到int中了

Starlette特性

FastAPI是基于Starlette,

知识点

  1. 当使用了第三方依赖库并使用了await方法时,需要在方法前加上async来修饰

  2. 我们通常的等待操作都是等待IO操作,IO操作是引起整个应用缓慢地原因,通常以下会出现IO操作:

 

客户端与服务端通过网络进行数据接收发送。 从磁盘中读取文件至用户空间,从用户空间写文件至磁盘 数据库交互工作 远程API操作

  1. Async和Await

 

async:告诉程序你将进行异步操作, await:他可以将异步进行其他操作,并将返回的结果,所以对于一个异步方法需要await await只能在被定义了async def的方法内被使用

  1. 对于可选参数可设置为:param:Optional[str] =None

  2. 当你想让一个查询参数成为必需的,不声明任何默认值就可以

  3. 如果不是必选的,可以给他设置默认值,或者Optional[str] =None

  4. 如果使用请求体的话在你定义的VO需要导入依赖:

        From pydnatic import basemodel

参数校验

requestParam

使用Query来实现,from fastapi import Query,q: Optional[str] = Query(None, max_length=50, regex="^fixedquery$")也可以添加正则之类的

当你使用Query时,想要这个参数是必须传递的,并且没有默认值,你可以使用 Query(..., min_length=3)其中三个点意味着特殊单独值

Pathvariable

使用Path来实现,from fastapi import path,用法和path相同。举例:

RequestBody

basemodel来表示为请求体,Field来确定对于参数的校验,from pydantic import BaseModel, Field

 

class SummaryRequest(BaseModel): content: str serverName: str = Field(default="chat", description="当前服务只支持pdf、ppt、chat或text", pattern="^(pdf|chat|ppt|text)$") summaryModel: str = Field(default="stuff", description="当前summary模式只支持stuff、refine或map-reduce", pattern="^(stuff|refine|map-reduce)$") streaming: bool = False model: str = Field(default="gpt-3.5-turbo-1106", description="当前model模式只支持gpt-3.5-turbo-1106", pattern="^(gpt-3.5-turbo-1106|gpt-4-preview)$") chunkSize: int = Field(default=10000, ge=0, lt=15000) output_language: str

set,list,optional都是typing依赖库中的,

在请求体中添加数组集合,List,from typing import List, Optional

 

class Item(BaseModel): name: str description: Optional[str] = None price: float tax: Optional[float] = None list: List[str] = [] set: Set[str] = set()

数据类型

  基础数据类型

  int,float,bool,str

  额外数据类型

  • UUID:from uuid import UUID

           item_id: UUID

  • datetime.datetime from datetime import datetime

     start_datetime: Optional[datetime]

  • datetime.time from datetime import time

          repeat_at: Optional[time] = Body(None)

    datetime.date

    datetime.timedelta from datetime import timedelta

    frozenset

    bytes

    Decimal

请求头构造

Cookie参数

导入cookie: from fastapi import cookie

cookie: Optional[str] = Cookie(None)

 

示例: @app.get("/items/") async def read_items(ads_id: Optional[str] = Cookie(None)): return {"ads_id": ads_id}

Header参数

导入Header: from fastapi import Header

 

示例: @app.get("/items/") async def read_items(x_token: Optional[List[str]] = Header(None)): return {"X-Token values": x_token}

响应模型

可以定义一个类专门用来进行数据返回,个人感觉去封装不值当,因为可以直接返回json,

表单数据

  表单数据,当我们传递的时候不是JSON就需要了。

  引入依赖包,需要安装依赖库,pip install python-multipart

  导入依赖from fastapi import form

 

示例: from fastapi import FastAPI, Form app = FastAPI() @app.post("/login/") async def login(username: str = Form(...), password: str = Form(...)): return {"username": username}

表单的编码传输类型为:application/x-www-form-urlencoded

但包含文件的表单编码为 multipart/form-data

异常处理:

如果是用HTTPException的话,需要导入依赖,from FastAPI import HTTPException

使用raise抛出异常,(什么是抛出异常,当代码触犯了该异常,不会执行函数中之后的操作,直接立即停止请求,并返回异常)

自定义异常处理器

有时我们会创建除了HTTPException之外的异常,那么我们就会自定义异常,并且使用自定义异常需要Starlette的异常处理器,@app.exception_handler()

 

示例: 1.首先创建异常对象实例: class UnicornException(Exception): def __init__(self, name: str): self.name = name 2.创建异常处理器 @app.exception_handler(UnicornException) async def unicorn_exception_handler(request: Request, exc: UnicornException): return JSONResponse( status_code=418, content={"message": f"Oops! {exc.name} did something. There goes a rainbow..."}, )

覆盖默认异常处理器

比如说当我们像对于参数校验,想要返回我们自己定义的格式和内容就得重写默认的异常处理。

示例

 

from fastapi import FastAPI, HTTPException from fastapi.exceptions import RequestValidationError from fastapi.responses import PlainTextResponse from starlette.exceptions import HTTPException as StarletteHTTPException app = FastAPI() @app.exception_handler(StarletteHTTPException) async def http_exception_handler(request, exc): return PlainTextResponse(str(exc.detail), status_code=exc.status_code) @app.exception_handler(RequestValidationError) async def validation_exception_handler(request, exc): return PlainTextResponse(str(exc), status_code=400) @app.get("/items/{item_id}") async def read_item(item_id: int): if item_id == 3: raise HTTPException(status_code=418, detail="Nope! I don't like 3.") return {"item_id": item_id}

FastAPI和starlette的关于异常处理和对于返回状态码的使用基本一致,fastAPI是基于starlette

在传入数据修改为json格式进行入库的时候需要引入:

  from fastapi.encoders import jsonable_encoder

  result = jsonable_encoder(item)

依赖注入

需要使用一些特定工具,那么我们就得通过声明方式来进行依赖注入。

依赖注入使用场景:共享业务逻辑,共享数据库链接,实现安全验证,角色权限

from fastapi import Depends

示例

 

from typing import Optional from fastapi import Depends, FastAPI app = FastAPI() #####创建一个使用实例对象, async def common_parameters(q: Optional[str] = None, skip: int = 0, limit: int = 100): return {"q": q, "skip": skip, "limit": limit} ###########在函数声明的时候添加依赖,然后再接下来的函数中就能使用这个实例对象 @app.get("/items/") async def read_items(commons: dict = Depends(common_parameters)): return commons @app.get("/users/") async def read_users(commons: dict = Depends(common_parameters)): return commons

安全性

这部分没啥好说的,基本上都是一样的处理,JWTtoken

中间件

中间件在FastAPI中,我的理解是它是一个类似于拦截器的概念,能够在请求之前或者之后被拦截进行一系列操作。

官方是这么说的他的功能:

  • 它接收你的应用程序的每一个请求.

  • 然后它可以对这个请求做一些事情或者执行任何需要的代码.

  • 然后它将请求传递给应用程序的其他部分 (通过某种路径操作).

  • 然后它获取应用程序生产的响应 (通过某种路径操作).

  • 它可以对该响应做些什么或者执行任何需要的代码.

  • 然后它返回这个 响应.

跨域请求

在FastAPI中解决跨域问题要使用CORSMIddleware中间件来解决,在请求进入时去处理。

使用:

  • 导入CORSMiddleware:from fastapi.middleware.cors import CORSMiddleware

  • 创建一个允许的源列表,也就是一个数组

  • 把它添加到应用中

在这个中间件里面我们可以添加:

  • 凭证:授权token(authorization),headers,cookies

  • 通配符允许方法访问:*

 

示例: from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware app = FastAPI() origins = [ "http://localhost.tiangolo.com", "https://localhost.tiangolo.com", "http://localhost", "http://localhost:8080", ] app.add_middleware( CORSMiddleware, allow_origins=origins, allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) @app.get("/") async def main(): return {"message": "Hello World"}

Background Tasks

具体场景比如一些需要理解返回结果,然后功能让它在后台操作,例如发邮件,接收文件等

示例:

 

from fastapi import BackgroundTasks, FastAPI app = FastAPI() def write_notification(email: str, message=""): with open("log.txt", mode="w") as email_file: content = f"notification for {email}: {message}" email_file.write(content) @app.post("/send-notification/{email}") async def send_notification(email: str, background_tasks: BackgroundTasks): background_tasks.add_task(write_notification, email, message="some notification") return {"message": "Notification sent in the background"}

高级功能介绍

  自定义response

from fastapi.responses import JSONResponse

又因为fastAPI是基于starlette,fastapi的response是与starlette基本相同,所以也可以使用starlette中的response.

如果你想要适应其他类型的Resounse,你可以翻看fastapi.response下的源码,它包含了高很多子类:HTMLResponse,RedirctResponse,streamningResponse等

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

毛毛的毛毛

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值