diff --git a/src/logic/databaseNew/Crud.py b/src/logic/databaseNew/Crud.py index 21cab087d034ea9ce97d0c777a5390a368d2d86e..4fbe5037785d9b910cb4d10d032905d0aa75099a 100644 --- a/src/logic/databaseNew/Crud.py +++ b/src/logic/databaseNew/Crud.py @@ -3,6 +3,9 @@ from sqlalchemy.orm import Session from logic.databaseNew import Models, Schemas +# ===== devices ===== + + def get_devices(db: Session, skip: int = 0, limit: int = 100): return db.query(Models.Device).offset(skip).limit(limit).all() @@ -28,13 +31,29 @@ def delete_device(db: Session, device: Schemas.Device): db.commit() +# ===== sensors ===== + def get_sensors(db: Session, skip: int = 0, limit: int = 100): return db.query(Models.Sensor).offset(skip).limit(limit).all() -def create_sensor(db: Session, item: Schemas.SensorCreate, deviceId: int): - dbSensor = Models.Sensor(**item.dict(), deviceId=deviceId) +def get_sensor(db: Session, sensorId: int): + return db.query(Models.Sensor).filter(Models.Sensor.id == sensorId).first() + + +def get_sensor_by_name_and_device_id(db: Session, sensorName: str, deviceId: int): + return db.query(Models.Sensor).filter( + Models.Sensor.name == sensorName and Models.Sensor.deviceId == deviceId).first() + + +def create_sensor(db: Session, sensor: Schemas.SensorCreate): + dbSensor = Models.Sensor(**sensor.dict()) db.add(dbSensor) db.commit() db.refresh(dbSensor) return dbSensor + + +def delete_sensor(db: Session, sensor: Schemas.Sensor): + db.delete(sensor) + db.commit() diff --git a/src/logic/databaseNew/Models.py b/src/logic/databaseNew/Models.py index f8fc1ea8cc8778d4a49e31848f89890c15b33e1b..8d73068c2c0459e2c0ab9ab4147ff13c9ee0ad1f 100644 --- a/src/logic/databaseNew/Models.py +++ b/src/logic/databaseNew/Models.py @@ -10,7 +10,7 @@ class Device(Base): id = Column(Integer, primary_key=True, index=True) name = Column(String, unique=True, index=True, nullable=False) - sensors = relationship('Sensor', back_populates='device') + sensors = relationship('Sensor', back_populates='device', cascade='all,delete') class Sensor(Base): diff --git a/src/logic/databaseNew/Schemas.py b/src/logic/databaseNew/Schemas.py index c82d577bbefcdf47cb099b73e50edef5cc3ec9a2..7d1594349abcf11c183aa748abc86c732386ac23 100644 --- a/src/logic/databaseNew/Schemas.py +++ b/src/logic/databaseNew/Schemas.py @@ -7,15 +7,20 @@ class Status(BaseModel): message: str +# ===== sensor ===== class SensorBase(BaseModel): id: int name: str type: str + class Config: + orm_mode = True + class SensorCreate(BaseModel): name: str type: str + deviceId: int class Sensor(BaseModel): @@ -28,6 +33,7 @@ class Sensor(BaseModel): orm_mode = True +# ===== device ===== class DeviceBase(BaseModel): id: int name: str diff --git a/src/main.py b/src/main.py index 5fcb30b491d763f6970d5225c6a5c0c897308836..39099cfea74f63e09b337a6e412ab1997d4165dc 100644 --- a/src/main.py +++ b/src/main.py @@ -9,7 +9,7 @@ from Settings import SETTINGS from logic import Constants from logic.databaseNew import Models from logic.databaseNew.Database import engine -from routers import DeviceRouter +from routers import DeviceRouter, SensorRouter LOGGER = DefaultLogger().create_logger_if_not_exists(Constants.APP_NAME) @@ -24,6 +24,7 @@ app = FastAPI(title=Constants.APP_NAME, description='The StorageLeaf API', servers=[{'url': SETTINGS['api']['url'], 'description': f'{Constants.APP_NAME} API'}]) app.include_router(DeviceRouter.router) +app.include_router(SensorRouter.router) @app.get('/') diff --git a/src/routers/DeviceRouter.py b/src/routers/DeviceRouter.py index 9471e500aa236baab00c50d6eab512cff0f1e783..29b0d412c0a3312bece4fb1f9e5d41c96c9dc98b 100644 --- a/src/routers/DeviceRouter.py +++ b/src/routers/DeviceRouter.py @@ -9,8 +9,7 @@ from logic.databaseNew.Schemas import Status router = APIRouter( prefix='/device', - tags=['device'], - responses={404: {'description': 'Not found'}}, + tags=['device'] ) @@ -42,7 +41,8 @@ async def create_device(device: Schemas.DeviceCreate, db: Session = Depends(get_ @router.delete('/{deviceId}', response_model=Status, - summary='Gets a specific device', + summary='Deletes a specific device', + description='All corresponding sensors and measurements will be deleted too.', responses={404: {'description': 'Device not found'}}, dependencies=[Depends(check_api_key)]) async def delete_device(deviceId: int, db: Session = Depends(get_database)): diff --git a/src/routers/SensorRouter.py b/src/routers/SensorRouter.py new file mode 100644 index 0000000000000000000000000000000000000000..0ba15e2b0b5e0c74079349a76bac458ba4953dd9 --- /dev/null +++ b/src/routers/SensorRouter.py @@ -0,0 +1,63 @@ +from typing import List + +from fastapi import APIRouter, HTTPException, Depends +from sqlalchemy.orm import Session + +from Dependencies import get_database, check_api_key +from logic.databaseNew import Schemas, Crud +from logic.databaseNew.Schemas import Status + +router = APIRouter( + prefix='/sensor', + tags=['sensor'] +) + + +@router.get('/', response_model=List[Schemas.Sensor], + summary='Gets all sensors') +async def read_sensors(skip: int = 0, limit: int = 100, db: Session = Depends(get_database)): + return Crud.get_sensors(db, skip=skip, limit=limit) + + +@router.get('/{sensorId}', response_model=Schemas.Sensor, + summary='Gets a specific sensor', + responses={404: {'description': 'Sensor not found'}}) +async def read_sensor(sensorId: int, db: Session = Depends(get_database)): + sensor = Crud.get_sensor(db, sensorId=sensorId) + if sensor is None: + raise HTTPException(status_code=404, detail='Sensor not found') + return sensor + + +@router.post('/', response_model=Schemas.Sensor, + summary='Adds a new sensor', + responses={400: {'description': 'A sensor called "{sensor.name}" already exists ' + '(ID: {existingSensor.id}) for device {sensor.deviceId}'}, + 404: {'description': 'No device with id "{sensor.deviceId}" existing'}}, + dependencies=[Depends(check_api_key)]) +async def create_sensor(sensor: Schemas.SensorCreate, db: Session = Depends(get_database)): + existingDevice = Crud.get_device(db, sensor.deviceId) + if not existingDevice: + raise HTTPException(status_code=404, detail=f'No device with id "{sensor.deviceId}" existing') + + existingSensor = Crud.get_sensor_by_name_and_device_id(db, sensor.name, sensor.deviceId) + if existingSensor: + raise HTTPException(status_code=400, + detail=f'A sensor called "{sensor.name}" already exists ' + f'(ID: {existingSensor.id}) for device {sensor.deviceId}') + + return Crud.create_sensor(db=db, sensor=sensor) + + +@router.delete('/{sensorId}', response_model=Status, + summary='Deletes a specific sensor', + description='All corresponding measurements will be deleted too.', + responses={404: {'description': 'Sensor not found'}}, + dependencies=[Depends(check_api_key)]) +async def delete_sensor(sensorId: int, db: Session = Depends(get_database)): + sensor = Crud.get_sensor(db, sensorId=sensorId) + if sensor is None: + raise HTTPException(status_code=404, detail='Sensor not found') + + Crud.delete_sensor(db, sensor) + return Status(message=f'Deleted sensor {sensor.id}')