FastAPI快速入门

文章目录

    • 了解FastAPI程序结构
      • 第一步,导入FastAPI
      • 第二步,创建一个app实例
      • 第三步,编写一个 路径操作装饰器
      • 第五步、运行开发服务器uvicorn main:app --reload即可访问api链接。
      • 符案例
    • 声明路径参数
    • 声明路径参数的类型
    • get请求查询参数
    • 请求体
      • 如何实现请求体
    • 跨域配置
    • 数据库连接
      • 1.配置
      • 2.定义实体
      • 3.应用
      • CRUD
      • 在main.py中声明
      • 路由就已经注册好了,可以正常访问

了解FastAPI程序结构

编写一个简单的FastAPI程序需要五个小步骤,先看一个完整例子

from fastapi import FastAPIapp = FastAPI()@app.get("/")
def root():return {"message": "Hello World"}

第一步,导入FastAPI

from fastapi import FastAPI

第二步,创建一个app实例

app = FastAPI()

第三步,编写一个 路径操作装饰器

@app.get("/")

需要注意的两点是:
● 你可以将get操作方法更改成@app.post()、@app.put()、@app.delete()等方法
● 你可以更改相应的路径(“/”)为自己想要的,例如我更改为(“/hello_word/”)
第四步,编写一个路径操作函数,例如下面代码中的root函数。它位于路径操作装饰器下方(见上方例子)
def root():
return {“message”: “Hello World”}
这个函数的返回值可以是
dict,list,单独的值,比如str,int,或者是Pydantic模型

第五步、运行开发服务器uvicorn main:app --reload即可访问api链接。

也可以安装uvicorn,启动

pip install uvicornimport uvicorn
from fastapi import FastAPI
app=FastAPI()
if __name__ == '__main__':uvicorn.run(app)
  1. 例如我在终端运行uvicorn main:app --reload之后,在浏览器输入127.0.0.1:8000,出现"message": "Hello World"这句话。
  2. 在这里可以自己指定要运行的服务器ip和端口号。
  3. 例如:uvicorn main:app --host 127.0.0.1 --port 8001 --reload表示指定本地电脑为服务器,端口号为8001。下面所有的代码演示都默认这个本机ip地址和8001端口号。

符案例

from fastapi import FastAPI
import uvicorn
from service.knowledge_service import router as kno_router
from service.session_service import router as session_router
app = FastAPI()
# 声明多应用
app.include_router(kno_router)
app.include_router(session_router)@app.get("/")
def root():return {"message": "Hello World"}if __name__ == '__main__':uvicorn.run(app="main:app", host="127.0.0.1", port=8000, reload=True)

声明路径参数

from fastapi import FastAPIapp = FastAPI()@app.get("/items/{item_id}") 
def read_item(item_id):return {"item_id": item_id}

声明路径参数的类型

from fastapi import FastAPIapp = FastAPI()@app.get1("/items/{item_id}")
async def read_item1(item_id: int):return {"item_id": item_id}@app.get2("/items/{item_name}")
def read_item2(item_name: str):return {"item_id": item_name}

get请求查询参数

from fastapi import FastAPIapp = FastAPI()@app.get("/files/")
def add(num1: int=2, num2: int=8):return {"num1 + num2 = ": num1 + num2}

请求体

请求体是客户端发送到您的API的数据。 响应体是您的API发送给客户端的数据。
API几乎总是必须发送一个响应体,但是客户端并不需要一直发送请求体。
定义请求体,需要使用 Pydantic 模型。注意以下几点
不能通过GET请求发送请求体
发送请求体数据,必须使用以下几种方法之一:POST(最常见)、PUT、DELETE、PATCH

如何实现请求体

第一步,从pydantic中导入BaseModel

from pydantic import BaseModel

第二步,创建请求体数据模型
声明请求体数据模型为一个类,且该类继承 BaseModel。所有的属性都用标准Python类。和查询参数一样:数据类型的属性如果不是必须的话,可以拥有一个默认值或者是可选None。否则,该属性就是必须的。

