python-3.x - 如何将额外数据传递给 fastapi APIRouter?
问题描述
这是我的第一个 fastapi 练习。我用 Flask 实现了我的旧模型服务代码,如下所示:
class HealthCheck(Resource):
def __init__(self, **kwargs):
super(HealthCheck, self).__init__()
self._model = kwargs['model']
self._logger = kwargs['logger']
def get(self):
if self._model:
return {"status" : "healthy"}, HTTPStatus.OK
return {"status": "unavailable"}, HTTPStatus.BAD_REQUEST
def put(self):
raise MethodNotAllowed('PUT request not supported')
# similarly other methods are disabled
# In a different module, say in App class
class App():
def __init__(self, name, logger, config):
self._logger = logger
self._model = load_model(config['model_path'])
self._flask_app = Flask(name)
api = Api(self._flask_app)
# logger and model is passed to HealthCheck resource
api.add_resource(HealthCheck, "/api/healthcheck",
resource_class_kwargs={'model': self._model, 'logger': self._logger})
如何使用 fastapi APIRouter 实现相同的目标?我的示例 fastapi 实现如下:
class HealthResult(BaseModel):
healthy: bool
health_router = fastapi.APIRouter()
@health_router.get("/healthcheck", response_model=HealthResult, name="heathcheck")
async def heartbeat() -> HealthResult:
hb = HealthResult(healthy=True)
return hb
# in the App module
class App():
def __init__(self, name, logger, config):
self._logger = logger
self._model = load_model(config['model_path'])
self._api = fastapi.FastAPI(title=name)
self._api.include_router(health_router, prefix="/api")
# how do I pass model and logger to health_router to use that in heartbeat method?
我想避免对模型和记录器使用任何全局存储,并从那里访问 health_router。
另外,由于我的 fastapi 对象在 App 类中,在这种情况下如何使用 uvicorn 调用多个工作人员?
解决方案
虽然我不喜欢它,但我修改了我的App
课程以解决这个问题 - 仍在寻找更清洁的解决方案。
class App(metaclass=Singleton):
_MODEL: Union[None, Model] = None
_LOGGER: Union[None, CustomLogger] = None
@classmethod
def setLogger(cls, logger: CustomLogger) -> None:
cls._LOGGER = logger
@classmethod
def getLogger(cls) -> CustomLogger:
return cls._LOGGER
@classmethod
def setModel(cls, model: Model) -> None:
assert model
cls._MODEL = model
@classmethod
def getModel(cls) -> Model:
return cls._MODEL
def __init__(self, name: str, logger: CustomLogger, config: YAML) -> None:
App.setLogger(logger)
model: Model = load_model(config['model_path'])
App.setModel(model)
self._api = fastapi.FastAPI(title=name)
self._api.include_router(health_router, prefix="/api")
....
class HealthResult(BaseModel):
healthy: bool
health_router = fastapi.APIRouter()
@health_router.get("/healthcheck", response_model=HealthResult, name="heathcheck")
async def heartbeat() -> HealthResult:
model: Model = App.getModel()
hb: HealthResult = HealthResult(healthy=True) if model else HealthResult(healthy=False)
return hb
推荐阅读
- python - 使用python将逗号分隔值到Dict
- javascript - 将存储在数组中的文件附加到 HTML 文件输入 [jQuery]
- typescript - Typescript 将模板字符串编译为 es5,即使 tsconfig 目标设置为 ESNEXT
- c++ - 升级 Visual Studio 后 Bazel 不再工作
- google-apps-script - Google 脚本中的 Onchange 更改表数据
- java - 如何软删除表 A 中的记录,以及其他 3 个表中的所有引用
- r - 我试图在显示 HH:MM:SS 的值中取出秒数
- angular - 如何对 div (Cypress) 的输入进行 e2e 测试?
- android - 从 url 方案启动 Android 应用程序非常慢
- django - 是否可以从从另一个模型派生的列表列表中创建多个模型实例?