首页 前端知识 FastAPI 学习与使用

FastAPI 学习与使用

2025-03-01 12:03:03 前端知识 前端哥 530 550 我要收藏

一、基本要求:

1.python版本3.6+支持异步编程与类型提示 type hints

2. http基础了解(get/post/put/delete)、状态码、请求协议等

3.推荐使用python虚拟环境进行开发环境隔离

python -m venv myenv
source myenv/bin/activate  # Linux/Mac
myenv\Scripts\activate     # Windows

4.了解fastapi最重要的两个插件:Pydantic和Starlette。

Pydantic是基于Python类型提示定义数据验证、序列化和文档库

Starlette是一种轻量级的ASGI框架,是构建高性能Asyncio服务的理想选择。

二、创建项目:

1.mkdir创建目FastApiDemo

在目录下创建虚拟环境myenv执行命令如下:

python3 -m venv myenv

之后创建项目目录mkdir demo1:

得到如下的目录结构:

我这里使用的vscode开发环境:

Ctrl+shift +p 输入python解释器选择同级目录下的myenv环境。

之后在终端执行命令后进入虚拟环境,之后安装所需的插件等。

source myenv/bin/activate

2安装常用依赖库:

常用依赖库
FastAPI框架常用的主要依赖库如下:
❑email.validator:主要用于邮件格式校验处理。
❑requests:使用单例测试TestClient或请求第三方接口时需要使用该
依赖库。
❑aiofiles:主要用于异步处理文件读写操作。❑jinja2:主要供用户渲染静态文件模板时使用,当项目要使用后端渲
染模板时安装该依赖库。
❑Python-multipart:当需要获取From表单数据时,只有通过这个库才
可以提取表单的数据并进行解析。
❑itsdangerous:用于在SessionMiddleware中间件中生成Session临时
身份令牌。
❑graphene:需要GraphQLApp支持时安装这个依赖库。
❑orjson:主要用于JSON序列化和反序列化,如使用FastAPI提供的
ORJSONR-esponse响应体处理时,则需要安装这个依赖库。
❑ujson:主要用于JSON序列化和反序列化,如需要使用FastAPI提供
的UJSONResponse响应体时就需要安装该依赖库。
❑uvicorn:主要用于运行和加载服务应用程序Web服务

单独安装:

pip install fastapi

pip install "uvicorn[standard]" #此命令的主要功能是借助 Python 的包管理工具

                      #pip 来安装 Uvicorn 服务器,并且会额外安装 

                                               # Uvicorn 的标准依赖项

全部安装的方法:

pip install fastapi[all]

创建如下的项目目录结构:

结构介绍:

根目录下main.py是主程序入口,flask_app.py是flask web架构的程序

apps目录下是各个应用程序,现有的代码结构如下各个app代码基本相同。

举例app01:

models.py是模型代码,urls.py实现路由和视图函数(类似Django的路由函数和视图函数)

一下是部分源码:

main.py:

from fastapi import FastAPI
from fastapi.responses import JSONResponse
from fastapi.params import Path,Query

from fastapi.middleware.wsgi import WSGIMiddleware

from flask_app import flask_app
from apps.app01.urls import shop
from apps.app02.urls import user
from apps.app03.app03 import appo3

app = FastAPI(title='主应用',description='我是主应用文档的描述',version='v1.0.0')

#此处实现多应用挂载
app.mount('/flask',app=WSGIMiddleware(app=flask_app),name='flask_app')

#实现路由功能
app.include_router(shop,prefix='/shop',tags=['购物中心'])
app.include_router(user,prefix='/user',tags=['用户中心'])
app.include_router(appo3,prefix='/appo3',tags=['请求体数据'])

@app.get('/index',summary='首页')
async def index():
    return JSONResponse(content={'code':200,'msg':'我是属于FastAPI的接口'})

@app.get('/param/{user_id}/book/{book_name}')
async def get_book_info(user_id: int=Path(...,description='用户ID'),book_name: str=Path(...,
                         description='书名',min_length=1,max_length=128),date: int=Query(...,description='日期'),version: int=Query(None,description='版本号')):
   
    return JSONResponse(content={'code':200,'msg':'我是属于FastAPI的接口','user_id':user_id,'book_name':book_name,'date':date,'version':version})

部分代码介绍:

app.mount('/flask',app=WSGIMiddleware(app=flask_app),name='flask_app')

实现子应用挂载即可以是fastapi应用作子应用也可以挂载其他WSGI应用,此处挂载的是flask应用。

