feat: add API endpoint to get devices list
This commit is contained in:
parent
0cb5706ed7
commit
f4b7daabd3
9 changed files with 66 additions and 1 deletions
10
server/backend/adapters/http/_devices_schemas.py
Normal file
10
server/backend/adapters/http/_devices_schemas.py
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
from pydantic import BaseModel
|
||||||
|
|
||||||
|
from domain.entities import Device
|
||||||
|
|
||||||
|
class DeviceResponseSchema(BaseModel):
|
||||||
|
device_eui: str
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_domain(cls, device: Device) -> "DeviceResponseSchema":
|
||||||
|
return cls(device_eui=device.device_eui)
|
||||||
12
server/backend/adapters/http/devices.py
Normal file
12
server/backend/adapters/http/devices.py
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
from fastapi import APIRouter, Depends
|
||||||
|
|
||||||
|
from services.devices_service import DeviceService
|
||||||
|
from dependencies import get_device_service
|
||||||
|
from ._devices_schemas import DeviceResponseSchema
|
||||||
|
|
||||||
|
devices_router = APIRouter(prefix="/devices", tags=["devices"])
|
||||||
|
|
||||||
|
|
||||||
|
@devices_router.get("", response_model=list[DeviceResponseSchema])
|
||||||
|
def list_devices(service: DeviceService = Depends(get_device_service)):
|
||||||
|
return [DeviceResponseSchema.from_domain(d) for d in service.get_all_devices()]
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
from fastapi import FastAPI
|
from fastapi import FastAPI
|
||||||
from fastapi.middleware.cors import CORSMiddleware
|
from fastapi.middleware.cors import CORSMiddleware
|
||||||
from .readings import readings_router
|
from .readings import readings_router
|
||||||
|
from .devices import devices_router
|
||||||
|
|
||||||
app = FastAPI(title="SimuGazAPI", version="1.0.0")
|
app = FastAPI(title="SimuGazAPI", version="1.0.0")
|
||||||
|
|
||||||
|
|
@ -12,6 +13,7 @@ app.add_middleware(
|
||||||
)
|
)
|
||||||
|
|
||||||
app.include_router(readings_router)
|
app.include_router(readings_router)
|
||||||
|
app.include_router(devices_router)
|
||||||
|
|
||||||
@app.get("/health")
|
@app.get("/health")
|
||||||
def health():
|
def health():
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import psycopg2
|
||||||
from ports import DeviceRepository
|
from ports import DeviceRepository
|
||||||
from domain.exceptions import DatabaseError
|
from domain.exceptions import DatabaseError
|
||||||
from infrastructure.db import get_conn
|
from infrastructure.db import get_conn
|
||||||
|
from domain.entities import Device
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
@ -28,3 +29,15 @@ class PgDeviceRepository(DeviceRepository):
|
||||||
return str(cur.fetchone()[0]) # type: ignore
|
return str(cur.fetchone()[0]) # type: ignore
|
||||||
except psycopg2.DatabaseError as e:
|
except psycopg2.DatabaseError as e:
|
||||||
raise DatabaseError(f"Erreur de création du device {dev_eui}") from e
|
raise DatabaseError(f"Erreur de création du device {dev_eui}") from e
|
||||||
|
|
||||||
|
def get_all(self) -> list[Device]:
|
||||||
|
query = "SELECT device_id, device_eui FROM device ORDER BY device_eui ASC"
|
||||||
|
try:
|
||||||
|
with get_conn() as conn:
|
||||||
|
with conn.cursor() as cur:
|
||||||
|
cur.execute(query)
|
||||||
|
rows = cur.fetchall()
|
||||||
|
except psycopg2.DatabaseError as e:
|
||||||
|
raise DatabaseError(f"Erreur d'accès aux devices : {e}") from e
|
||||||
|
|
||||||
|
return [Device(device_id=r[0], device_eui=r[1]) for r in rows]
|
||||||
|
|
@ -4,6 +4,7 @@ from adapters.postgres import PgDeviceRepository, PgReadingRepository, PgReading
|
||||||
from adapters.mqtt import PahoMqttBroker
|
from adapters.mqtt import PahoMqttBroker
|
||||||
from services.uplink_service import UplinkService
|
from services.uplink_service import UplinkService
|
||||||
from services.consumption_service import ConsumptionService
|
from services.consumption_service import ConsumptionService
|
||||||
|
from services.devices_service import DeviceService
|
||||||
|
|
||||||
MQTT_HOST = os.getenv("MQTT_HOST", "mosquitto")
|
MQTT_HOST = os.getenv("MQTT_HOST", "mosquitto")
|
||||||
MQTT_PORT = int(os.getenv("MQTT_PORT", 1883))
|
MQTT_PORT = int(os.getenv("MQTT_PORT", 1883))
|
||||||
|
|
@ -28,6 +29,9 @@ def get_uplink_service() -> UplinkService:
|
||||||
def get_consumption_service() -> ConsumptionService:
|
def get_consumption_service() -> ConsumptionService:
|
||||||
return ConsumptionService(get_query_repo())
|
return ConsumptionService(get_query_repo())
|
||||||
|
|
||||||
|
def get_device_service() -> DeviceService:
|
||||||
|
return DeviceService(get_device_repo())
|
||||||
|
|
||||||
|
|
||||||
## Adapters
|
## Adapters
|
||||||
def get_mqtt_broker() -> PahoMqttBroker:
|
def get_mqtt_broker() -> PahoMqttBroker:
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
from .uplink_event import UplinkEvent
|
from .uplink_event import UplinkEvent
|
||||||
from .consumption_point import ConsumptionPoint, ConsumptionResponse
|
from .consumption_point import ConsumptionPoint, ConsumptionResponse
|
||||||
|
from .device import Device
|
||||||
|
|
||||||
__all__ = ["UplinkEvent", "ConsumptionPoint", "ConsumptionResponse"]
|
__all__ = ["UplinkEvent", "ConsumptionPoint", "ConsumptionResponse", "Device"]
|
||||||
6
server/backend/domain/entities/device.py
Normal file
6
server/backend/domain/entities/device.py
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
from dataclasses import dataclass
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class Device:
|
||||||
|
device_id: int
|
||||||
|
device_eui: str
|
||||||
|
|
@ -1,7 +1,14 @@
|
||||||
from abc import ABC, abstractmethod
|
from abc import ABC, abstractmethod
|
||||||
|
|
||||||
|
from domain.entities import Device
|
||||||
|
|
||||||
class DeviceRepository(ABC):
|
class DeviceRepository(ABC):
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def get_or_create_device_id(self, dev_eui: str) -> str:
|
def get_or_create_device_id(self, dev_eui: str) -> str:
|
||||||
"""Retourne le device_id, crée le device s'il est inconnu"""
|
"""Retourne le device_id, crée le device s'il est inconnu"""
|
||||||
|
...
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def get_all(self) -> list[Device]:
|
||||||
|
"""Retourne l'ensemble des devices existants"""
|
||||||
...
|
...
|
||||||
10
server/backend/services/devices_service.py
Normal file
10
server/backend/services/devices_service.py
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
from domain.entities import Device
|
||||||
|
from adapters.postgres.device_repository import DeviceRepository
|
||||||
|
|
||||||
|
|
||||||
|
class DeviceService:
|
||||||
|
def __init__(self, device_repo: DeviceRepository) -> None:
|
||||||
|
self._device_repo = device_repo
|
||||||
|
|
||||||
|
def get_all_devices(self) -> list[Device]:
|
||||||
|
return self._device_repo.get_all()
|
||||||
Loading…
Add table
Add a link
Reference in a new issue