From 9739b8cfe9b094b98a513199b0105f37cba58da0 Mon Sep 17 00:00:00 2001 From: GotthardG <51994228+GotthardG@users.noreply.github.com> Date: Fri, 17 Jan 2025 09:36:16 +0100 Subject: [PATCH] Make shipment fields optional and refactor test scripts. Updated the `number_of_pucks` and `number_of_samples` fields in the `schemas.py` to be optional for greater flexibility. Simplified the test Jupyter Notebook by restructuring imports and consolidating function calls for better readability and maintainability. --- backend/app/routers/dewar.py | 147 ++++++-- backend/app/routers/shipment.py | 79 +---- backend/app/schemas.py | 4 +- frontend/src/components/ShipmentDetails.tsx | 2 +- frontend/src/components/SpreadsheetTable.tsx | 208 ++++++----- testfunctions.ipynb | 354 ++++++++++++++----- 6 files changed, 485 insertions(+), 309 deletions(-) diff --git a/backend/app/routers/dewar.py b/backend/app/routers/dewar.py index 15ab1ad..e3a7401 100644 --- a/backend/app/routers/dewar.py +++ b/backend/app/routers/dewar.py @@ -8,7 +8,6 @@ from sqlalchemy.orm import Session, joinedload from typing import List import logging from sqlalchemy.exc import SQLAlchemyError -from pydantic import ValidationError, BaseModel from app.schemas import ( Dewar as DewarSchema, DewarCreate, @@ -65,11 +64,114 @@ def generate_unique_id(db: Session, length: int = 16) -> str: @router.post("/", response_model=DewarSchema, status_code=status.HTTP_201_CREATED) -async def create_dewar( - dewar: DewarCreate, db: Session = Depends(get_db) +async def create_or_update_dewar( + shipment_id: int, + dewar: DewarCreate, + db: Session = Depends(get_db), ) -> DewarSchema: try: - db_dewar = DewarModel( + # Query existing dewar by name within the shipment + existing_dewar = ( + db.query(DewarModel) + .filter( + DewarModel.dewar_name == dewar.dewar_name, + DewarModel.shipment_id == shipment_id, + ) + .first() + ) + + if existing_dewar: + logging.debug( + f"Updating existing dewar with name " + f"{dewar.dewar_name} in shipment {shipment_id}" + ) + + # Check for associated puck events + for puck in existing_dewar.pucks: + puck_event_exists = ( + db.query(PuckEvent).filter(PuckEvent.puck_id == puck.id).first() + ) + if puck_event_exists: + raise HTTPException( + status_code=400, + detail=f"Puck {puck.id} " + f"associated with Dewar {existing_dewar.id}" + f" has events. " + f"Update not allowed.", + ) + + # Check for associated sample events within each puck + for sample in puck.samples: + sample_event_exists = ( + db.query(SampleEvent) + .filter(SampleEvent.sample_id == sample.id) + .first() + ) + if sample_event_exists: + raise HTTPException( + status_code=400, + detail=f"Sample {sample.id} " + f"associated with Puck " + f"{puck.id} in Dewar " + f"{existing_dewar.id} " + f"has events. Update not allowed.", + ) + + # Delete associated pucks and samples if no events are found + for puck in existing_dewar.pucks: + for sample in puck.samples: + db.delete(sample) + db.delete(puck) + db.commit() + + # Update dewar metadata + for key, value in dewar.dict( + exclude={"pucks", "number_of_pucks", "number_of_samples"} + ).items(): + if ( + hasattr(existing_dewar, key) + and hasattr(type(existing_dewar), key) + and isinstance(getattr(type(existing_dewar), key), property) + and getattr(type(existing_dewar), key).fset + ): + setattr(existing_dewar, key, value) + + # Commit updates to existing dewar + db.commit() + + # Add new pucks and samples + for puck_data in dewar.pucks: + puck = PuckModel( + dewar_id=existing_dewar.id, + puck_name=puck_data.puck_name, + puck_type=puck_data.puck_type, + puck_location_in_dewar=puck_data.puck_location_in_dewar, + ) + db.add(puck) + db.commit() + db.refresh(puck) + + for sample_data in puck_data.samples: + sample = SampleModel( + puck_id=puck.id, + sample_name=sample_data.sample_name, + proteinname=sample_data.proteinname, + position=sample_data.position, + priority=sample_data.priority, + comments=sample_data.comments, + data_collection_parameters=dict( + sample_data.data_collection_parameters or {} + ), + ) + db.add(sample) + db.commit() + db.refresh(sample) + + db.refresh(existing_dewar) + return existing_dewar + + # Create a completely new dewar if none exists + dewar_obj = DewarModel( dewar_name=dewar.dewar_name, tracking_number=dewar.tracking_number, status=dewar.status, @@ -79,14 +181,16 @@ async def create_dewar( returning_date=dewar.returning_date, contact_person_id=dewar.contact_person_id, return_address_id=dewar.return_address_id, + shipment_id=shipment_id, # Associate with the shipment ) - db.add(db_dewar) + db.add(dewar_obj) db.commit() - db.refresh(db_dewar) + db.refresh(dewar_obj) + # Add pucks and samples for the new dewar for puck_data in dewar.pucks: puck = PuckModel( - dewar_id=db_dewar.id, + dewar_id=dewar_obj.id, puck_name=puck_data.puck_name, puck_type=puck_data.puck_type, puck_location_in_dewar=puck_data.puck_location_in_dewar, @@ -96,26 +200,6 @@ async def create_dewar( db.refresh(puck) for sample_data in puck_data.samples: - logging.debug( - f"data_collection_parameters: " - f"{sample_data.data_collection_parameters}" - ) - if sample_data.data_collection_parameters is None: - serialized_params = {} - elif hasattr(sample_data.data_collection_parameters, "to_dict"): - serialized_params = sample_data.data_collection_parameters.to_dict() - elif isinstance(sample_data.data_collection_parameters, BaseModel): - serialized_params = sample_data.data_collection_parameters.dict( - exclude_unset=True - ) - elif isinstance(sample_data.data_collection_parameters, dict): - serialized_params = sample_data.data_collection_parameters - else: - raise ValueError( - "data_collection_parameters must be a dictionary," - "have a to_dict method, or be None" - ) - sample = SampleModel( puck_id=puck.id, sample_name=sample_data.sample_name, @@ -123,20 +207,19 @@ async def create_dewar( position=sample_data.position, priority=sample_data.priority, comments=sample_data.comments, - data_collection_parameters=serialized_params, + data_collection_parameters=dict( + sample_data.data_collection_parameters or {} + ), ) db.add(sample) db.commit() db.refresh(sample) - return db_dewar + return dewar_obj except SQLAlchemyError as e: logging.error(f"Database error occurred: {e}") raise HTTPException(status_code=500, detail="Internal server error") - except ValidationError as e: - logging.error(f"Validation error occurred: {e}") - raise HTTPException(status_code=400, detail="Validation error") @router.post("/{dewar_id}/generate-qrcode") diff --git a/backend/app/routers/shipment.py b/backend/app/routers/shipment.py index 37d6bce..1cb3cd0 100644 --- a/backend/app/routers/shipment.py +++ b/backend/app/routers/shipment.py @@ -2,9 +2,7 @@ from fastapi import APIRouter, HTTPException, status, Query, Depends from sqlalchemy.orm import Session from typing import List, Optional import logging -from pydantic import ValidationError from datetime import date -from sqlalchemy.exc import SQLAlchemyError import json from app.models import ( @@ -13,8 +11,6 @@ from app.models import ( Address as AddressModel, Proposal as ProposalModel, Dewar as DewarModel, - Puck as PuckModel, - Sample as SampleModel, LogisticsEvent, SampleEvent, PuckEvent, @@ -25,7 +21,6 @@ from app.schemas import ( Shipment as ShipmentSchema, ContactPerson as ContactPersonSchema, Sample as SampleSchema, - DewarCreate, DewarSchema, ) from app.database import get_db @@ -334,8 +329,13 @@ async def remove_dewar_from_shipment( f"has associated events. Removal not allowed.", ) - # Unlink the dewar from the shipment - shipment.dewars = [dw for dw in shipment.dewars if dw.id != dewar_id] + # Perform cascade deletion: Delete samples, pucks, and the dewar + for puck in dewar.pucks: + for sample in puck.samples: + db.delete(sample) # Delete associated samples + db.delete(puck) # Delete associated puck + db.delete(dewar) # Finally, delete the dewar itself + db.commit() db.refresh(shipment) @@ -399,68 +399,3 @@ async def update_shipment_comments( db.commit() db.refresh(shipment) return shipment - - -@router.post( - "/{shipment_id}/add_dewar_puck_sample", - response_model=ShipmentSchema, - status_code=status.HTTP_201_CREATED, -) -def add_dewar_puck_sample_to_shipment( - shipment_id: int, payload: DewarCreate, db: Session = Depends(get_db) -): - shipment = db.query(ShipmentModel).filter(ShipmentModel.id == shipment_id).first() - if not shipment: - raise HTTPException(status_code=404, detail="Shipment not found") - - try: - for dewar_data in payload.dewars: - dewar = ( - db.query(DewarModel) - .filter(DewarModel.dewar_name == dewar_data.dewar_name) - .first() - ) - if dewar: - # Update existing dewar - dewar.tracking_number = dewar_data.tracking_number - dewar.status = dewar_data.status - db.commit() - else: - dewar = DewarModel( - shipment_id=shipment_id, - dewar_name=dewar_data.dewar_name, - tracking_number=dewar_data.tracking_number, - status=dewar_data.status, - ) - db.add(dewar) - db.commit() - db.refresh(dewar) - - for puck_data in dewar_data.pucks: - puck = PuckModel( - dewar_id=dewar.id, - puck_name=puck_data.puck_name, - puck_type=puck_data.puck_type, - puck_location_in_dewar=puck_data.puck_location_in_dewar, - ) - db.add(puck) - db.commit() - db.refresh(puck) - - for sample_data in puck_data.samples: - sample = SampleModel( - puck_id=puck.id, - sample_name=sample_data.sample_name, - position=sample_data.position, - ) - db.add(sample) - db.commit() - db.refresh(sample) - - db.refresh(shipment) - except SQLAlchemyError as e: - raise HTTPException(status_code=500, detail=f"Database error: {e}") - except ValidationError as e: - raise HTTPException(status_code=400, detail=f"Validation error: {e}") - - return shipment diff --git a/backend/app/schemas.py b/backend/app/schemas.py index 9a3d864..bf981b2 100644 --- a/backend/app/schemas.py +++ b/backend/app/schemas.py @@ -493,8 +493,8 @@ class DewarBase(BaseModel): dewar_serial_number_id: Optional[int] = None unique_id: Optional[str] = None tracking_number: str - number_of_pucks: int - number_of_samples: int + number_of_pucks: Optional[int] = None + number_of_samples: Optional[int] = None status: str ready_date: Optional[date] shipping_date: Optional[date] diff --git a/frontend/src/components/ShipmentDetails.tsx b/frontend/src/components/ShipmentDetails.tsx index 759ad17..03bad09 100644 --- a/frontend/src/components/ShipmentDetails.tsx +++ b/frontend/src/components/ShipmentDetails.tsx @@ -126,7 +126,7 @@ const ShipmentDetails: React.FC = ({ throw new Error('Missing required fields'); } - const createdDewar = await DewarsService.createDewarDewarsPost(newDewarToPost); + const createdDewar = await DewarsService.createOrUpdateDewarDewarsPost(selectedShipment.id, newDewarToPost); if (createdDewar && selectedShipment) { const updatedShipment = await ShipmentsService.addDewarToShipmentShipmentsShipmentIdAddDewarPost(selectedShipment.id, createdDewar.id); diff --git a/frontend/src/components/SpreadsheetTable.tsx b/frontend/src/components/SpreadsheetTable.tsx index a7fa0bc..da15cc4 100644 --- a/frontend/src/components/SpreadsheetTable.tsx +++ b/frontend/src/components/SpreadsheetTable.tsx @@ -63,7 +63,6 @@ const SpreadsheetTable = ({ shipping_date: null, arrival_date: null, returning_date: null, - qrcode: 'N/A', contact_person_id: selectedShipment?.contact_person?.id, return_address_id: selectedShipment?.return_address?.id, dewar_name: '', @@ -236,14 +235,23 @@ const SpreadsheetTable = ({ 'chiphiangles': 31 }; - const checkIfDewarExists = async (dewarName) => { + const checkIfDewarExists = async (dewarName: string) => { if (!selectedShipment) return null; try { + // Fetch dewars related to the current shipment via API const shipDewars = await ShipmentsService.getDewarsByShipmentIdShipmentsShipmentIdDewarsGet(selectedShipment.id); - return shipDewars.find((d) => d.dewar_name === dewarName); + + // Search for dewar by name within the shipment + const existingDewar = shipDewars.find((d) => d.dewar_name === dewarName); + + if (existingDewar) { + console.log(`Dewar "${dewarName}" exists with ID: ${existingDewar.id}`); + return existingDewar; + } + return null; } catch (error) { - console.error('Failed to fetch existing dewars:', error); + console.error("Failed to fetch existing dewars:", error); return null; } }; @@ -258,75 +266,34 @@ const SpreadsheetTable = ({ const puckPositionMap = new Map(); const dewarsToReplace = []; - const dewarNameIdx = fieldToCol['dewarname']; - const puckNameIdx = fieldToCol['puckname']; - const puckTypeIdx = fieldToCol['pucktype']; - const sampleNameIdx = fieldToCol['crystalname']; - const proteinNameIdx = fieldToCol['proteinname']; - const samplePositionIdx = fieldToCol['positioninpuck']; - const priorityIdx = fieldToCol['priority']; - const commentsIdx = fieldToCol['comments']; - for (let rowIndex = 0; rowIndex < data.length; rowIndex++) { const row = data[rowIndex]; if (!row.data) { - console.error('Row data is missing'); + console.error(`Row ${rowIndex}: Missing or invalid data`); continue; } - // Extract values from the appropriate columns - const dewarName = typeof row.data[dewarNameIdx] === 'string' ? row.data[dewarNameIdx].trim() : null; - const puckName = row.data[puckNameIdx] !== undefined && row.data[puckNameIdx] !== null ? String(row.data[puckNameIdx]).trim() : null; - const puckType = typeof row.data[puckTypeIdx] === 'string' ? row.data[puckTypeIdx] : 'Unipuck'; - const sampleName = typeof row.data[sampleNameIdx] === 'string' ? row.data[sampleNameIdx].trim() : null; - const proteinName = typeof row.data[proteinNameIdx] === 'string' ? row.data[proteinNameIdx].trim() : null; - const samplePosition = row.data[samplePositionIdx] !== undefined && row.data[samplePositionIdx] !== null ? Number(row.data[samplePositionIdx]) : null; - const priority = row?.data?.[priorityIdx] ? Number(row.data[priorityIdx]) : null; - const comments = typeof row.data[commentsIdx] === 'string' ? row.data[commentsIdx].trim() : null; - - // Create data_collection_parameters object - const dataCollectionParameters = { - directory: row.data[fieldToCol['directory']], - oscillation: row.data[fieldToCol['oscillation']] ? parseFloat(row.data[fieldToCol['oscillation']]) : undefined, - aperture: row.data[fieldToCol['aperture']] ? row.data[fieldToCol['aperture']].trim() : undefined, - exposure: row.data[fieldToCol['exposure']] ? parseFloat(row.data[fieldToCol['exposure']]) : undefined, - totalrange: row.data[fieldToCol['totalrange']] ? parseInt(row.data[fieldToCol['totalrange']], 10) : undefined, - transmission: row.data[fieldToCol['transmission']] ? parseInt(row.data[fieldToCol['transmission']], 10) : undefined, - dose: row.data[fieldToCol['dose']] ? parseFloat(row.data[fieldToCol['dose']]) : undefined, - targetresolution: row.data[fieldToCol['targetresolution']] ? parseFloat(row.data[fieldToCol['targetresolution']]) : undefined, - datacollectiontype: row.data[fieldToCol['datacollectiontype']], - processingpipeline: row.data[fieldToCol['processingpipeline']], - spacegroupnumber: row.data[fieldToCol['spacegroupnumber']] ? parseInt(row.data[fieldToCol['spacegroupnumber']], 10) : undefined, - cellparameters: row.data[fieldToCol['cellparameters']], - rescutkey: row.data[fieldToCol['rescutkey']], - rescutvalue: row.data[fieldToCol['rescutvalue']] ? parseFloat(row.data[fieldToCol['rescutvalue']]) : undefined, - userresolution: row.data[fieldToCol['userresolution']] ? parseFloat(row.data[fieldToCol['userresolution']]) : undefined, - pdbid: row.data[fieldToCol['pdbid']], - autoprocfull: row.data[fieldToCol['autoprocfull']] === true, - procfull: row.data[fieldToCol['procfull']] === true, - adpenabled: row.data[fieldToCol['adpenabled']] === true, - noano: row.data[fieldToCol['noano']] === true, - ffcscampaign: row.data[fieldToCol['ffcscampaign']] === true, - trustedhigh: row.data[fieldToCol['trustedhigh']] ? parseFloat(row.data[fieldToCol['trustedhigh']]) : undefined, - autoprocextraparams: row.data[fieldToCol['autoprocextraparams']], - chiphiangles: row.data[fieldToCol['chiphiangles']] ? parseFloat(row.data[fieldToCol['chiphiangles']]) : undefined, - }; + const dewarName = sanitizeAndValidateColumn(row, fieldToCol['dewarname'], 'string', 'Dewar Name'); + const puckName = sanitizeAndValidateColumn(row, fieldToCol['puckname'], 'string', 'Puck Name'); + const puckType = sanitizeAndValidateColumn(row, fieldToCol['pucktype'], 'string', 'Unipuck', true); // Default: `Unipuck` + const sampleName = sanitizeAndValidateColumn(row, fieldToCol['crystalname'], 'string', 'Sample Name'); if (dewarName && puckName) { let dewar; if (!dewars.has(dewarName)) { + // Initialize new dewar object dewar = { ...initialNewDewarState, dewar_name: dewarName, contact_person_id: contactPerson.id, return_address_id: returnAddress.id, - pucks: [] + pucks: [], }; dewars.set(dewarName, dewar); puckPositionMap.set(dewarName, new Map()); - // Check if the dewar exists in the shipment + // Check if dewar exists using backend const existingDewar = await checkIfDewarExists(dewarName); if (existingDewar) { dewarsToReplace.push(existingDewar); @@ -335,78 +302,115 @@ const SpreadsheetTable = ({ dewar = dewars.get(dewarName); } + // Handle puck positions let puckPositions = puckPositionMap.get(dewarName); if (!puckPositions.has(puckName)) { puckPositions.set(puckName, puckPositions.size + 1); } + const puckPosition = puckPositions.get(puckName); - let puck = dewar.pucks.find(p => p.puck_name === puckName); + // Create puck and attach it to the dewar + let puck = dewar.pucks.find((p) => p.puck_name === puckName); if (!puck) { - puck = { - puck_name: puckName, - puck_type: puckType, - puck_location_in_dewar: puckPosition, - samples: [] - }; + puck = { puck_name: puckName, puck_type: puckType, puck_location_in_dewar: puckPosition, samples: [] }; dewar.pucks.push(puck); } + // Add sample to puck const sample = { sample_name: sampleName, - proteinname: proteinName, - position: samplePosition, - priority: priority, - comments: comments, - data_collection_parameters: dataCollectionParameters, // Attach the parameters - results: null // Placeholder for results field + position: sanitizeIntColumn(row, fieldToCol['positioninpuck'], 'Sample Position'), + proteinname: sanitizeAndValidateColumn(row, fieldToCol['proteinname'], 'string', 'Protein Name'), + priority: sanitizeIntColumn(row, fieldToCol['priority'], 'Priority'), + comments: sanitizeAndValidateColumn(row, fieldToCol['comments'], 'string', 'Comments', true), + data_collection_parameters: collectDataParameters(row), // Consolidate data parameters }; - if (isNaN(sample.position)) { - console.error(`Invalid sample position for sample ${sample.sample_name} in puck ${puckName}`); - } else { - puck.samples.push(sample); - } + puck.samples.push(sample); } else { - if (!dewarName) { - console.error(`Dewar name is missing in row ${rowIndex}`); - } - if (!puckName) { - console.error(`Puck name is missing in row ${rowIndex}`); - } + console.error(`Row ${rowIndex} is missing required fields for dewar/puck creation.`); } } const dewarsArray = Array.from(dewars.values()); - // Save dewars array for later use in handleConfirmUpdate + // Save for update dialog control setDewarsToCreate(dewars); if (dewarsArray.length > 0 && dewarsToReplace.length > 0) { setDewarsToReplace(dewarsToReplace); setShowUpdateDialog(true); - } else { + } else if (dewarsArray.length > 0) { await handleDewarCreation(dewarsArray); } }; + const sanitizeAndValidateColumn = (row, colIndex, type, columnName, isOptional = false) => { + const value = row?.data?.[colIndex]; + const sanitizedValue = type === 'string' ? value?.trim() : value; + + if (!sanitizedValue && !isOptional) { + console.error(`${columnName} is missing or invalid.`); + return null; + } + + if (type === 'number' && isNaN(sanitizedValue)) { + console.error(`${columnName} is not a valid number.`); + } + + return sanitizedValue; + }; + +// Utility to sanitize integer columns + const sanitizeIntColumn = (row, colIndex, columnName) => { + const rawValue = row?.data?.[colIndex]; + const intValue = parseInt(rawValue, 10); + + if (isNaN(intValue)) { + console.error(`${columnName} is not a valid integer.`); + } + + return intValue; + }; + +// Consolidate data collection parameters + const collectDataParameters = (row) => ({ + directory: sanitizeAndValidateColumn(row, fieldToCol['directory'], 'string', 'Directory', true), + oscillation: parseFloat(sanitizeAndValidateColumn(row, fieldToCol['oscillation'], 'number', 'Oscillation', true)), + aperture: sanitizeAndValidateColumn(row, fieldToCol['aperture'], 'string', 'Aperture', true), + exposure: parseFloat(sanitizeAndValidateColumn(row, fieldToCol['exposure'], 'number', 'Exposure', true)), + totalrange: sanitizeIntColumn(row, fieldToCol['totalrange'], 'Total Range'), + transmission: sanitizeIntColumn(row, fieldToCol['transmission'], 'Transmission'), + dose: parseFloat(sanitizeAndValidateColumn(row, fieldToCol['dose'], 'number', 'Dose', true)), + targetresolution: parseFloat(sanitizeAndValidateColumn(row, fieldToCol['targetresolution'], 'number', 'Target Resolution', true)), + datacollectiontype: sanitizeAndValidateColumn(row, fieldToCol['datacollectiontype'], 'string', 'Data Collection Type', true), + processingpipeline: sanitizeAndValidateColumn(row, fieldToCol['processingpipeline'], 'string', 'Processing Pipeline', true), + spacegroupnumber: sanitizeIntColumn(row, fieldToCol['spacegroupnumber'], 'Space Group Number'), + cellparameters: sanitizeAndValidateColumn(row, fieldToCol['cellparameters'], 'string', 'Cell Parameters', true), + rescutkey: sanitizeAndValidateColumn(row, fieldToCol['rescutkey'], 'string', 'Resolution Cut Key', true), + rescutvalue: parseFloat(sanitizeAndValidateColumn(row, fieldToCol['rescutvalue'], 'number', 'Resolution Cut Value', true)), + userresolution: parseFloat(sanitizeAndValidateColumn(row, fieldToCol['userresolution'], 'number', 'User Resolution', true)), + pdbid: sanitizeAndValidateColumn(row, fieldToCol['pdbid'], 'string', 'PDB ID', true), + autoprocfull: row.data[fieldToCol['autoprocfull']] === true, + procfull: row.data[fieldToCol['procfull']] === true, + adpenabled: row.data[fieldToCol['adpenabled']] === true, + noano: row.data[fieldToCol['noano']] === true, + ffcscampaign: row.data[fieldToCol['ffcscampaign']] === true, + trustedhigh: parseFloat(sanitizeAndValidateColumn(row, fieldToCol['trustedhigh'], 'number', 'Trusted High', true)), + autoprocextraparams: sanitizeAndValidateColumn(row, fieldToCol['autoprocextraparams'], 'string', 'Autoproc Extra Params', true), + chiphiangles: parseFloat(sanitizeAndValidateColumn(row, fieldToCol['chiphiangles'], 'number', 'Chi/Phi Angles', true)), + }); + const handleConfirmUpdate = async () => { if (dewarsToReplace.length === 0) return; try { - for (const dewar of dewarsToReplace) { - await DewarsService.deleteDewarDewarsDewarIdDelete(dewar.id); - } const dewarsArray = Array.from(dewarsToCreate.values()); - await handleDewarCreation(dewarsArray); + await handleDewarCreation(dewarsArray); // Updated logic handles replacement console.log('Dewars replaced successfully'); } catch (error) { - console.error('Error replacing dewar', error); - if (error instanceof ApiError && error.body) { - console.error('Validation errors:', error.body.detail); - } else { - console.error('Unexpected error:', error); - } + console.error('Error replacing dewars:', error); } setShowUpdateDialog(false); setDewarsToReplace([]); @@ -419,30 +423,18 @@ const SpreadsheetTable = ({ setDewarsToCreate(new Map()); }; - const handleDewarCreation = async (dewarsArray) => { + const handleDewarCreation = async (dewarsArray: any[]) => { for (const dewar of dewarsArray) { try { - if (!dewar.pucks || dewar.pucks.length === 0) { - console.error(`Dewar ${dewar.dewar_name} does not have any pucks.`); - continue; - } + // Prepare payload and exclude number_of_pucks before sending + const { number_of_pucks, number_of_samples, ...payload } = dewar; - const createdDewar = await DewarsService.createDewarDewarsPost(dewar); + // Call the backend to create or update dewars + await DewarsService.createOrUpdateDewarDewarsPost(selectedShipment.id, payload); - if (createdDewar && selectedShipment) { - await ShipmentsService.addDewarToShipmentShipmentsShipmentIdAddDewarPost( - selectedShipment.id, - createdDewar.id - ); - console.log(`Dewar ${createdDewar.dewar_name} with ID ${createdDewar.id} created and added to the shipment.`); - } + console.log(`Dewar "${dewar.dewar_name}" processed successfully.`); } catch (error) { - console.error('Error adding dewar', error); - if (error instanceof ApiError && error.body) { - console.error('Validation errors:', error.body.detail); - } else { - console.error('Unexpected error:', error); - } + console.error("Error creating/updating dewar:", error); } } }; diff --git a/testfunctions.ipynb b/testfunctions.ipynb index ae6efd0..a3fefcd 100644 --- a/testfunctions.ipynb +++ b/testfunctions.ipynb @@ -6,49 +6,249 @@ "metadata": { "collapsed": true, "ExecuteTime": { - "end_time": "2025-01-10T11:42:48.076458Z", - "start_time": "2025-01-10T11:42:48.071372Z" + "end_time": "2025-01-16T19:48:49.601896Z", + "start_time": "2025-01-16T19:48:49.599534Z" } }, "source": [ "import json\n", - "import aareDBclient\n", + "import backend.aareDBclient as aareDBclient\n", "from aareDBclient.rest import ApiException\n", "from pprint import pprint\n", - "from aareDBclient import SamplesApi\n", - "from aareDBclient.models import SampleEventCreate, SetTellPosition\n", + "#from aareDBclient import SamplesApi, ShipmentsApi, PucksApi\n", + "#from aareDBclient.models import SampleEventCreate, SetTellPosition\n", + "#from examples.examples import api_response\n", "\n", "print(aareDBclient.__version__)\n", "\n", "configuration = aareDBclient.Configuration(\n", - " host = \"https://mx-aare-test.psi.ch:1492\"\n", - " #host = \"https://127.0.0.1:8000\"\n", + " #host = \"https://mx-aare-test.psi.ch:1492\"\n", + " host = \"https://127.0.0.1:8000\"\n", ")\n", "\n", + "print(configuration.host)\n", + "\n", "configuration.verify_ssl = False # Disable SSL verification\n", - "print(dir(SamplesApi))" + "#print(dir(SamplesApi))" ], "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "0.1.0a18\n", - "['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_create_sample_event_samples_samples_sample_id_events_post_serialize', '_get_all_pucks_with_samples_and_events_samples_pucks_samples_get_serialize', '_get_last_sample_event_samples_samples_sample_id_events_last_get_serialize', '_get_samples_with_events_samples_puck_id_samples_get_serialize', 'create_sample_event_samples_samples_sample_id_events_post', 'create_sample_event_samples_samples_sample_id_events_post_with_http_info', 'create_sample_event_samples_samples_sample_id_events_post_without_preload_content', 'get_all_pucks_with_samples_and_events_samples_pucks_samples_get', 'get_all_pucks_with_samples_and_events_samples_pucks_samples_get_with_http_info', 'get_all_pucks_with_samples_and_events_samples_pucks_samples_get_without_preload_content', 'get_last_sample_event_samples_samples_sample_id_events_last_get', 'get_last_sample_event_samples_samples_sample_id_events_last_get_with_http_info', 'get_last_sample_event_samples_samples_sample_id_events_last_get_without_preload_content', 'get_samples_with_events_samples_puck_id_samples_get', 'get_samples_with_events_samples_puck_id_samples_get_with_http_info', 'get_samples_with_events_samples_puck_id_samples_get_without_preload_content']\n" + "0.1.0a19\n", + "https://127.0.0.1:8000\n" ] } ], - "execution_count": 8 + "execution_count": 11 }, { "metadata": { "ExecuteTime": { - "end_time": "2025-01-10T11:42:50.424118Z", - "start_time": "2025-01-10T11:42:50.385515Z" + "end_time": "2025-01-16T21:02:44.756830Z", + "start_time": "2025-01-16T21:02:44.640622Z" } }, "cell_type": "code", "source": [ + "## Fetch all Shipments, list corresponding dewars and pucks\n", + "\n", + "from datetime import date\n", + "from aareDBclient import ShipmentsApi\n", + "from aareDBclient.models import Shipment\n", + "\n", + "with aareDBclient.ApiClient(configuration) as api_client:\n", + " api_instance = aareDBclient.ShipmentsApi(api_client)\n", + "\n", + " try:\n", + " # Fetch all shipments\n", + " all_shipments_response = api_instance.fetch_shipments_shipments_get()\n", + "\n", + " # Print shipment names and their associated puck names\n", + " for shipment in all_shipments_response:\n", + " print(f\"Shipment ID: {shipment.id}, Shipment Name: {shipment.shipment_name}\")\n", + " if hasattr(shipment, 'dewars') and shipment.dewars: # Ensure 'dewars' exists\n", + " for dewar in shipment.dewars:\n", + " print(f\" Dewar ID: {dewar.id}, Dewar Name: {dewar.dewar_name}, Dewar Unique ID: {dewar.unique_id} \")\n", + "\n", + " if hasattr(dewar, 'pucks') and dewar.pucks: # Ensure 'pucks' exists\n", + " for puck in dewar.pucks:\n", + " print(f\" Puck ID: {puck.id}, Puck Name: {puck.puck_name}\")\n", + " else:\n", + " print(\" No pucks found in this dewar.\")\n", + " else:\n", + " print(\" No dewars found in this shipment.\")\n", + "\n", + " except ApiException as e:\n", + " print(f\"Exception when calling ShipmentsApi->fetch_shipments_shipments_get: {e}\")\n" + ], + "id": "45cc7ab6d4589711", + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Shipment ID: 2, Shipment Name: Shipment from Mordor\n", + " Dewar ID: 1, Dewar Name: Dewar One, Dewar Unique ID: bd3cb1a303be0fc9 \n", + " Puck ID: 1, Puck Name: PUCK-001\n", + " Puck ID: 2, Puck Name: PUCK002\n", + " Puck ID: 3, Puck Name: PUCK003\n", + " Puck ID: 4, Puck Name: PUCK004\n", + " Puck ID: 5, Puck Name: PUCK005\n", + " Puck ID: 6, Puck Name: PUCK006\n", + " Puck ID: 7, Puck Name: PUCK007\n", + " Dewar ID: 2, Dewar Name: Dewar Two, Dewar Unique ID: 6d23d26250394f38 \n", + " Puck ID: 8, Puck Name: PK001\n", + " Puck ID: 9, Puck Name: PK002\n", + " Puck ID: 10, Puck Name: PK003\n", + " Puck ID: 11, Puck Name: PK004\n", + " Puck ID: 12, Puck Name: PK005\n", + " Puck ID: 13, Puck Name: PK006\n", + "Shipment ID: 3, Shipment Name: Shipment from Mordor\n", + " Dewar ID: 3, Dewar Name: Dewar Three, Dewar Unique ID: None \n", + " Puck ID: 14, Puck Name: P001\n", + " Puck ID: 15, Puck Name: P002\n", + " Puck ID: 16, Puck Name: P003\n", + " Puck ID: 17, Puck Name: P004\n", + " Puck ID: 18, Puck Name: P005\n", + " Puck ID: 19, Puck Name: P006\n", + " Puck ID: 20, Puck Name: P007\n", + " Dewar ID: 4, Dewar Name: Dewar Four, Dewar Unique ID: None \n", + " Puck ID: 21, Puck Name: PC002\n", + " Puck ID: 22, Puck Name: PC003\n", + " Puck ID: 23, Puck Name: PC004\n", + " Puck ID: 24, Puck Name: PC005\n", + " Puck ID: 25, Puck Name: PC006\n", + " Puck ID: 26, Puck Name: PC007\n", + "Shipment ID: 1, Shipment Name: Shipment from Mordor\n", + " Dewar ID: 5, Dewar Name: Dewar Five, Dewar Unique ID: None \n", + " Puck ID: 27, Puck Name: PKK004\n", + " Puck ID: 28, Puck Name: PKK005\n", + " Puck ID: 29, Puck Name: PKK006\n", + " Puck ID: 30, Puck Name: PKK007\n", + " Dewar ID: 23, Dewar Name: tutu, Dewar Unique ID: None \n", + " No pucks found in this dewar.\n", + " Dewar ID: 24, Dewar Name: Dewar_test, Dewar Unique ID: 84b5630f4e933b4d \n", + " Puck ID: 178, Puck Name: CPS-4093\n", + " Puck ID: 179, Puck Name: CPS-4178\n", + " Puck ID: 180, Puck Name: PSIMX-122\n", + " Puck ID: 181, Puck Name: E-07\n", + " Puck ID: 182, Puck Name: CPS-6597\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/site-packages/urllib3/connectionpool.py:1097: InsecureRequestWarning: Unverified HTTPS request is being made to host '127.0.0.1'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#tls-warnings\n", + " warnings.warn(\n" + ] + } + ], + "execution_count": 25 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-01-16T21:27:00.520915Z", + "start_time": "2025-01-16T21:27:00.501009Z" + } + }, + "cell_type": "code", + "source": [ + "from datetime import date\n", + "from aareDBclient import LogisticsApi\n", + "from aareDBclient.models import LogisticsEventCreate # Import required model\n", + "\n", + "with aareDBclient.ApiClient(configuration) as api_client:\n", + " api_instance = aareDBclient.LogisticsApi(api_client)\n", + "\n", + " #try:\n", + " # # Create payload using the required model\n", + " # logistics_event_create = LogisticsEventCreate(\n", + " # dewar_qr_code='84b5630f4e933b4d',\n", + " # location_qr_code='A1-X06SA',\n", + " # transaction_type='incoming',\n", + " # timestamp=date.today() # Adjust if the API expects datetime\n", + " # )\n", + " #\n", + " # # Pass the payload to the API function\n", + " # api_response = api_instance.scan_dewar_logistics_dewar_scan_post(\n", + " # logistics_event_create=logistics_event_create # Pass as an object\n", + " # )\n", + " # print(\"API Response:\", api_response)\n", + " #\n", + " #except ApiException as e:\n", + " # print(f\"Exception when calling LogisticsApi->scan_dewar_logistics_dewar_scan_post: {e}\")\n", + " #\n", + " #try:\n", + " # # Create payload using the required model\n", + " # logistics_event_create = LogisticsEventCreate(\n", + " # dewar_qr_code='84b5630f4e933b4d',\n", + " # location_qr_code='A1-X06SA',\n", + " # transaction_type='refill',\n", + " # timestamp=date.today() # Adjust if the API expects datetime\n", + " # )\n", + " #\n", + " # # Pass the payload to the API function\n", + " # api_response = api_instance.scan_dewar_logistics_dewar_scan_post(\n", + " # logistics_event_create=logistics_event_create # Pass as an object\n", + " # )\n", + " # print(\"API Response:\", api_response)\n", + " #\n", + " #except ApiException as e:\n", + " # print(f\"Exception when calling LogisticsApi->scan_dewar_logistics_dewar_scan_post: {e}\")\n", + " #\n", + " try:\n", + " # Create payload using the required model\n", + " logistics_event_create = LogisticsEventCreate(\n", + " dewar_qr_code='84b5630f4e933b4d',\n", + " location_qr_code='X06DA-Beamline',\n", + " transaction_type='beamline',\n", + " timestamp=date.today() # Adjust if the API expects datetime\n", + " )\n", + "\n", + " # Pass the payload to the API function\n", + " api_response = api_instance.scan_dewar_logistics_dewar_scan_post(\n", + " logistics_event_create=logistics_event_create # Pass as an object\n", + " )\n", + " print(\"API Response:\", api_response)\n", + "\n", + " except ApiException as e:\n", + " print(f\"Exception when calling LogisticsApi->scan_dewar_logistics_dewar_scan_post: {e}\")\n" + ], + "id": "f5de1787214a6642", + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "API Response: {'message': 'Status updated successfully'}\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/site-packages/urllib3/connectionpool.py:1097: InsecureRequestWarning: Unverified HTTPS request is being made to host '127.0.0.1'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#tls-warnings\n", + " warnings.warn(\n" + ] + } + ], + "execution_count": 37 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-01-16T21:35:54.798099Z", + "start_time": "2025-01-16T21:35:54.775893Z" + } + }, + "cell_type": "code", + "source": [ + "# Get a list of pucks that are \"at the beamline\"\n", + "\n", "with aareDBclient.ApiClient(configuration) as api_client:\n", " # Create an instance of the API class\n", " api_instance = aareDBclient.PucksApi(api_client)\n", @@ -71,42 +271,37 @@ "text": [ "The response of PucksApi->get_pucks_by_slot_pucks_slot_slot_identifier_get:\n", "\n", - "[PuckWithTellPosition(id=1, puck_name='CPS-4093', puck_type='unipuck', puck_location_in_dewar=1, dewar_id=1, dewar_name='Dewar_test', user='e16371', samples=None, tell_position='D1'),\n", - " PuckWithTellPosition(id=2, puck_name='CPS-4178', puck_type='unipuck', puck_location_in_dewar=2, dewar_id=1, dewar_name='Dewar_test', user='e16371', samples=None, tell_position=None),\n", - " PuckWithTellPosition(id=3, puck_name='PSIMX-122', puck_type='unipuck', puck_location_in_dewar=3, dewar_id=1, dewar_name='Dewar_test', user='e16371', samples=None, tell_position=None),\n", - " PuckWithTellPosition(id=4, puck_name='E-07', puck_type='unipuck', puck_location_in_dewar=4, dewar_id=1, dewar_name='Dewar_test', user='e16371', samples=None, tell_position=None),\n", - " PuckWithTellPosition(id=5, puck_name='CPS-6597', puck_type='unipuck', puck_location_in_dewar=5, dewar_id=1, dewar_name='Dewar_test', user='e16371', samples=None, tell_position=None),\n", - " PuckWithTellPosition(id=6, puck_name='PSIMX-078', puck_type='unipuck', puck_location_in_dewar=6, dewar_id=1, dewar_name='Dewar_test', user='e16371', samples=None, tell_position=None),\n", - " PuckWithTellPosition(id=7, puck_name='1002', puck_type='unipuck', puck_location_in_dewar=7, dewar_id=1, dewar_name='Dewar_test', user='e16371', samples=None, tell_position=None),\n", - " PuckWithTellPosition(id=15, puck_name='PSIMX123', puck_type='unipuck', puck_location_in_dewar=1, dewar_id=4, dewar_name='Huang', user='e16371', samples=None, tell_position=None),\n", - " PuckWithTellPosition(id=16, puck_name='PSIMX125', puck_type='unipuck', puck_location_in_dewar=2, dewar_id=4, dewar_name='Huang', user='e16371', samples=None, tell_position=None),\n", - " PuckWithTellPosition(id=17, puck_name='PSIMX127', puck_type='unipuck', puck_location_in_dewar=3, dewar_id=4, dewar_name='Huang', user='e16371', samples=None, tell_position=None),\n", - " PuckWithTellPosition(id=18, puck_name='PSIMX128', puck_type='unipuck', puck_location_in_dewar=4, dewar_id=4, dewar_name='Huang', user='e16371', samples=None, tell_position=None),\n", - " PuckWithTellPosition(id=19, puck_name='PSIMX130', puck_type='unipuck', puck_location_in_dewar=5, dewar_id=4, dewar_name='Huang', user='e16371', samples=None, tell_position=None),\n", - " PuckWithTellPosition(id=20, puck_name='PSIMX131', puck_type='unipuck', puck_location_in_dewar=6, dewar_id=4, dewar_name='Huang', user='e16371', samples=None, tell_position=None),\n", - " PuckWithTellPosition(id=21, puck_name='PSIMX132', puck_type='unipuck', puck_location_in_dewar=7, dewar_id=4, dewar_name='Huang', user='e16371', samples=None, tell_position=None)]\n" + "[PuckWithTellPosition(id=188, puck_name='CPS-4093', puck_type='unipuck', puck_location_in_dewar=1, dewar_id=24, dewar_name='Dewar_test', user='e16371', samples=None, tell_position=None),\n", + " PuckWithTellPosition(id=189, puck_name='CPS-4178', puck_type='unipuck', puck_location_in_dewar=2, dewar_id=24, dewar_name='Dewar_test', user='e16371', samples=None, tell_position=None),\n", + " PuckWithTellPosition(id=190, puck_name='PSIMX-122', puck_type='unipuck', puck_location_in_dewar=3, dewar_id=24, dewar_name='Dewar_test', user='e16371', samples=None, tell_position=None),\n", + " PuckWithTellPosition(id=191, puck_name='E-07', puck_type='unipuck', puck_location_in_dewar=4, dewar_id=24, dewar_name='Dewar_test', user='e16371', samples=None, tell_position=None),\n", + " PuckWithTellPosition(id=192, puck_name='CPS-6597', puck_type='unipuck', puck_location_in_dewar=5, dewar_id=24, dewar_name='Dewar_test', user='e16371', samples=None, tell_position=None),\n", + " PuckWithTellPosition(id=193, puck_name='PSIMX-078', puck_type='unipuck', puck_location_in_dewar=6, dewar_id=24, dewar_name='Dewar_test', user='e16371', samples=None, tell_position=None),\n", + " PuckWithTellPosition(id=194, puck_name='1002', puck_type='unipuck', puck_location_in_dewar=7, dewar_id=24, dewar_name='Dewar_test', user='e16371', samples=None, tell_position=None)]\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ - "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/site-packages/urllib3/connectionpool.py:1097: InsecureRequestWarning: Unverified HTTPS request is being made to host 'mx-aare-test.psi.ch'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#tls-warnings\n", + "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/site-packages/urllib3/connectionpool.py:1097: InsecureRequestWarning: Unverified HTTPS request is being made to host '127.0.0.1'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#tls-warnings\n", " warnings.warn(\n" ] } ], - "execution_count": 9 + "execution_count": 38 }, { "metadata": { "ExecuteTime": { - "end_time": "2025-01-09T16:38:00.334741Z", - "start_time": "2025-01-09T16:38:00.302589Z" + "end_time": "2025-01-16T21:39:16.947946Z", + "start_time": "2025-01-16T21:39:16.918422Z" } }, "cell_type": "code", "source": [ + "# Attribute a puck to a position in the TELL dewar\n", + "\n", "with aareDBclient.ApiClient(configuration) as api_client:\n", " # Create an instance of the API class\n", " api_instance = aareDBclient.PucksApi(api_client)\n", @@ -115,7 +310,7 @@ " # This part is commented but will be used to attribute a puck to a position of the TELL\n", " # Define the puck ID and payload\n", "\n", - " payload = [SetTellPosition(puck_name='CPS-4093', segment='C', puck_in_segment=2),SetTellPosition(puck_name='CPS-4178', segment='C', puck_in_segment=3)]\n", + " payload = [SetTellPosition(puck_name='CPS-4178', segment='A', puck_in_segment=2),SetTellPosition(puck_name='CPS-4178', segment='C', puck_in_segment=3)]\n", " #payload = []\n", "\n", " try:\n", @@ -136,9 +331,9 @@ "The response of PucksApi->pucks_puck_id_tell_position_put:\n", "\n", "[{'message': 'The tell_position was updated successfully.',\n", - " 'new_position': 'C2',\n", + " 'new_position': 'A2',\n", " 'previous_position': None,\n", - " 'puck_name': 'CPS-4093',\n", + " 'puck_name': 'CPS-4178',\n", " 'status': 'updated'},\n", " {'message': 'The tell_position was updated successfully.',\n", " 'new_position': 'C3',\n", @@ -156,13 +351,13 @@ ] } ], - "execution_count": 36 + "execution_count": 39 }, { "metadata": { "ExecuteTime": { - "end_time": "2025-01-10T10:17:48.013415Z", - "start_time": "2025-01-10T10:17:47.983861Z" + "end_time": "2025-01-16T19:45:40.811948Z", + "start_time": "2025-01-16T19:45:40.798389Z" } }, "cell_type": "code", @@ -191,41 +386,24 @@ "id": "95f8c133359945d5", "outputs": [ { - "name": "stdout", - "output_type": "stream", - "text": [ - "The response of PucksApi->get_all_pucks_in_tell:\n", - "\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/site-packages/urllib3/connectionpool.py:1097: InsecureRequestWarning: Unverified HTTPS request is being made to host '127.0.0.1'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#tls-warnings\n", - " warnings.warn(\n" - ] - }, - { - "ename": "AttributeError", - "evalue": "'PuckWithTellPosition' object has no attribute 'sample_id'", + "ename": "NameError", + "evalue": "name 'aareDBclient' is not defined", "output_type": "error", "traceback": [ "\u001B[0;31m---------------------------------------------------------------------------\u001B[0m", - "\u001B[0;31mAttributeError\u001B[0m Traceback (most recent call last)", - "Cell \u001B[0;32mIn[7], line 17\u001B[0m\n\u001B[1;32m 15\u001B[0m \u001B[38;5;66;03m#print(formatted_response)\u001B[39;00m\n\u001B[1;32m 16\u001B[0m \u001B[38;5;28;01mfor\u001B[39;00m p \u001B[38;5;129;01min\u001B[39;00m all_pucks_response:\n\u001B[0;32m---> 17\u001B[0m \u001B[38;5;28mprint\u001B[39m(p\u001B[38;5;241m.\u001B[39mpuck_name, \u001B[43mp\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43msample_id\u001B[49m)\n\u001B[1;32m 19\u001B[0m \u001B[38;5;28;01mexcept\u001B[39;00m ApiException \u001B[38;5;28;01mas\u001B[39;00m e:\n\u001B[1;32m 20\u001B[0m \u001B[38;5;28mprint\u001B[39m(\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mException when calling PucksApi->get_all_pucks_in_tell: \u001B[39m\u001B[38;5;132;01m%s\u001B[39;00m\u001B[38;5;130;01m\\n\u001B[39;00m\u001B[38;5;124m\"\u001B[39m \u001B[38;5;241m%\u001B[39m e)\n", - "File \u001B[0;32m/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/site-packages/pydantic/main.py:856\u001B[0m, in \u001B[0;36mBaseModel.__getattr__\u001B[0;34m(self, item)\u001B[0m\n\u001B[1;32m 853\u001B[0m \u001B[38;5;28;01mreturn\u001B[39;00m \u001B[38;5;28msuper\u001B[39m()\u001B[38;5;241m.\u001B[39m\u001B[38;5;21m__getattribute__\u001B[39m(item) \u001B[38;5;66;03m# Raises AttributeError if appropriate\u001B[39;00m\n\u001B[1;32m 854\u001B[0m \u001B[38;5;28;01melse\u001B[39;00m:\n\u001B[1;32m 855\u001B[0m \u001B[38;5;66;03m# this is the current error\u001B[39;00m\n\u001B[0;32m--> 856\u001B[0m \u001B[38;5;28;01mraise\u001B[39;00m \u001B[38;5;167;01mAttributeError\u001B[39;00m(\u001B[38;5;124mf\u001B[39m\u001B[38;5;124m'\u001B[39m\u001B[38;5;132;01m{\u001B[39;00m\u001B[38;5;28mtype\u001B[39m(\u001B[38;5;28mself\u001B[39m)\u001B[38;5;241m.\u001B[39m\u001B[38;5;18m__name__\u001B[39m\u001B[38;5;132;01m!r}\u001B[39;00m\u001B[38;5;124m object has no attribute \u001B[39m\u001B[38;5;132;01m{\u001B[39;00mitem\u001B[38;5;132;01m!r}\u001B[39;00m\u001B[38;5;124m'\u001B[39m)\n", - "\u001B[0;31mAttributeError\u001B[0m: 'PuckWithTellPosition' object has no attribute 'sample_id'" + "\u001B[0;31mNameError\u001B[0m Traceback (most recent call last)", + "Cell \u001B[0;32mIn[5], line 1\u001B[0m\n\u001B[0;32m----> 1\u001B[0m \u001B[38;5;28;01mwith\u001B[39;00m \u001B[43maareDBclient\u001B[49m\u001B[38;5;241m.\u001B[39mApiClient(configuration) \u001B[38;5;28;01mas\u001B[39;00m api_client:\n\u001B[1;32m 2\u001B[0m \u001B[38;5;66;03m# Create an instance of the API class\u001B[39;00m\n\u001B[1;32m 3\u001B[0m api_instance \u001B[38;5;241m=\u001B[39m aareDBclient\u001B[38;5;241m.\u001B[39mPucksApi(api_client)\n\u001B[1;32m 5\u001B[0m \u001B[38;5;66;03m# GET request: Fetch all pucks in the tell\u001B[39;00m\n", + "\u001B[0;31mNameError\u001B[0m: name 'aareDBclient' is not defined" ] } ], - "execution_count": 7 + "execution_count": 5 }, { "metadata": { "ExecuteTime": { - "end_time": "2025-01-09T19:41:14.264895Z", - "start_time": "2025-01-09T19:41:14.245643Z" + "end_time": "2025-01-16T19:45:44.042534Z", + "start_time": "2025-01-16T19:45:44.030292Z" } }, "cell_type": "code", @@ -256,30 +434,24 @@ "id": "ee8abb293096334a", "outputs": [ { - "name": "stdout", - "output_type": "stream", - "text": [ - "The response of post_sample_event:\n", - "\n", - "SampleEventResponse(id=418, sample_id=261, event_type='Failed', timestamp=datetime.datetime(2025, 1, 9, 20, 41, 14))\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/site-packages/urllib3/connectionpool.py:1097: InsecureRequestWarning: Unverified HTTPS request is being made to host '127.0.0.1'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#tls-warnings\n", - " warnings.warn(\n" + "ename": "NameError", + "evalue": "name 'aareDBclient' is not defined", + "output_type": "error", + "traceback": [ + "\u001B[0;31m---------------------------------------------------------------------------\u001B[0m", + "\u001B[0;31mNameError\u001B[0m Traceback (most recent call last)", + "Cell \u001B[0;32mIn[6], line 1\u001B[0m\n\u001B[0;32m----> 1\u001B[0m \u001B[38;5;28;01mwith\u001B[39;00m \u001B[43maareDBclient\u001B[49m\u001B[38;5;241m.\u001B[39mApiClient(configuration) \u001B[38;5;28;01mas\u001B[39;00m api_client:\n\u001B[1;32m 2\u001B[0m \u001B[38;5;66;03m# Create an instance of the Samples API class\u001B[39;00m\n\u001B[1;32m 3\u001B[0m api_instance \u001B[38;5;241m=\u001B[39m aareDBclient\u001B[38;5;241m.\u001B[39mSamplesApi(api_client)\n\u001B[1;32m 5\u001B[0m \u001B[38;5;66;03m# Define the sample ID and event payload using the expected model\u001B[39;00m\n", + "\u001B[0;31mNameError\u001B[0m: name 'aareDBclient' is not defined" ] } ], - "execution_count": 70 + "execution_count": 6 }, { "metadata": { "ExecuteTime": { - "end_time": "2025-01-10T11:43:57.303671Z", - "start_time": "2025-01-10T11:43:57.285551Z" + "end_time": "2025-01-16T19:45:46.332149Z", + "start_time": "2025-01-16T19:45:46.320963Z" } }, "cell_type": "code", @@ -301,24 +473,18 @@ "id": "6a808ee09f97ae13", "outputs": [ { - "name": "stdout", - "output_type": "stream", - "text": [ - "The response of get_last_sample_event:\n", - "\n", - "SampleEventResponse(id=3, sample_id=14, event_type='Unmounted', timestamp=datetime.datetime(2025, 1, 10, 5, 53, 38))\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/site-packages/urllib3/connectionpool.py:1097: InsecureRequestWarning: Unverified HTTPS request is being made to host 'mx-aare-test.psi.ch'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#tls-warnings\n", - " warnings.warn(\n" + "ename": "NameError", + "evalue": "name 'aareDBclient' is not defined", + "output_type": "error", + "traceback": [ + "\u001B[0;31m---------------------------------------------------------------------------\u001B[0m", + "\u001B[0;31mNameError\u001B[0m Traceback (most recent call last)", + "Cell \u001B[0;32mIn[7], line 1\u001B[0m\n\u001B[0;32m----> 1\u001B[0m \u001B[38;5;28;01mwith\u001B[39;00m \u001B[43maareDBclient\u001B[49m\u001B[38;5;241m.\u001B[39mApiClient(configuration) \u001B[38;5;28;01mas\u001B[39;00m api_client:\n\u001B[1;32m 2\u001B[0m \u001B[38;5;66;03m# Create an instance of the Samples API class\u001B[39;00m\n\u001B[1;32m 3\u001B[0m api_instance \u001B[38;5;241m=\u001B[39m aareDBclient\u001B[38;5;241m.\u001B[39mSamplesApi(api_client)\n\u001B[1;32m 5\u001B[0m \u001B[38;5;28;01mtry\u001B[39;00m:\n\u001B[1;32m 6\u001B[0m \u001B[38;5;66;03m# Get the last sample event\u001B[39;00m\n", + "\u001B[0;31mNameError\u001B[0m: name 'aareDBclient' is not defined" ] } ], - "execution_count": 11 + "execution_count": 7 } ], "metadata": {