重点介绍路径参数和输入参数:

其中,@app.get()表示API端点的路径操作,也就是API装饰器,它里
面的传输参数则可以理解为路径操作参数;async def get_book_info()(忽略截图函数名的错误)表示
视图函数,该视图函数可以是同步函数,也可以是协程函数,其中需
要传入的参数表示路径函数参数,这里称其为视图函数参数

在上面的参数中:{user_id}和{book_name}两个路径参数变量,
FastAPI会自动把这两个参数传递到视图函数上。在视图函数中,对这
两个路径参数的要求如下:

user_id:int类型,是必填项。如果传递过程中没有这个参数,则会
抛出请求参数校验异常。

...:表示user_id是一个必填项

title:表示参数显示在API交互式文档中的标题名称。

description:表示参数显示在API交互式文档中的详细描述。

ge=10000:表示参数传值需要大于或等于10000,若不满足,则会
抛出请求参数校验异常
book_name:字符串类型,是必填项。如果传递过程中没有这个参数,
则会抛出请求参数校验异常。

min_length=1:表示参数传值需要满足字符串长度大于1,若不符合
该条件,则会抛出请求参数校验异常。
max_length=128:表示参数传值需要满足字符串长度小于50,若不
符合该条件,则会抛出请求参数校验异常

ps:在视图函数中,声明的参数分为有默认值和无默认值两种。如果把有
默认值参数放在无默认值参数的前面,那么IDE会提示告警,并且无法
启动服务。如果坚持把有默认值的参数放在最前面,则需要在第一个
参数前面加一个*

Query(查询)参数不属于路径参数的范畴,但是它会在URL地址上显
示出来,如http://127.0.0.1:8000/items/?skip=0&limit=10,其中,
skip=0&limit就是所谓的查询参数

参数多条件校验
和Path参数一样,FastAPI框架还提供了一个专门用于在查询参数中进
行多维度条件限制的Query类

Query类中的参数和Path中的大部分参数是相同的,所以这里不再重复
说明。这里需要关注user_id字段,该字段在对int类型数据校验时涉及
的参数说明如下:
❑gt:表示大于。
❑lt:表示小于。
❑ge:表示大于或等于。
❑le:表示小于或等于

Body参数
Body(请求体)参数表示在HTTP中提交请求体的数据,它既可以是某
种文档类型的数据,也可以是文件类型或是表单类的数据。常见的请
求体参数传递都是JSON格式的,如果是JSON格式的数据,则通常要求
提交请求头字段Content-Type的格式为如下形式。
FastAPI框架提供了如下3种方式来接收Body参数,并自动把JSON格式
的字符串转换为dict格式。
❑引入Pydantic模型来声明请求体并进行绑定

❑直接通过Request对象获取Body的函数。
❑使用Body类来定义

UploadFile方式接收文件上传
上文示例中,直接使用File对象来接收处理上传的文件,但它接收的是
字节数据,而且缺少相关文件元数据信息,如文件名称、文件大小、
文件格式类型等。如果需要获取更多关于文件的元信息,则需要从请
求头来截取。FastAPI框架提供了一个更高级的UploadFile类来处理类似
需求

flask_app.py代码如下:

from flask import Flask
from fastapi.middleware.wsgi import WSGIMiddleware

flask_app = Flask(__name__)


@flask_app.route('/index')
def flask_main():
    return {'index':'我是flask的接口'}

apps/app01/urls.py代码如下:

from fastapi import APIRouter


shop = APIRouter()

@shop.get('/book')
async def get_book():
    return {'code':200,'msg':'我是属于FastAPI shop app的接口'}

apps/app01/models.py代码如下:

from tortoise.models import Model
from tortoise import fields


class Students(Model):
    id = fields.IntField(pk=True)
    name = fields.CharField(max_length=64,description='姓名')
    pwd = fields.CharField(max_length=64,description='密码')
    sex = fields.CharField(max_length=16,description='性别')
    number = fields.CharField(max_length=64,description='学号')
    # 一对多的关系
    clas = fields.ForeignKeyField('models.Clas',related_name='students')

    #多对多的关系

    course = fields.ManyToManyField('models.Course',related_name='students')

class Course(Model):
    id = fields.IntField(pk=True)
    name = fields.CharField(max_length=64,description='课程名称')
    teacher = fields.ForeignKeyField('models.Teacher',related_name='course')

class Clas(Model):
    id = fields.IntField(pk=True)
    name = fields.CharField(max_length=64,description='班级名称')
  