from pydantic import BaseModelclass Item(BaseModel):name: str description: str = Noneprice: float tax: float = None 

所以访问链接的时候传入的请求体可以是下面两种

第一种
{"name": "Foo","description": "An optional description","price": 45.2,"tax": 3.5
}
第二种
{"name": "Foo","price": 45.2
}

第三步、将模型定义为参数
将上面定义的模型添加到你的路径操作中,就和定义Path和Query参数一样的方式:

from fastapi import FastAPI
from pydantic import BaseModelclass Item(BaseModel):name: strdescription: str = Noneprice: floattax: float = Noneapp = FastAPI()@app.post("/items/")
async def create_item(item: Item):return item

【注】
(1)

class Item(BaseModel):name: strdescription: str | None = Noneprice: floattax: float | None = None@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Annotated[Item, Body(embed=True)]):results = {"item_id": item_id, "item": item}return results

async def update_item(item_id: int, item: Annotated[Item, Body(embed=True)]):
item: Annotated[Item, Body(embed=True)

item: Annotated[Item, Body(embed=True)]
● 这部分定义了请求体中的数据。它使用了 Annotated 和 Body 来为 item 参数指定详细的信息。
● Annotated[Item, Body(embed=True)]:
○ Item 是一个 Pydantic 模型类,表示请求体的数据结构。Pydantic 会验证请求体中的数据是否符合 Item 类的要求,自动进行类型检查。
○ Item 类的字段包括:
■ name(字符串类型,必填)
■ description(可选的字符串)
■ price(浮动类型,必填)
■ tax(可选的浮动类型)
○ Body(embed=True) 是 FastAPI 提供的一个功能,表示请求体数据应该“嵌套”在一个对象内,而不是直接以属性的形式存在。这意味着,客户端请求的 JSON 数据结构应该像这样:
{
“item”: {
“name”: “item_name”,
“description”: “item_description”,
“price”: 99.99,
“tax”: 5.0
}
}

(2)

from pydantic import BaseModel, Field
description: str | None = Field(default=None, title="The description of the item", max_length=300
)

= Field(…)
● 这里使用了 Pydantic 的 Field 函数来为 description 字段提供更多的元数据和验证规则。
● Field 是 Pydantic 用来定义字段的函数,可以用来设置字段的默认值、验证条件、描述信息等。

跨域配置

from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddlewareapp = 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"}

数据库连接

1.配置

from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
from contextlib import contextmanager
# MySQL所在主机名
HOSTNAME = "127.0.0.1"
# MySQL监听的端口号,默认3306
PORT = 3306
# 连接MySQL的用户名,自己设置
USERNAME = "root"
# 连接MySQL的密码,自己设置
PASSWORD = "root"
# MySQL上创建的数据库名称
DATABASE = "fadiantest"SQLALCHEMY_DATABASE_URL = f"mysql+pymysql://{USERNAME}:{PASSWORD}@{HOSTNAME}:{PORT}/{DATABASE}?charset=utf8mb4"engine = create_engine(SQLALCHEMY_DATABASE_URL, pool_pre_ping=True
)SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)@contextmanager
def get_db():db = SessionLocal()try:yield dbfinally:db.close()Base = declarative_base()

2.定义实体

from sqlalchemy import Column, String, Integer, Float ,DateTime
from config.mysql_config import Baseclass PowerPlant(Base):'''发电量'''__tablename__ = 'power_plant'id = Column(Integer, primary_key=True, autoincrement=True)power_plant_date = Column(String(128))month_power_generation = Column(Float)unit = Column(String(128))

3.应用

from config.mysql_config import get_db
from pojo.entities import PowerPlant@app.get("/hi")
async def say_hello():with get_db() as db:  # 确保会话被正确管理powerPlant = PowerPlant(power_plant_date="2024-11-11", month_power_generation=12.21, unit="机组")db.add(powerPlant)db.commit()return {"message": f"添加成功"}

