harden delivery pipeline and production runtime
This commit is contained in:
1
backend/__init__.py
Normal file
1
backend/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
"""Secondary application entry points for SillyHome Next."""
|
||||
@@ -1,4 +1,8 @@
|
||||
from collections.abc import AsyncIterator
|
||||
from contextlib import asynccontextmanager
|
||||
|
||||
from fastapi import FastAPI
|
||||
from starlette.datastructures import State
|
||||
|
||||
from backend.routes.ml import init_ml_routes
|
||||
from app.ml.registry.model_registry import ModelRegistry
|
||||
@@ -6,14 +10,20 @@ from app.ml.training import TrainingPipeline
|
||||
from app.ml.feature_store import FeatureStore, FeatureVector
|
||||
|
||||
|
||||
def create_app() -> FastAPI:
|
||||
application = FastAPI(title="SillyHome Next ML")
|
||||
init_ml_routes(application)
|
||||
@asynccontextmanager
|
||||
async def lifespan(application: FastAPI) -> AsyncIterator[None]:
|
||||
application.state.registry = ModelRegistry(application.state.model_store)
|
||||
_seed_default_model(application.state)
|
||||
yield
|
||||
|
||||
|
||||
def create_app() -> FastAPI:
|
||||
application = FastAPI(title="SillyHome Next ML", lifespan=lifespan)
|
||||
init_ml_routes(application)
|
||||
return application
|
||||
|
||||
|
||||
def _seed_default_model(state) -> None: # noqa: ANN001
|
||||
def _seed_default_model(state: State) -> None:
|
||||
registry = getattr(state, "registry", None)
|
||||
if registry is None:
|
||||
registry = ModelRegistry(".model_store")
|
||||
|
||||
1
backend/routes/__init__.py
Normal file
1
backend/routes/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
"""API route modules."""
|
||||
@@ -2,7 +2,7 @@ from __future__ import annotations
|
||||
|
||||
import logging
|
||||
from datetime import datetime, timezone
|
||||
from typing import List, Sequence
|
||||
from collections.abc import Sequence
|
||||
|
||||
from fastapi import APIRouter, FastAPI, HTTPException, Request, status
|
||||
from pydantic import BaseModel, Field
|
||||
@@ -24,7 +24,7 @@ class HealthResponse(BaseModel):
|
||||
class PredictRequest(BaseModel):
|
||||
model_id: str = Field(..., alias="modelId")
|
||||
sensor_id: str
|
||||
values: dict
|
||||
values: dict[str, float]
|
||||
|
||||
|
||||
class PredictResponse(BaseModel):
|
||||
@@ -42,7 +42,7 @@ class BatchResponse(BaseModel):
|
||||
|
||||
|
||||
class ModelsResponse(BaseModel):
|
||||
models: List[str]
|
||||
models: list[str]
|
||||
|
||||
|
||||
@router.get("/health", response_model=HealthResponse, status_code=200)
|
||||
@@ -82,7 +82,7 @@ def predict(payload: PredictRequest, request: Request) -> PredictResponse:
|
||||
def predict_batch(payload: BatchRequest, request: Request) -> BatchResponse:
|
||||
registry = _require_registry(request)
|
||||
predictor = Predictor(registry=registry)
|
||||
responses: List[PredictResponse] = []
|
||||
responses: list[PredictResponse] = []
|
||||
for item in payload.requests:
|
||||
vector = FeatureVector(sensor_id=item.sensor_id, values=item.values)
|
||||
try:
|
||||
@@ -111,7 +111,6 @@ def _require_registry(request: Request) -> ModelRegistry:
|
||||
|
||||
|
||||
def init_ml_routes(app: FastAPI, model_store: str = ".model_store") -> None:
|
||||
registry = ModelRegistry(model_store)
|
||||
app.state.registry = registry
|
||||
app.state.model_store = model_store
|
||||
app.include_router(router)
|
||||
logger.info("ML routes registered")
|
||||
|
||||
Reference in New Issue
Block a user