Refactor puck event handling and add tell
filtering
Updated puck event queries to improve robustness and ensure distinct results. Introduced filtering by `tell` in specific API endpoints and added validation for `tell` values. Incremented project version to 0.1.0a21 to reflect API changes.
This commit is contained in:
parent
780ba1959f
commit
9e5ae2b43c
@ -145,6 +145,7 @@ def get_pucks_at_beamline(slot_id: int, db: Session) -> List[PuckWithTellPositio
|
|||||||
PuckModel,
|
PuckModel,
|
||||||
PuckEventModel.event_type,
|
PuckEventModel.event_type,
|
||||||
PuckEventModel.tell_position,
|
PuckEventModel.tell_position,
|
||||||
|
PuckEventModel.timestamp, # Useful for debugging or edge cases
|
||||||
DewarModel,
|
DewarModel,
|
||||||
)
|
)
|
||||||
.join(
|
.join(
|
||||||
@ -163,36 +164,41 @@ def get_pucks_at_beamline(slot_id: int, db: Session) -> List[PuckWithTellPositio
|
|||||||
)
|
)
|
||||||
.join(DewarModel, PuckModel.dewar_id == DewarModel.id, isouter=True)
|
.join(DewarModel, PuckModel.dewar_id == DewarModel.id, isouter=True)
|
||||||
.filter(PuckModel.dewar_id.in_(dewar_ids))
|
.filter(PuckModel.dewar_id.in_(dewar_ids))
|
||||||
|
.distinct() # Ensure no duplicates
|
||||||
.all()
|
.all()
|
||||||
)
|
)
|
||||||
|
|
||||||
# Prepare the results
|
# Prepare the results
|
||||||
results = []
|
results = {}
|
||||||
for puck, event_type, tell_position, dewar in pucks_with_latest_events:
|
for (
|
||||||
dewar_name = dewar_map.get(puck.dewar_id, "Unknown")
|
puck,
|
||||||
|
event_type,
|
||||||
|
tell_position,
|
||||||
|
event_timestamp,
|
||||||
|
dewar,
|
||||||
|
) in pucks_with_latest_events:
|
||||||
|
dewar_name = dewar_map.get(puck.dewar_id)
|
||||||
pgroup = dewar_pgroups.get(puck.dewar_id)
|
pgroup = dewar_pgroups.get(puck.dewar_id)
|
||||||
|
|
||||||
# For pucks with no events or whose latest event is "puck_removed", set
|
# If the event is None or explicitly a "puck_removed", set `tell_position=None`
|
||||||
# tell_position to None
|
|
||||||
if event_type is None or event_type == "puck_removed":
|
if event_type is None or event_type == "puck_removed":
|
||||||
tell_position = None
|
tell_position = None
|
||||||
|
|
||||||
results.append(
|
# Always replace results since we are processing the latest event
|
||||||
PuckWithTellPosition(
|
results[puck.id] = PuckWithTellPosition(
|
||||||
id=puck.id,
|
id=puck.id,
|
||||||
pgroup=pgroup,
|
pgroup=pgroup,
|
||||||
puck_name=puck.puck_name,
|
puck_name=puck.puck_name,
|
||||||
puck_type=puck.puck_type,
|
puck_type=puck.puck_type,
|
||||||
puck_location_in_dewar=int(puck.puck_location_in_dewar)
|
puck_location_in_dewar=int(puck.puck_location_in_dewar)
|
||||||
if puck.puck_location_in_dewar
|
if puck.puck_location_in_dewar
|
||||||
else None,
|
else None,
|
||||||
dewar_id=puck.dewar_id,
|
dewar_id=puck.dewar_id,
|
||||||
dewar_name=dewar_name,
|
dewar_name=dewar_name,
|
||||||
tell_position=tell_position,
|
tell_position=tell_position, # Respect if `None` is explicitly set
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
return results
|
return list(results.values())
|
||||||
|
|
||||||
|
|
||||||
@router.get("/", response_model=List[PuckSchema])
|
@router.get("/", response_model=List[PuckSchema])
|
||||||
@ -269,7 +275,7 @@ async def set_tell_positions(
|
|||||||
tell=None, # Nullify the `tell` for removal
|
tell=None, # Nullify the `tell` for removal
|
||||||
tell_position=None,
|
tell_position=None,
|
||||||
event_type="puck_removed",
|
event_type="puck_removed",
|
||||||
timestamp=datetime.utcnow(),
|
timestamp=datetime.now(),
|
||||||
)
|
)
|
||||||
db.add(remove_event)
|
db.add(remove_event)
|
||||||
|
|
||||||
@ -309,9 +315,8 @@ async def set_tell_positions(
|
|||||||
puck.id: db.query(PuckEventModel)
|
puck.id: db.query(PuckEventModel)
|
||||||
.filter(
|
.filter(
|
||||||
PuckEventModel.puck_id == puck.id,
|
PuckEventModel.puck_id == puck.id,
|
||||||
PuckEventModel.event_type == "tell_position_set",
|
|
||||||
)
|
)
|
||||||
.order_by(PuckEventModel.timestamp.desc())
|
.order_by(PuckEventModel.id.desc())
|
||||||
.first()
|
.first()
|
||||||
for puck in pucks_at_beamline
|
for puck in pucks_at_beamline
|
||||||
}
|
}
|
||||||
@ -358,7 +363,7 @@ async def set_tell_positions(
|
|||||||
tell=None,
|
tell=None,
|
||||||
tell_position=None,
|
tell_position=None,
|
||||||
event_type="puck_removed",
|
event_type="puck_removed",
|
||||||
timestamp=datetime.utcnow(),
|
timestamp=datetime.now(),
|
||||||
)
|
)
|
||||||
db.add(remove_event)
|
db.add(remove_event)
|
||||||
|
|
||||||
@ -368,7 +373,7 @@ async def set_tell_positions(
|
|||||||
tell=tell,
|
tell=tell,
|
||||||
tell_position=new_position,
|
tell_position=new_position,
|
||||||
event_type="tell_position_set",
|
event_type="tell_position_set",
|
||||||
timestamp=datetime.utcnow(),
|
timestamp=datetime.now(),
|
||||||
)
|
)
|
||||||
db.add(new_event)
|
db.add(new_event)
|
||||||
|
|
||||||
@ -409,7 +414,7 @@ async def set_tell_positions(
|
|||||||
tell=None,
|
tell=None,
|
||||||
tell_position=None,
|
tell_position=None,
|
||||||
event_type="puck_removed",
|
event_type="puck_removed",
|
||||||
timestamp=datetime.utcnow(),
|
timestamp=datetime.now(),
|
||||||
)
|
)
|
||||||
db.add(remove_event)
|
db.add(remove_event)
|
||||||
results.append(
|
results.append(
|
||||||
@ -436,13 +441,23 @@ async def set_tell_positions(
|
|||||||
|
|
||||||
|
|
||||||
@router.get("/with-tell-position", response_model=List[PuckWithTellPosition])
|
@router.get("/with-tell-position", response_model=List[PuckWithTellPosition])
|
||||||
async def get_pucks_with_tell_position(db: Session = Depends(get_db)):
|
async def get_pucks_with_tell_position(
|
||||||
|
tell: str, # Specify tell as a query parameter
|
||||||
|
db: Session = Depends(get_db),
|
||||||
|
):
|
||||||
"""
|
"""
|
||||||
Retrieve all pucks with a valid `tell_position` set (non-null),
|
Retrieve all pucks with a valid `tell_position` set (non-null),
|
||||||
their associated samples, and the latest `tell_position` value (if any).
|
their associated samples, and the latest `tell_position` value (if any),
|
||||||
Only include pucks when their latest event has a `tell_position`
|
filtered by a specific `tell`.
|
||||||
set and an `event_type` matching "tell_position_set".
|
|
||||||
"""
|
"""
|
||||||
|
# Validate the incoming `tell` value
|
||||||
|
try:
|
||||||
|
validate_tell(tell) # Ensure `tell` is valid using predefined valid options
|
||||||
|
except ValueError as error:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=400, detail=str(error)
|
||||||
|
) # Raise error for invalid tells
|
||||||
|
|
||||||
# Step 1: Prepare a subquery to fetch the latest event timestamp for each puck.
|
# Step 1: Prepare a subquery to fetch the latest event timestamp for each puck.
|
||||||
latest_event_subquery = (
|
latest_event_subquery = (
|
||||||
db.query(
|
db.query(
|
||||||
@ -471,6 +486,7 @@ async def get_pucks_with_tell_position(db: Session = Depends(get_db)):
|
|||||||
.filter(
|
.filter(
|
||||||
PuckEventModel.event_type == "tell_position_set"
|
PuckEventModel.event_type == "tell_position_set"
|
||||||
) # Only include relevant event types
|
) # Only include relevant event types
|
||||||
|
.filter(PuckEventModel.tell == tell) # Filter by the specific `tell` variable
|
||||||
.all()
|
.all()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|||||||
|
|
||||||
[project]
|
[project]
|
||||||
name = "aareDB"
|
name = "aareDB"
|
||||||
version = "0.1.0a20"
|
version = "0.1.0a21"
|
||||||
description = "Backend for next gen sample management system"
|
description = "Backend for next gen sample management system"
|
||||||
authors = [{name = "Guillaume Gotthard", email = "guillaume.gotthard@psi.ch"}]
|
authors = [{name = "Guillaume Gotthard", email = "guillaume.gotthard@psi.ch"}]
|
||||||
license = {text = "MIT"}
|
license = {text = "MIT"}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user