CRUD

from fastapi import FastAPI,Query
import uvicorn
from sqlalchemy.orm import Session
from sqlalchemy import and_
app = FastAPI()@app.get("/")
async def root():return {"message": "Hello World"}@app.get("/hello/{name}")
async def say_hello(name: str):return {"message": f"Hello {name}"}from config.mysql_config import get_db
from models.entities import PowerPlant
from pojo.entities import PowerPlantPo
@app.get("/hi")
async def say_hello():with get_db() as db:  # 确保会话被正确管理powerPlant = PowerPlant(power_plant_date="2024-11-11", month_power_generation=12.21, unit="机组")db.add(powerPlant)db.commit()return {"message": f"添加成功"}@app.get("/getAll")
async def get_all_power_plants():with get_db() as db:powerPlants = db.query(PowerPlant).all()  # 查询所有记录return [{"id": plant.id,"power_plant_date": plant.power_plant_date,"month_power_generation": plant.month_power_generation,"unit": plant.unit} for plant in powerPlants]@app.put("/update_power_plant")
async def update_power_plant(powerPlant: PowerPlantPo):with get_db() as db:db_power_plant = db.query(PowerPlant).filter(PowerPlant.id == powerPlant.id).first()if db_power_plant:db_power_plant.power_plant_date = powerPlant.power_plant_datedb_power_plant.month_power_generation = powerPlant.month_power_generationdb_power_plant.unit = powerPlant.unitdb.commit()  # 提交事务db.refresh(db_power_plant)  # 确保数据已经被提交并刷新到数据库print(f"Updated power plant: {db_power_plant}")  # 打印确认是否更新return {"message": "更新成功"}return {"message": "未找到该电厂信息"}@app.post("/addpow")
async def add_power_plant(powerPlant: PowerPlantPo):with get_db() as db:powerPlant = PowerPlant(power_plant_date=powerPlant.power_plant_date,month_power_generation=powerPlant.month_power_generation,unit=powerPlant.unit)db.add(powerPlant)  # 将实体添加到会话db.commit()  # 提交事务return {"message": "添加成功"}@app.delete("/deletepower/{plant_id}")
async def delete_power_plant(plant_id: int):with get_db() as db:powerPlant = db.query(PowerPlant).filter(PowerPlant.id == plant_id).first()if powerPlant:db.delete(powerPlant)  # 删除数据db.commit()  # 提交事务return {"message": "删除成功"}return {"message": "未找到该电厂信息"}@app.get("/powerplants")
async def get_power_plants(page: int = 1,  # 默认第一页size: int = 10,  # 默认每页10条name: str = Query(None),  # 过滤条件:电厂名称location: str = Query(None)  # 过滤条件:电厂位置
):offset = (page - 1) * size  # 计算偏移量with get_db() as db:# 构造查询过滤条件query_filters = []if name:query_filters.append(PowerPlant.unit.like(f"%{name}%"))if location:query_filters.append(PowerPlant.power_plant_date.like(f"%{location}%"))# 使用and_将多个过滤条件组合query = db.query(PowerPlant).filter(and_(*query_filters)) if query_filters else db.query(PowerPlant)# 获取总数total_count = query.count()# 获取分页后的数据power_plants = query.offset(offset).limit(size).all()# 计算总页数total_pages = (total_count + size - 1) // sizereturn {"total_count": total_count,"total_pages": total_pages,"page": page,"size": size,"power_plants": power_plants}if __name__ == '__main__':uvicorn.run(app)
``## 多个文件对应flask的蓝图
### 注册多个文件```python
from fastapi import APIRouter
from config.mysql_config import get_db
from models.entities import PowerPlantrouter = APIRouter(prefix="/user",tags=["user"],responses={404: {"description": "Not found"}}
)@router.get('/getAll',tags=["users"])
def read_pow():with get_db() as db:powerPlants = db.query(PowerPlant).all()  # 查询所有记录return [{"id": plant.id,"power_plant_date": plant.power_plant_date,"month_power_generation": plant.month_power_generation,"unit": plant.unit} for plant in powerPlants]