class Teacher(Model):
    id = fields.IntField(pk=True)
    name = fields.CharField(max_length=64,description='老师名称')
    pwd = fields.CharField(max_length=64,description='密码')
    sex = fields.CharField(max_length=16,description='性别')
    number = fields.CharField(max_length=64,description='工号')

三、静态文件和动态模板文件

request请求可能会请求静态html和一些动态数据的html(正常应该前后端分类,但是一些项目需要后端也实现前端的一些)

在根目录(在main.py同级)创建静态文件夹statics和模板文件夹templates。

在两个目录分别创建需要的文件(html,txt,图片等)细节不做介绍

在main.py下如何引用静态文件和动态模板做一些介绍:

from fastapi import FastAPI

from fastapi.templating import Jinja2Templates
from fastapi.staticfiles import StaticFiles

from fastapi.responses import HTMLResponse
from fastapi import Request

import pathlib

import uvicorn

from tortoise.contrib.fastapi import register_tortoise
from settings import TORTOISE_ORM

app = FastAPI()

templates = Jinja2Templates(directory=f'{pathlib.Path.cwd()}/templates/')
staticfiles = StaticFiles(directory=f'{pathlib.Path.cwd()}/static/')
app.mount('/static',staticfiles,name='static')

register_tortoise(
    app,
    config = TORTOISE_ORM
)


@app.get("/",response_class=HTMLResponse)
async def get_response(request:Request):
    return templates.TemplateResponse('index.html',{'request':request})




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

四、FastAPI的ORM模型

1.ORM模型是操作数据库的

ORM是对SQL语句的一种封装,它是对数据库表中列和行操
作的一种对象映射。在某些情况下,使用ORM库时甚至不需要了解
SQL,只需要通过对表映射出来的实体类模型进行操作就可实现对数
据的增、删、改、查操作

引入ORM库有以下几个好处:
❑对数据进行增、删、改、查更快捷。
❑有效避免编写SQL语句时以字符串拼接或字符串格式化的方式进行
入参的传输,进而规避SQL注入问题。
❑可以自适应且高效地切换到其他DBMS
(DataBase Management System),不需要额外修改逻辑,提高代
码的可移植性和跨平台兼容性

2.tortoise ORM支持的数据库:
1.PostgreSQL >=9.4 version (使用asyncpg)
2.SQLite (使用aiosqlite)
3.mysql/MariaDB (使用aiomysql或使用asyncmy)

安装tortoise ORM
pip install tortoise-orm

这里使用的是mysql所以需要安装异步支持(aiomysql)

pip install aiomysql

# 数据库迁移工具(推荐)
pip install aerich

main.py

from fastapi import FastAPI

import uvicorn

from tortoise.contrib.fastapi import register_tortoise
from settings import TORTOISE_ORM

app = FastAPI()


register_tortoise(
    app,
    config = TORTOISE_ORM
)




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

settings.py和main.py放在同级目录,独立配置文件中初始化 Tortoise

TORTOISE_ORM={
    'connections':{
        'default':{
            'engine': 'tortoise.backends.mysql',
            'credentials':{
                'host':'127.0.0.1',
                'port':3306,
                'user':'root',
                'password':'jlcao',
                'database':'fastapi_demo',
                'minsize':1,
                'maxsize':5,
                'charset':'utf8mb4',
                'echo':True
            }
        }
    },
    'apps':{
        'models':{
            'models':['app01.models','aerich.models'],
            'default_connection':'default',
        }
    },
    'use_tz':False,
    'timezone':'Asia/Shanghai'
}

定义models.py的代码

from tortoise.models import Model
from tortoise import fields


class Students(Model):
    id = fields.IntField(pk=True)
    name = fields.CharField(max_length=64,description='姓名')
    pwd = fields.CharField(max_length=64,description='密码')
    sex = fields.CharField(max_length=16,description='性别')
    number = fields.CharField(max_length=64,description='学号')
    # 一对多的关系
    clas = fields.ForeignKeyField('models.Clas',related_name='students')

    #多对多的关系

    course = fields.ManyToManyField('models.Course',related_name='students')

class Course(Model):
    id = fields.IntField(pk=True)
    name = fields.CharField(max_length=64,description='课程名称')
    teacher = fields.ForeignKeyField('models.Teacher',related_name='course')

class Clas(Model):
    id = fields.IntField(pk=True)
    name = fields.CharField(max_length=64,description='班级名称')
  


