You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在FastAPI + Uvicorn运行时注入硬件状态对象的引用?

如何在FastAPI + Uvicorn运行时注入硬件状态对象的引用?

我明白你的痛点——想把提前初始化好的硬件状态对象传给FastAPI,又不想把初始化逻辑和API代码混在一起,确实刚开始容易卡壳。下面给你几个实用的方案,都是FastAPI生态里常用的做法:

方案一:用FastAPI原生依赖注入(推荐)

这种方式最符合FastAPI的设计理念,而且方便后续测试(比如替换成模拟对象),耦合度也低。

首先把硬件初始化逻辑单独放在一个文件里,比如hardware_setup.py:

# hardware_setup.py
class Terminal:
    def __init__(self, runtime_config):
        self.config = runtime_config
        # 这里写硬件初始化的逻辑,比如连接设备、加载配置等
    def status(self):
        # 返回硬件状态的具体逻辑
        return {"hardware_state": "active", "config": self.config}

# 根据用户输入和运行时配置创建实例的函数
def create_terminal_instance():
    # 这里模拟获取运行时配置,比如从环境变量、命令行参数读取
    runtime_config = {"baud_rate": 9600, "device_port": "/dev/ttyUSB0"}
    return Terminal(runtime_config)

然后在myapp.py里通过依赖注入拿到这个实例:

# myapp.py
import uvicorn
from fastapi import FastAPI, Depends
from hardware_setup import create_terminal_instance, Terminal

# 提前初始化好Terminal实例
terminal = create_terminal_instance()

fastapi = FastAPI()

# 定义一个依赖函数,返回我们的硬件实例
def get_terminal() -> Terminal:
    return terminal

@fastapi.get("/status")
async def get_hardware_status(terminal: Terminal = Depends(get_terminal)):
    # 直接使用注入的实例
    return terminal.status()

if __name__ == '__main__':
    uvicorn.run("myapp:fastapi", host="0.0.0.0", port=10101)

方案二:把实例挂载到FastAPI应用的state属性上

这种方式更直接,适合简单场景,不需要额外的依赖函数:

修改myapp.py如下:

# myapp.py
import uvicorn
from fastapi import FastAPI
from hardware_setup import create_terminal_instance

fastapi = FastAPI()

# 在应用创建后,把硬件实例挂载到app.state上(这是FastAPI专门用来存应用级状态的地方)
fastapi.state.terminal = create_terminal_instance()

@fastapi.get("/status")
async def get_hardware_status():
    # 直接通过app.state访问实例
    return fastapi.state.terminal.status()

if __name__ == '__main__':
    uvicorn.run("myapp:fastapi", host="0.0.0.0", port=10101)

方案三:全局变量(不推荐,适合小型项目)

如果你的项目非常简单,也可以用全局变量,但这种方式耦合度高,测试时不好替换实例,不推荐大型项目使用:

在hardware_setup.py里直接创建全局实例:

# hardware_setup.py
# ... 之前的Terminal类和create_terminal_instance函数 ...
# 直接创建全局实例
terminal_instance = create_terminal_instance()

然后在myapp.py里直接导入使用:

# myapp.py
from hardware_setup import terminal_instance

@fastapi.get("/status")
async def get_hardware_status():
    return terminal_instance.status()

额外提示:异步初始化的情况

如果你的硬件初始化是异步操作(比如需要异步连接设备),可以用FastAPI的lifespan事件来处理:

# myapp.py
async def lifespan(app: FastAPI):
    # 应用启动前异步初始化硬件
    app.state.terminal = await create_terminal_async()
    yield
    # 应用关闭时异步清理资源
    await app.state.terminal.disconnect()

fastapi = FastAPI(lifespan=lifespan)

总结一下,优先选方案一或方案二,这两种都是FastAPI官方推荐的做法,既优雅又便于维护。

备注:内容来源于stack exchange,提问作者Henry

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.22 07:17:57