在main.py中声明

from service.user_service import router as user_router
app = FastAPI()app.include_router(user_router)

路由就已经注册好了,可以正常访问

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/62249.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

云计算.运维.面试题

1、计算机能直接识别的语言( C )。 A、汇编语言 B、自然语言 C、机器语言 D、高级语言 2、应用软件是指( D )。 A、所有能够使用的软件 B、能被各应用单位共同使用的某种软件 C、所有计算机上都应使用的基本软件D、专门为某一应用目的而编制的软件 3、计算机的显示器是一…

如何优雅地实现单例模式?内部静态类还是双重检查锁定?

在最近的一个项目中,我需要为一个核心配置类实现单例模式。在设计过程中,我发现要同时满足延迟加载和线程安全这两个要求,常见的实现方式有两种:内部静态类和双重检查锁定(Double-Checked Locking, DCL)。 …

【计算机网络】 —— 数据链路层(壹)

文章目录 前言 一、概述 1. 基本概念 2. 数据链路层的三个主要问题 二、封装成帧 1. 概念 2. 帧头、帧尾的作用 3. 透明传输 4. 提高效率 三、差错检测 1. 概念 2. 奇偶校验 3. 循环冗余校验CRC 1. 步骤 2. 生成多项式 3. 例题 4. 总结 四、可靠传输 1. 基本…

golang实现简单的redis服务

golang 手搓redis服务器仓库地址:实现思路: golang 手搓redis服务器 仓库地址: 仓库: https://github.com/dengjiayue/my-redis.git 实现思路: ● 协议: tcp通信 ● 数据包: 长度(4byte)方法(1byte)数据json ● 数据处理: 单线程map读写 ○ 依次处理待处理队列的请求(chan)…

智慧银行反欺诈大数据管控平台方案(八)

智慧银行反欺诈大数据管控平台的核心理念,在于通过整合先进的大数据技术、算法模型和人工智能技术,构建一个全面、智能、动态的反欺诈管理框架,以实现对金融交易的全方位监控、欺诈行为的精准识别和高效处理。这一理念强调数据驱动决策&#…

3D 生成重建019-LERF用文本在Nerf中开启上帝之眼

3D 生成重建019-LERF用文本在Nerf中开启上帝之眼 文章目录 0 论文工作1 论文方法2 实验结果 0 论文工作 人类利用自然语言描述物理世界,根据各种特性(视觉外观、语义、抽象关联)寻找具体的3D位置。在这项工作中,作者提出了语言嵌…

如何选择合适的期刊投稿?从课题组经验到在线工具的使用全解析

~~~本文是作者个人的经验分享,建立在导师让自己选刊的情况下~~~ 投稿选刊是科研过程中至关重要的一步,选刊过程可能让许多初投稿的研究者感到迷茫和困惑:期刊那么多,如何找到最合适的? 本文将从多个角度介绍如何选择投…

024、Docker与SSH在分布式系统中的实践指南

1. Docker SSH配置最佳实践 Docker容器通常不需要SSH服务来运行,因为它们设计为轻量级、无状态的,并且通常通过Docker命令行界面与宿主机进行交互。但是,在某些情况下,您可能需要通过SSH访问Docker容器进行调试、维护或其他操作。…

【kafka】消息队列的认识,Kafka与RabbitMQ的简单对比

什么是消息队列? 消息队列(Message Queue,简称 MQ)是一个在不同应用程序、系统或服务之间传递数据的机制。 它允许系统间异步地交换信息,而无需直接交互,确保消息的可靠传输。 想象一下,你正在…

.NET MAUI与.NET for Android/IOS的关系

