fixing bugs with ci pipeline
This commit is contained in:
@ -1,4 +1,8 @@
|
||||
import os, tempfile, time, random, hashlib
|
||||
import os
|
||||
import tempfile
|
||||
import time
|
||||
import random
|
||||
import hashlib
|
||||
from fastapi import APIRouter, HTTPException, status, Depends, Response
|
||||
from sqlalchemy.orm import Session, joinedload
|
||||
from typing import List
|
||||
@ -21,14 +25,12 @@ from app.models import (
|
||||
Sample as SampleModel,
|
||||
DewarType as DewarTypeModel,
|
||||
DewarSerialNumber as DewarSerialNumberModel,
|
||||
Shipment as ShipmentModel, # Clearer name for model
|
||||
)
|
||||
from app.dependencies import get_db
|
||||
import uuid
|
||||
import qrcode
|
||||
import io
|
||||
from io import BytesIO
|
||||
from PIL import ImageFont, ImageDraw, Image
|
||||
from PIL import Image
|
||||
from reportlab.lib.pagesizes import A5, landscape
|
||||
from reportlab.lib.units import cm
|
||||
from reportlab.pdfgen import canvas
|
||||
@ -211,7 +213,7 @@ def generate_label(dewar):
|
||||
c.drawString(2 * cm, y_position, f"Country: {return_address.country}")
|
||||
y_position -= line_height
|
||||
|
||||
c.drawString(2 * cm, y_position, f"Beamtime Information: Placeholder")
|
||||
c.drawString(2 * cm, y_position, "Beamtime Information: Placeholder")
|
||||
|
||||
# Generate QR code
|
||||
qr = qrcode.QRCode(version=1, box_size=10, border=4)
|
||||
|
@ -34,7 +34,8 @@ def calculate_time_until_refill(
|
||||
@router.post("/dewars/return", response_model=DewarSchema)
|
||||
async def return_to_storage(data: LogisticsEventCreate, db: Session = Depends(get_db)):
|
||||
logger.info(
|
||||
f"Returning dewar to storage: {data.dewar_qr_code} at location {data.location_qr_code}"
|
||||
f"Returning dewar to storage: {data.dewar_qr_code}"
|
||||
f"at location {data.location_qr_code}"
|
||||
)
|
||||
|
||||
try:
|
||||
@ -57,11 +58,13 @@ async def return_to_storage(data: LogisticsEventCreate, db: Session = Depends(ge
|
||||
)
|
||||
if original_slot and original_slot.qr_code != data.location_qr_code:
|
||||
logger.error(
|
||||
f"Dewar {data.dewar_qr_code} is associated with slot {original_slot.qr_code}"
|
||||
f"Dewar {data.dewar_qr_code} is"
|
||||
f"associated with slot {original_slot.qr_code}"
|
||||
)
|
||||
raise HTTPException(
|
||||
status_code=400,
|
||||
detail=f"Dewar {data.dewar_qr_code} is associated with a different slot {original_slot.qr_code}.",
|
||||
detail=f"Dewar {data.dewar_qr_code} is associated"
|
||||
f"with a different slot {original_slot.qr_code}.",
|
||||
)
|
||||
|
||||
slot = (
|
||||
@ -87,12 +90,16 @@ async def return_to_storage(data: LogisticsEventCreate, db: Session = Depends(ge
|
||||
slot.occupied = True
|
||||
dewar.last_retrieved_timestamp = None
|
||||
|
||||
# Set the `at_beamline` attribute to False
|
||||
dewar.at_beamline = False
|
||||
|
||||
# Log the event
|
||||
log_event(db, dewar.id, slot.id, "returned")
|
||||
db.commit()
|
||||
|
||||
logger.info(
|
||||
f"Dewar {data.dewar_qr_code} successfully returned to storage slot {slot.qr_code}."
|
||||
f"Dewar {data.dewar_qr_code} successfully"
|
||||
f"returned to storage slot {slot.qr_code}."
|
||||
)
|
||||
db.refresh(dewar)
|
||||
return dewar
|
||||
@ -174,7 +181,8 @@ async def scan_dewar(event_data: LogisticsEventCreate, db: Session = Depends(get
|
||||
log_event(db, dewar.id, slot.id if slot else None, transaction_type)
|
||||
db.commit()
|
||||
logger.info(
|
||||
f"Transaction completed: {transaction_type} for dewar {dewar_qr_code} in slot {slot.qr_code if slot else 'N/A'}"
|
||||
f"Transaction completed: {transaction_type}"
|
||||
f"for dewar {dewar_qr_code} in slot {slot.qr_code if slot else 'N/A'}"
|
||||
)
|
||||
|
||||
return {"message": "Status updated successfully"}
|
||||
@ -191,7 +199,6 @@ async def get_all_slots(db: Session = Depends(get_db)):
|
||||
retrievedTimestamp = None
|
||||
beamlineLocation = None
|
||||
at_beamline = False
|
||||
retrieved = False
|
||||
|
||||
if slot.dewar_unique_id:
|
||||
# Calculate time until refill
|
||||
@ -212,32 +219,32 @@ async def get_all_slots(db: Session = Depends(get_db)):
|
||||
else:
|
||||
time_until_refill = -1
|
||||
|
||||
# Fetch the latest beamline event
|
||||
last_beamline_event = (
|
||||
# Fetch the latest event for the dewar
|
||||
last_event = (
|
||||
db.query(LogisticsEventModel)
|
||||
.join(DewarModel, DewarModel.id == LogisticsEventModel.dewar_id)
|
||||
.filter(
|
||||
DewarModel.unique_id == slot.dewar.unique_id,
|
||||
LogisticsEventModel.event_type == "beamline",
|
||||
)
|
||||
.filter(DewarModel.unique_id == slot.dewar.unique_id)
|
||||
.order_by(LogisticsEventModel.timestamp.desc())
|
||||
.first()
|
||||
)
|
||||
|
||||
if last_beamline_event:
|
||||
# Set retrievedTimestamp to the timestamp of the beamline event
|
||||
retrievedTimestamp = last_beamline_event.timestamp.isoformat()
|
||||
|
||||
# Fetch the associated slot's label for beamlineLocation
|
||||
associated_slot = (
|
||||
db.query(SlotModel)
|
||||
.filter(SlotModel.id == last_beamline_event.slot_id)
|
||||
.first()
|
||||
)
|
||||
beamlineLocation = associated_slot.label if associated_slot else None
|
||||
|
||||
# Mark as being at a beamline
|
||||
at_beamline = True
|
||||
# Determine if the dewar is at the beamline
|
||||
if last_event:
|
||||
if last_event.event_type == "beamline":
|
||||
at_beamline = True
|
||||
# Optionally set retrievedTimestamp and beamlineLocation for
|
||||
# beamline events
|
||||
retrievedTimestamp = last_event.timestamp.isoformat()
|
||||
associated_slot = (
|
||||
db.query(SlotModel)
|
||||
.filter(SlotModel.id == last_event.slot_id)
|
||||
.first()
|
||||
)
|
||||
beamlineLocation = (
|
||||
associated_slot.label if associated_slot else None
|
||||
)
|
||||
elif last_event.event_type == "returned":
|
||||
at_beamline = False
|
||||
|
||||
# Correct the contact_person assignment
|
||||
contact_person = None
|
||||
@ -296,7 +303,8 @@ async def refill_dewar(qr_code: str, db: Session = Depends(get_db)):
|
||||
|
||||
time_until_refill_seconds = calculate_time_until_refill(now)
|
||||
logger.info(
|
||||
f"Dewar refilled successfully with time_until_refill: {time_until_refill_seconds}"
|
||||
f"Dewar refilled successfully"
|
||||
f"with time_until_refill: {time_until_refill_seconds}"
|
||||
)
|
||||
|
||||
return {
|
||||
@ -334,5 +342,6 @@ def log_event(db: Session, dewar_id: int, slot_id: Optional[int], event_type: st
|
||||
db.add(new_event)
|
||||
db.commit()
|
||||
logger.info(
|
||||
f"Logged event: {event_type} for dewar: {dewar_id} in slot: {slot_id if slot_id else 'N/A'}"
|
||||
f"Logged event: {event_type} for dewar: {dewar_id} "
|
||||
f"in slot: {slot_id if slot_id else 'N/A'}"
|
||||
)
|
||||
|
@ -7,7 +7,6 @@ from app.schemas import (
|
||||
PuckCreate,
|
||||
PuckUpdate,
|
||||
SetTellPosition,
|
||||
PuckEvent,
|
||||
)
|
||||
from app.models import (
|
||||
Puck as PuckModel,
|
||||
@ -35,7 +34,8 @@ async def get_pucks(db: Session = Depends(get_db)):
|
||||
@router.get("/with-tell-position", response_model=List[dict])
|
||||
async def get_pucks_with_tell_position(db: Session = Depends(get_db)):
|
||||
"""
|
||||
Retrieve all pucks with a `tell_position` set (not null) and their associated samples.
|
||||
Retrieve all pucks with a `tell_position`
|
||||
set (not null) and their associated samples.
|
||||
"""
|
||||
# Query all pucks that have an event with a non-null tell_position
|
||||
pucks = (
|
||||
@ -157,8 +157,10 @@ async def set_tell_position(
|
||||
# Create a new PuckEvent (always a new event, even with null/None)
|
||||
new_puck_event = PuckEventModel(
|
||||
puck_id=puck_id,
|
||||
tell_position=actual_position, # Null for disassociation, else the valid position
|
||||
event_type="tell_position_set", # Example event type
|
||||
tell_position=actual_position,
|
||||
# Null for disassociation, else the valid position
|
||||
event_type="tell_position_set",
|
||||
# Example event type
|
||||
timestamp=datetime.utcnow(),
|
||||
)
|
||||
db.add(new_puck_event)
|
||||
@ -232,7 +234,9 @@ async def get_pucks_by_slot(slot_identifier: str, db: Session = Depends(get_db))
|
||||
if not slot_id:
|
||||
raise HTTPException(
|
||||
status_code=400,
|
||||
detail="Invalid slot identifier. Must be an ID or one of the following: PXI, PXII, PXIII, X06SA, X10SA, X06DA.",
|
||||
detail="Invalid slot identifier."
|
||||
"Must be an ID or one of the following:"
|
||||
"PXI, PXII, PXIII, X06SA, X10SA, X06DA.",
|
||||
)
|
||||
|
||||
# Verify that the slot exists
|
||||
|
@ -1,7 +1,7 @@
|
||||
from fastapi import APIRouter, HTTPException, status, Depends
|
||||
from fastapi import APIRouter, HTTPException, Depends
|
||||
from sqlalchemy.orm import Session
|
||||
from typing import List
|
||||
from app.schemas import Puck as PuckSchema, Sample as SampleSchema, SampleEventCreate
|
||||
from app.schemas import Puck as PuckSchema, Sample as SampleSchema
|
||||
from app.models import (
|
||||
Puck as PuckModel,
|
||||
Sample as SampleModel,
|
||||
|
@ -2,9 +2,10 @@ from fastapi import APIRouter, HTTPException, status, Query, Depends
|
||||
from sqlalchemy.orm import Session
|
||||
from typing import List, Optional
|
||||
import logging
|
||||
from pydantic import BaseModel, ValidationError
|
||||
from pydantic import ValidationError
|
||||
from datetime import date
|
||||
from sqlalchemy.exc import SQLAlchemyError
|
||||
import json
|
||||
|
||||
from app.models import (
|
||||
Shipment as ShipmentModel,
|
||||
@ -19,12 +20,9 @@ from app.schemas import (
|
||||
ShipmentCreate,
|
||||
UpdateShipmentComments,
|
||||
Shipment as ShipmentSchema,
|
||||
DewarUpdate,
|
||||
ContactPerson as ContactPersonSchema,
|
||||
Sample as SampleSchema,
|
||||
DewarCreate,
|
||||
PuckCreate,
|
||||
SampleCreate,
|
||||
DewarSchema,
|
||||
)
|
||||
from app.database import get_db
|
||||
@ -185,7 +183,8 @@ async def update_shipment(
|
||||
if not contact_person:
|
||||
raise HTTPException(
|
||||
status_code=404,
|
||||
detail=f"Contact person with ID {value} for Dewar {dewar_data.dewar_id} not found",
|
||||
detail=f"Contact person with ID {value}"
|
||||
f"for Dewar {dewar_data.dewar_id} not found",
|
||||
)
|
||||
if key == "return_address_id":
|
||||
address = (
|
||||
@ -194,7 +193,8 @@ async def update_shipment(
|
||||
if not address:
|
||||
raise HTTPException(
|
||||
status_code=404,
|
||||
detail=f"Address with ID {value} for Dewar {dewar_data.dewar_id} not found",
|
||||
detail=f"Address with ID {value}"
|
||||
f"for Dewar {dewar_data.dewar_id} not found",
|
||||
)
|
||||
|
||||
for key, value in update_fields.items():
|
||||
|
@ -51,9 +51,12 @@ async def upload_file(file: UploadFile = File(...)):
|
||||
)
|
||||
|
||||
# Initialize the importer and process the spreadsheet
|
||||
validated_model, errors, raw_data, headers = (
|
||||
importer.import_spreadsheet_with_errors(file)
|
||||
)
|
||||
(
|
||||
validated_model,
|
||||
errors,
|
||||
raw_data,
|
||||
headers,
|
||||
) = importer.import_spreadsheet_with_errors(file)
|
||||
|
||||
# Extract unique values for dewars, pucks, and samples
|
||||
dewars = {sample.dewarname for sample in validated_model if sample.dewarname}
|
||||
@ -82,7 +85,8 @@ async def upload_file(file: UploadFile = File(...)):
|
||||
row_storage.set_row(row_num, row.dict())
|
||||
|
||||
logger.info(
|
||||
f"Returning response with {len(validated_model)} records and {len(errors)} errors."
|
||||
f"Returning response with {len(validated_model)}"
|
||||
f"records and {len(errors)} errors."
|
||||
)
|
||||
return response_data
|
||||
|
||||
@ -121,7 +125,9 @@ async def validate_cell(data: dict):
|
||||
|
||||
try:
|
||||
# Ensure we're using the full row data context for validation
|
||||
validated_row = SpreadsheetModel(**current_row_data)
|
||||
SpreadsheetModel(
|
||||
**current_row_data
|
||||
) # Instantiates the Pydantic model, performing validation
|
||||
logger.info(f"Validation succeeded for row {row_num}, column {col_name}")
|
||||
return {"is_valid": True, "message": ""}
|
||||
except ValidationError as e:
|
||||
|
Reference in New Issue
Block a user