FastAPI 学习与使用

news/2025/3/1 23:43:21/

一、基本要求:

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,Queryfrom fastapi.middleware.wsgi import WSGIMiddlewarefrom flask_app import flask_app
from apps.app01.urls import shop
from apps.app02.urls import user
from apps.app03.app03 import appo3app = 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 WSGIMiddlewareflask_app = Flask(__name__)@flask_app.route('/index')
def flask_main():return {'index':'我是flask的接口'}

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

from fastapi import APIRoutershop = 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 fieldsclass 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 FastAPIfrom fastapi.templating import Jinja2Templates
from fastapi.staticfiles import StaticFilesfrom fastapi.responses import HTMLResponse
from fastapi import Requestimport pathlibimport uvicornfrom tortoise.contrib.fastapi import register_tortoise
from settings import TORTOISE_ORMapp = 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 FastAPIimport uvicornfrom tortoise.contrib.fastapi import register_tortoise
from settings import TORTOISE_ORMapp = 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 fieldsclass 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 BaseDBAsyncClientasync 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 模型,简化数据验证。


http://www.ppmy.cn/news/1575897.html

相关文章

MS SQL 2008 技术内幕:T-SQL 语言基础

《MS SQL 2008 技术内幕:T-SQL 语言基础》是一部全面介绍 Microsoft SQL Server 2008 中 T-SQL(Transact-SQL)语言的书籍。T-SQL 是 SQL Server 的扩展版本,增加了编程功能和数据库管理功能,使得开发者和数据库管理员能…

MySQL 8.4 SQL 全攻略:所有知识点与实战场景

一、引言 MySQL 作为一款广泛使用的开源关系型数据库管理系统,在数据存储和管理领域占据着重要地位。MySQL 8.4 版本在性能、功能和安全性等方面都有了显著的提升。本文将全面介绍 MySQL 8.4 中 SQL 的各种知识点,并结合实战场景进行详细讲解&#xff0…

Spring Boot Admin 踩坑

记一次SpringBoot升级2.x以后遇到的一个小坑&#xff1a; 以前采用1.x的时候&#xff0c;在服务发现中心点击单个服务&#xff0c;可以查看当前服务的详细信息&#xff0c;配置文件只需要简单的配置&#xff0c; &#xff1a; 父级&#xff1a; <parent><groupId>…

雷军力荐学 AI,背后隐藏着怎样的时代密码?

本文围绕雷军力荐学 AI 展开&#xff0c;剖析 AI 发展现状、核心技术&#xff0c;阐述 C 在 AI 的应用&#xff0c;分析 AI 带来的机遇与挑战&#xff0c;还指明学习路径&#xff0c;强调个人学 AI 顺应时代且意义重大&#xff1b;欢迎大家阅读丫&#xff01;&#xff01;&…

【愚公系列】《Python网络爬虫从入门到精通》033-DataFrame的数据排序

标题详情作者简介愚公搬代码头衔华为云特约编辑,华为云云享专家,华为开发者专家,华为产品云测专家,CSDN博客专家,CSDN商业化专家,阿里云专家博主,阿里云签约作者,腾讯云优秀博主,腾讯云内容共创官,掘金优秀博主,亚马逊技领云博主,51CTO博客专家等。近期荣誉2022年度…

Linux操作系统:基于ELK栈的日志分析系统与数据爬虫的设计与实现

基于ELK栈的日志分析系统与数据爬虫的设计与实现 摘要 随着信息技术的飞速发展&#xff0c;服务器运维和数据采集在现代企业中扮演着越来越重要的角色。日志分析系统能够帮助运维人员快速定位问题&#xff0c;提高系统稳定性&#xff1b;数据爬虫则可以用于采集互联网上的公开…

Haption:机器人遥操作触觉力反馈技术革新解决方案

在机器人遥操作过程中&#xff0c;实时、准确地感知机器人所抓握物体的大小与力度&#xff0c;是机器人能否胜任复杂精密任务的关键所在。触觉力反馈技术的融入&#xff0c;正为遥操作技术带来前所未有的变革&#xff0c;推动其迈向新的发展阶段。作为力反馈技术的佼佼者&#…

计算机视觉算法

计算机视觉算法简介 计算机视觉(Computer Vision)作为人工智能的一个重要分支,致力于让计算机能够“看”并理解图像或视频中的内容。其应用领域广泛,从自动驾驶汽车、医疗影像分析到增强现实和安全监控等。随着深度学习技术的发展,计算机视觉已经取得了显著的进展,尤其是…