2024年11月13日微软发布了.Net9.0,我打算体验一下。安装好.Net9.0 SDK后发现Visual Studio识别不到9.0,但是通过命令行dotnet --info查看是正常的,后面看到了VS有版本可以升级,把VS升级到17.12.0就可以了。更新完打开以后看到如下界面 这里…

SqlDataAdapter

SqlDataAdapter 是 .NET Framework 和 .NET Core 中提供的一个数据适配器类,属于 System.Data.SqlClient 命名空间(或在 .NET 6 中属于 Microsoft.Data.SqlClient 命名空间)。它的作用是充当数据源(如 SQL Server 数据库&#xff…

【vivado】时序报告--best时序和worst时序

利用vivado进行开发时,生成best时序报告和worst时序报告。 best时序报告 slow选择min_max,fast选择none。 worst时序报告 fast选择min_max,slow选择none。

FastAPI 响应状态码:管理和自定义 HTTP Status Code

FastAPI 响应状态码:管理和自定义 HTTP Status Code 本文介绍了如何在 FastAPI 中声明、使用和修改 HTTP 状态码,涵盖了常见的 HTTP 状态码分类,如信息响应(1xx)、成功状态(2xx)、客户端错误&a…

力扣题库-掷骰子模拟详细解析

题目如下: 有一个骰子模拟器会每次投掷的时候生成一个 1 到 6 的随机数。 不过我们在使用它时有个约束,就是使得投掷骰子时,连续 掷出数字 i 的次数不能超过 rollMax[i](i 从 1 开始编号)。 现在,给你一…

深入浅出:PHP中的数据类型全解析

文章目录 引言理解数据类型标量类型整数 (integer)浮点数 (float)布尔值 (boolean)字符串 (string) 复合类型数组 (array)对象 (object)资源 (resource)NULL 特殊类型Callable强制类型转换 实战案例总结与展望参考资料 引言 在编程的世界里,数据类型是构建任何应用…

当linux可执行文件缺少或者不兼容so库时候,如何查看版本以及缺少那些库

解决方法: ldd 命令来验证程序是否加载了正确的库: 如检查linear_elasticity可执行文件缺少的库,用下面命令: ldd linear_elasticity 可以发现下面not found就是缺少的库,还有对应的库的位置已经版本 $ ldd lin…

第P1周:Pytorch实现mnist手写数字识别

🍨 本文为🔗365天深度学习训练营 中的学习记录博客🍖 原作者:K同学啊 目标 1. 实现pytorch环境配置 2. 实现mnist手写数字识别 3. 自己写几个数字识别试试具体实现 (一)环境 语言环境:Python…

Seq2Seq模型的发展历史;深层RNN结构为什么出现梯度消失/爆炸问题,Transformer为什么不会;Seq2Seq模型存在问题

目录 Seq2Seq模型的发展历史 改进不足的地方 深层RNN结构为什么出现梯度消失/爆炸问题,Transformer为什么不会 深层RNN结构为什么出现梯度消失/爆炸问题: Transformer为什么不会出现梯度消失/爆炸问题: Seq2Seq模型存在问题 T5模型介绍 Seq2Seq模型的发展历史 序列到…

网络安全技术详解:虚拟专用网络(VPN) 安全信息与事件管理(SIEM)

虚拟专用网络(VPN)详细介绍 虚拟专用网络(VPN)通过在公共网络上创建加密连接来保护数据传输的安全性和隐私性。 工作原理 VPN的工作原理涉及建立安全隧道和数据加密: 隧道协议:使用协议如PPTP、L2TP/IP…

Hive 窗口函数与分析函数深度解析:开启大数据分析的新维度

Hive 窗口函数与分析函数深度解析:开启大数据分析的新维度 在当今大数据蓬勃发展的时代,Hive 作为一款强大的数据仓库工具,其窗口函数和分析函数犹如一把把精巧的手术刀,助力数据分析师们精准地剖析海量数据,挖掘出深…