FastAPI FSM 不适用于我使用 FastAPI 运行 aiogram 的情况

FastAPI FSM 不适用于我使用 FastAPI 运行 aiogram 的情况

在本文中,我们将介绍 FastAPI FSM 在使用 FastAPI 运行 aiogram 时的问题以及解决方法。FastAPI 是一个基于 Python 的高性能 Web 框架,而 aiogram 则是一个用于构建 Telegram 机器人的库。然而,当我们尝试在 FastAPI 项目中使用 aiogram 时,发现 FastAPI 的 FSM(有限状态机)在运行时并不起作用,导致状态切换失效。本文将详细讨论这个问题,并提供一种解决方案。

阅读更多:FastAPI 教程

问题描述

在使用 FastAPI 和 aiogram 的过程中,我们经常会遇到需要使用有限状态机(FSM)的情况。FSM 可以帮助我们管理用户与机器人的会话状态,从而实现更复杂的交互逻辑。然而,在将 aiogram 集成到 FastAPI 项目中时,我们发现 FSM 并不起作用,状态切换不起效果。

探究原因

经过调查,我们发现这个问题是由于 FastAPI 和 aiogram 在处理请求和响应时的机制不同所导致的。FastAPI 采用异步的方式处理请求和响应,而 aiogram 则是基于同步的方式运行。这样就造成了在使用 FSM 进行状态切换时的冲突,导致 FSM 功能失效。

解决方案

为了解决这个问题,我们可以使用一个叫做 “aiogram.contrib.middlewares.fastapi” 的中间件库来集成 FastAPI 和 aiogram。该库提供了一个名为 “AiogramApp” 的类,用于处理 aiogram 和 FastAPI 的集成。使用这个库可以使 FSM 功能在 FastAPI 中正常工作。

首先,在项目中安装 “aiogram.contrib.middlewares.fastapi”:

pip install aiogram[fastapi]

然后,在项目中引入所需的依赖:

from aiogram import Bot
from aiogram.contrib.middlewares.fastapi import InvincibleMiddleware
from aiogram.dispatcher import Dispatcher
from aiogram.types import BotCommand
from aiogram.contrib.middlewares.fastapi import RequestContextMiddleware

from fastapi import FastAPI

app = FastAPI()

TOKEN = "YOUR_TELEGRAM_BOT_TOKEN"
bot = Bot(token=TOKEN)
dp = Dispatcher(bot)

接下来,我们需要在 FastAPI 中注册中间件,使其可以正常工作:

@app.on_event("startup")
async def on_startup():
    # 为 FastAPI 和 aiogram 注册中间件
    app.add_middleware(InvincibleMiddleware, dp=dp)
    app.add_middleware(RequestContextMiddleware, dp=dp)

@app.on_event("shutdown")
async def on_shutdown():
    # 关闭 aiogram 的事件循环
    await dp.storage.close()
    await dp.storage.wait_closed()
    await bot.close()

@app.get("/set_commands")
async def set_commands():
    # 设置机器人的命令
    commands = [
        BotCommand(command="/start", description="Start the bot"),
        BotCommand(command="/help", description="Get help"),
    ]
    await bot.set_my_commands(commands)
    return {"message": "Commands set successfully."}

现在,我们可以根据自己的需求,通过 aiogram 的方式来实现有限状态机的功能:

from aiogram import types
from aiogram.dispatcher import FSMContext
from aiogram.dispatcher.filters.state import State, StatesGroup

class Registration(StatesGroup):
    name = State()
    age = State()
    gender = State()

@dp.message_handler(commands=['start'])
async def cmd_start(message: types.Message, state: FSMContext):
    await message.reply("Welcome! What's your name?")
    await Registration.name.set()

@dp.message_handler(state=Registration.name)
async def process_name(message: types.Message, state: FSMContext):
    async with state.proxy() as data:
        data['name'] = message.text

    await message.reply("How old are you?")
    await Registration.next()

@dp.message_handler(state=Registration.age)
async def process_age(message: types.Message, state: FSMContext):
    async with state.proxy() as data:
        data['age'] = message.text

    await message.reply("What's your gender?")
    await Registration.next()

@dp.message_handler(state=Registration.gender)
async def process_gender(message: types.Message, state: FSMContext):
    async with state.proxy() as data:
        data['gender'] = message.text

    await state.finish()
    await message.reply("Thank you for the information! Registration completed.")

通过以上代码,我们可以实现一个简单的用户注册功能,用户需要依次输入姓名、年龄和性别。使用 FSM 可以很方便地管理用户的会话状态,从而实现复杂的功能。

总结

通过使用 “aiogram.contrib.middlewares.fastapi” 中间件库,我们可以在使用 FastAPI 运行 aiogram 时正常使用 FSM 功能。解决了在集成 FastAPI 和 aiogram 时遇到的 FSM 不工作的问题。现在,我们可以轻松地构建复杂的 Telegram 机器人,并充分利用 FastAPI 的高性能特性。

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程