58 lines
1.9 KiB
Python
58 lines
1.9 KiB
Python
"""Contexte applicatif injecté dans les routers de features.
|
|
|
|
Patron évolutif : chaque feature expose `make_router(ctx) -> APIRouter` et reçoit ce
|
|
contexte (adb, store, bridge, autosync, identité opérateur) + les helpers transverses
|
|
(`guard` = mapping exceptions→HTTP, `now_ms`, `client`). Ajouter une feature = créer son
|
|
router et l'enregistrer dans `app.create_app` — sans toucher au reste.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import time
|
|
from dataclasses import dataclass
|
|
from typing import Any, Callable
|
|
|
|
from fastapi import HTTPException
|
|
|
|
from .adb import Adb, AdbError
|
|
from .provider import ProviderClient
|
|
from .store import Store, StoreLocked
|
|
|
|
VERSION = "0.1.0"
|
|
|
|
|
|
@dataclass
|
|
class Ctx:
|
|
adb: Adb
|
|
store: Store
|
|
bridge: Any # VoiceBridge (feature voices) — typé Any pour découpler core
|
|
autosync: Any # VoiceAutoSync
|
|
operator: str
|
|
|
|
@staticmethod
|
|
def now_ms() -> int:
|
|
return int(time.time() * 1000)
|
|
|
|
def client(self, serial: str) -> ProviderClient:
|
|
return ProviderClient(self.adb, serial)
|
|
|
|
def guard(self, fn: Callable):
|
|
"""Exécute `fn`, mappe les exceptions de domaine en HTTP. Les erreurs de
|
|
feature peuvent porter un attribut `http_status` (ex. VoiceWorkerError=503)
|
|
pour rester découplées du core."""
|
|
try:
|
|
return fn()
|
|
except HTTPException:
|
|
raise
|
|
except AdbError as e:
|
|
raise HTTPException(502, str(e)) from e
|
|
except StoreLocked as e:
|
|
raise HTTPException(423, str(e)) from e
|
|
except IndexError as e: # endpoint a renvoyé 0 ligne
|
|
raise HTTPException(404, "aucune donnée") from e
|
|
except Exception as e:
|
|
code = getattr(type(e), "http_status", None)
|
|
if code:
|
|
raise HTTPException(code, str(e)) from e
|
|
raise
|