harden delivery pipeline and production runtime
Some checks failed
quality / test (3.11) (push) Has been cancelled
quality / test (3.13) (push) Has been cancelled
quality / test (3.11) (pull_request) Has been cancelled
quality / test (3.13) (pull_request) Has been cancelled

This commit is contained in:
2026-06-11 21:14:07 +02:00
parent 471146761e
commit aaf319ff14
26 changed files with 202 additions and 73 deletions

1
backend/__init__.py Normal file
View File

@@ -0,0 +1 @@
"""Secondary application entry points for SillyHome Next."""

View File

@@ -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")

View File

@@ -0,0 +1 @@
"""API route modules."""

View File

@@ -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")