class Teacher(Model):
    id = fields.IntField(pk=True)
    name = fields.CharField(max_length=64,description='老师名称')
    pwd = fields.CharField(max_length=64,description='密码')
    sex = fields.CharField(max_length=16,description='性别')
    number = fields.CharField(max_length=64,description='工号')
使用 Aerich 进行数据库迁移

初始化迁移环境,终端执行

aerich init -t settings.TORTOISE_ORM # 指定配置文件中的 ORM 配置
aerich init-db  # 生成初始迁移文件

以上操作后会生成操作的记录文件,在migrations目录下

from tortoise import BaseDBAsyncClient


async def upgrade(db: BaseDBAsyncClient) -> str:
    return """
        CREATE TABLE IF NOT EXISTS `clas` (
    `id` INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
    `name` VARCHAR(64) NOT NULL  COMMENT '班级名称'
) CHARACTER SET utf8mb4;
CREATE TABLE IF NOT EXISTS `students` (
    `id` INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
    `name` VARCHAR(64) NOT NULL  COMMENT '姓名',
    `pwd` VARCHAR(64) NOT NULL  COMMENT '密码',
    `sex` VARCHAR(16) NOT NULL  COMMENT '性别',
    `number` VARCHAR(64) NOT NULL  COMMENT '学号',
    `clas_id` INT NOT NULL,
    CONSTRAINT `fk_students_clas_822af58b` FOREIGN KEY (`clas_id`) REFERENCES `clas` (`id`) ON DELETE CASCADE
) CHARACTER SET utf8mb4;
CREATE TABLE IF NOT EXISTS `teacher` (
    `id` INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
    `name` VARCHAR(64) NOT NULL  COMMENT '老师名称',
    `pwd` VARCHAR(64) NOT NULL  COMMENT '密码',
    `sex` VARCHAR(16) NOT NULL  COMMENT '性别',
    `number` VARCHAR(64) NOT NULL  COMMENT '工号'
) CHARACTER SET utf8mb4;
CREATE TABLE IF NOT EXISTS `course` (
    `id` INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
    `name` VARCHAR(64) NOT NULL  COMMENT '课程名称',
    `teacher_id` INT NOT NULL,
    CONSTRAINT `fk_course_teacher_2de38fe7` FOREIGN KEY (`teacher_id`) REFERENCES `teacher` (`id`) ON DELETE CASCADE
) CHARACTER SET utf8mb4;
CREATE TABLE IF NOT EXISTS `aerich` (
    `id` INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
    `version` VARCHAR(255) NOT NULL,
    `app` VARCHAR(100) NOT NULL,
    `content` JSON NOT NULL
) CHARACTER SET utf8mb4;
CREATE TABLE IF NOT EXISTS `students_course` (
    `students_id` INT NOT NULL,
    `course_id` INT NOT NULL,
    FOREIGN KEY (`students_id`) REFERENCES `students` (`id`) ON DELETE CASCADE,
    FOREIGN KEY (`course_id`) REFERENCES `course` (`id`) ON DELETE CASCADE,
    UNIQUE KEY `uidx_students_co_student_cea02e` (`students_id`, `course_id`)
) CHARACTER SET utf8mb4;"""


async def downgrade(db: BaseDBAsyncClient) -> str:
    return """
        """

数据模型变更后:

aerich migrate --name "add_user_table"  # 生成迁移文件
aerich upgrade  # 应用迁移到数据库

回滚上一个版本:

aerich history  # 查看迁移历史
aerich downgrade  # 回滚到上一个版本
关键插件说明
  1. Tortoise-ORM

    • 异步 ORM 框架,支持 PostgreSQL/MySQL/SQLite。

    • 提供 Django-like 的模型定义和查询 API。

  2. Aerich

    • 数据库迁移工具,类似 Django 的 migrate

    • 自动生成并管理数据库版本变更。

  3. asyncpg/aiosqlite

    • 异步数据库驱动,提升 FastAPI 的并发性能。

  4. tortoise.contrib.pydantic

    • 自动将 Tortoise 模型转换为 Pydantic 模型,简化数据验证。

转载请注明出处或者链接地址:https://www.qianduange.cn//article/22197.html
标签
fastapi
评论
发布的文章

FastAPI 学习与使用

2025-03-01 12:03:03

(转)Java单例模式(1)

2025-03-01 12:03:58

Go语言学习笔记(五)

2025-03-01 12:03:58

微信小程序-二维码绘制

2025-03-01 12:03:57

大家推荐的文章
会员中心 联系我 留言建议 回顶部
复制成功!