Add default values to optional fields in SampleUpdate
This commit is contained in:
parent
ac38bc3bb6
commit
0f6759e417
@ -313,6 +313,40 @@ async def download_dewar_label(dewar_id: int, db: Session = Depends(get_db)):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@router.put("/samples/{sample_id}", response_model=Sample)
|
||||||
|
async def update_sample(
|
||||||
|
sample_id: int,
|
||||||
|
sample_update: SampleUpdate,
|
||||||
|
db: Session = Depends(get_db),
|
||||||
|
):
|
||||||
|
# Log the payload received from the frontend
|
||||||
|
logging.info(
|
||||||
|
f"Payload received for sample ID {sample_id}: "
|
||||||
|
f"{sample_update.dict(exclude_unset=True)}"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Query the sample from the database
|
||||||
|
sample = db.query(SampleModel).filter(SampleModel.id == sample_id).first()
|
||||||
|
|
||||||
|
if not sample:
|
||||||
|
logging.error(f"Sample with ID {sample_id} not found")
|
||||||
|
raise HTTPException(status_code=404, detail="Sample not found")
|
||||||
|
|
||||||
|
# Apply updates
|
||||||
|
for key, value in sample_update.dict(exclude_unset=True).items():
|
||||||
|
if hasattr(sample, key):
|
||||||
|
setattr(sample, key, value)
|
||||||
|
|
||||||
|
# Commit changes to the database
|
||||||
|
db.commit()
|
||||||
|
db.refresh(sample) # Reload the updated sample object
|
||||||
|
|
||||||
|
# Log the updated sample before returning it
|
||||||
|
logging.info(f"Updated sample with ID {sample_id}: {Sample.from_orm(sample)}")
|
||||||
|
|
||||||
|
return Sample.from_orm(sample)
|
||||||
|
|
||||||
|
|
||||||
@router.get("/dewars/{dewar_id}/samples", response_model=Dewar)
|
@router.get("/dewars/{dewar_id}/samples", response_model=Dewar)
|
||||||
async def get_dewar_samples(dewar_id: int, db: Session = Depends(get_db)):
|
async def get_dewar_samples(dewar_id: int, db: Session = Depends(get_db)):
|
||||||
# Fetch the Dewar with nested relationships
|
# Fetch the Dewar with nested relationships
|
||||||
@ -374,27 +408,6 @@ async def get_dewar_samples(dewar_id: int, db: Session = Depends(get_db)):
|
|||||||
return Dewar(**dewar_data)
|
return Dewar(**dewar_data)
|
||||||
|
|
||||||
|
|
||||||
@router.put("/samples/{sample_id}", response_model=Sample)
|
|
||||||
async def update_sample(
|
|
||||||
sample_id: int,
|
|
||||||
sample_update: SampleUpdate,
|
|
||||||
db: Session = Depends(get_db),
|
|
||||||
):
|
|
||||||
sample = db.query(SampleModel).filter(SampleModel.id == sample_id).first()
|
|
||||||
if not sample:
|
|
||||||
raise HTTPException(status_code=404, detail="Sample not found")
|
|
||||||
|
|
||||||
# Apply updates
|
|
||||||
for key, value in sample_update.dict(exclude_unset=True).items():
|
|
||||||
if hasattr(sample, key):
|
|
||||||
setattr(sample, key, value)
|
|
||||||
|
|
||||||
# Save changes
|
|
||||||
db.commit()
|
|
||||||
db.refresh(sample)
|
|
||||||
return Sample.from_orm(sample)
|
|
||||||
|
|
||||||
|
|
||||||
@router.get("/", response_model=List[DewarSchema])
|
@router.get("/", response_model=List[DewarSchema])
|
||||||
async def get_dewars(db: Session = Depends(get_db)):
|
async def get_dewars(db: Session = Depends(get_db)):
|
||||||
try:
|
try:
|
||||||
|
@ -619,12 +619,12 @@ class SlotSchema(BaseModel):
|
|||||||
|
|
||||||
|
|
||||||
class SampleUpdate(BaseModel):
|
class SampleUpdate(BaseModel):
|
||||||
sample_name: Optional[str]
|
sample_name: Optional[str] = None
|
||||||
proteinname: Optional[str]
|
proteinname: Optional[str] = None
|
||||||
priority: Optional[int]
|
priority: Optional[int] = None
|
||||||
position: Optional[int]
|
position: Optional[int] = None
|
||||||
comments: Optional[str]
|
comments: Optional[str] = None
|
||||||
data_collection_parameters: Optional[DataCollectionParameters]
|
data_collection_parameters: Optional[DataCollectionParameters] = None
|
||||||
|
|
||||||
class Config:
|
class Config:
|
||||||
from_attributes = True
|
from_attributes = True
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import React, { useEffect, useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import { DataGrid, GridColDef, GridCellEditStopParams } from "@mui/x-data-grid";
|
import { DataGrid, GridColDef, GridCellEditStopParams, GridRowModel } from "@mui/x-data-grid";
|
||||||
import { DewarsService } from "../../openapi";
|
import { DewarsService } from "../../openapi";
|
||||||
|
|
||||||
interface SampleSpreadsheetProps {
|
interface SampleSpreadsheetProps {
|
||||||
@ -34,6 +34,24 @@ const SampleSpreadsheet: React.FC<SampleSpreadsheetProps> = ({ dewarId }) => {
|
|||||||
totalrange,
|
totalrange,
|
||||||
transmission,
|
transmission,
|
||||||
dose,
|
dose,
|
||||||
|
targetresolution,
|
||||||
|
aperture,
|
||||||
|
datacollectiontype,
|
||||||
|
processingpipeline,
|
||||||
|
spacegroupnumber,
|
||||||
|
cellparameters,
|
||||||
|
rescutkey,
|
||||||
|
rescutvalue,
|
||||||
|
userresolution,
|
||||||
|
pdbid,
|
||||||
|
autoprocfull,
|
||||||
|
procfull,
|
||||||
|
adpenabled,
|
||||||
|
noano,
|
||||||
|
ffcscampaig,
|
||||||
|
trustedhigh,
|
||||||
|
autoprocextraparams,
|
||||||
|
chiphiangles
|
||||||
} = sample.data_collection_parameters || {};
|
} = sample.data_collection_parameters || {};
|
||||||
|
|
||||||
allRows.push({
|
allRows.push({
|
||||||
@ -53,7 +71,24 @@ const SampleSpreadsheet: React.FC<SampleSpreadsheetProps> = ({ dewarId }) => {
|
|||||||
totalRange: totalrange || null,
|
totalRange: totalrange || null,
|
||||||
transmission: transmission || null,
|
transmission: transmission || null,
|
||||||
dose: dose || null,
|
dose: dose || null,
|
||||||
dataCollectionParameters: sample.data_collection_parameters || {}, // Ensure this is never undefined
|
targetresolution: targetresolution || null,
|
||||||
|
aperture: aperture || null,
|
||||||
|
datacollectiontype: datacollectiontype || null,
|
||||||
|
processingpipeline: processingpipeline || null,
|
||||||
|
spacegroupnumber: spacegroupnumber || null,
|
||||||
|
cellparameters: cellparameters || {},
|
||||||
|
rescutkey: rescutkey || null,
|
||||||
|
rescutvalue: rescutvalue || null,
|
||||||
|
userresolution: userresolution || null,
|
||||||
|
pdbid: pdbid || null,
|
||||||
|
autoprocfull: autoprocfull || null,
|
||||||
|
procfull: procfull || null,
|
||||||
|
adpenabled: adpenabled || null,
|
||||||
|
noano: noano || null,
|
||||||
|
ffcscampaig: ffcscampaig || null,
|
||||||
|
trustedhigh: trustedhigh || null,
|
||||||
|
autoprocextraparams: autoprocextraparams || {},
|
||||||
|
chiphiangles: chiphiangles || null,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -62,30 +97,38 @@ const SampleSpreadsheet: React.FC<SampleSpreadsheetProps> = ({ dewarId }) => {
|
|||||||
|
|
||||||
// Define columns for the grid
|
// Define columns for the grid
|
||||||
setColumns([
|
setColumns([
|
||||||
{ field: "dewarName", headerName: "Dewar Name", width: 150, editable: false },
|
{ field: "dewarName", headerName: "Dewar Name", width: 150, editable: false }, // not editable for now
|
||||||
{ field: "puckName", headerName: "Puck Name", width: 150 },
|
{ field: "puckName", headerName: "Puck Name", width: 150, editable: false }, // not editable for now
|
||||||
{ field: "puckType", headerName: "Puck Type", width: 150 },
|
{ field: "puckType", headerName: "Puck Type", width: 150, editable: false }, // not editable for now
|
||||||
{ field: "crystalName", headerName: "Crystal Name", width: 200, editable: true },
|
{ field: "crystalName", headerName: "Crystal Name", width: 200, editable: false }, // not editable for now
|
||||||
{ field: "proteinName", headerName: "Protein Name", width: 200, editable: true },
|
{ field: "proteinName", headerName: "Protein Name", width: 200, editable: false }, // not editable for now
|
||||||
{ field: "position", headerName: "Position", width: 100, editable: true, type: "number" },
|
{ field: "position", headerName: "Position", width: 100, editable: true, type: "number" },
|
||||||
{ field: "priority", headerName: "Priority", width: 100, editable: true, type: "number" },
|
{ field: "priority", headerName: "Priority", width: 100, editable: true, type: "number" },
|
||||||
{ field: "comments", headerName: "Comments", width: 300, editable: true },
|
{ field: "comments", headerName: "Comments", width: 300, editable: true },
|
||||||
{ field: "directory", headerName: "Directory", width: 200 },
|
{ field: "directory", headerName: "Directory", width: 200, editable: true },
|
||||||
{ field: "oscillation", headerName: "Oscillation", width: 150, editable: true, type: "number" },
|
{ field: "oscillation", headerName: "Oscillation", width: 150, editable: true, type: "number" },
|
||||||
{ field: "exposure", headerName: "Exposure", width: 150, editable: true, type: "number" },
|
{ field: "exposure", headerName: "Exposure", width: 150, editable: true, type: "number" },
|
||||||
{ field: "totalRange", headerName: "Total Range", width: 150, editable: true, type: "number" },
|
{ field: "totalRange", headerName: "Total Range", width: 150, editable: true, type: "number" },
|
||||||
{ field: "transmission", headerName: "Transmission", width: 150, editable: true, type: "number" },
|
{ field: "transmission", headerName: "Transmission", width: 150, editable: true, type: "number" },
|
||||||
{ field: "dose", headerName: "Dose", width: 150, editable: true, type: "number" },
|
{ field: "dose", headerName: "Dose", width: 150, editable: true, type: "number" },
|
||||||
{
|
{ field: "targetresolution", headerName: "Target Resolution", width: 150, editable: true, type: "number" },
|
||||||
field: "dataCollectionParameters",
|
{ field: "aperture", headerName: "Aperture", width: 150, editable: true },
|
||||||
headerName: "Data Collection Parameters (Raw)",
|
{ field: "datacollectiontype", headerName: "Data Collection Type", width: 200, editable: true },
|
||||||
width: 300,
|
{ field: "processingpipeline", headerName: "Processing Pipeline", width: 200, editable: true },
|
||||||
valueGetter: (params) =>
|
{ field: "spacegroupnumber", headerName: "Space Group Number", width: 200, editable: true },
|
||||||
params.row?.dataCollectionParameters
|
{ field: "cellparameters", headerName: "Cell Parameters", width: 300, editable: true },
|
||||||
? JSON.stringify(params.row.dataCollectionParameters)
|
{ field: "rescutkey", headerName: "ResCut Key", width: 150, editable: true },
|
||||||
: "N/A", // Fallback if undefined
|
{ field: "rescutvalue", headerName: "ResCut Value", width: 150, editable: true, editable: true },
|
||||||
editable: false,
|
{ field: "userresolution", headerName: "User Resolution", width: 150, editable: true, editable: true },
|
||||||
},
|
{ field: "pdbid", headerName: "PDB ID", width: 150, editable: true },
|
||||||
|
{ field: "autoprocfull", headerName: "AutoProc Full", width: 200, editable: true },
|
||||||
|
{ field: "procfull", headerName: "Proc Full", width: 200, editable: true },
|
||||||
|
{ field: "adpenabled", headerName: "ADP Enabled", width: 150, editable: true },
|
||||||
|
{ field: "noano", headerName: "No Anomalous", width: 150, editable: true },
|
||||||
|
{ field: "ffcscampaig", headerName: "FFCS Campaign", width: 150, editable: true },
|
||||||
|
{ field: "trustedhigh", headerName: "Trusted High", width: 150, editable: true },
|
||||||
|
{ field: "autoprocextraparams", headerName: "AutoProc Extra Params", width: 300, editable: true },
|
||||||
|
{ field: "chiphiangles", headerName: "Chi Phi Angles", width: 150, editable: true },
|
||||||
]);
|
]);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error fetching dewar samples:", error);
|
console.error("Error fetching dewar samples:", error);
|
||||||
@ -98,19 +141,112 @@ const SampleSpreadsheet: React.FC<SampleSpreadsheetProps> = ({ dewarId }) => {
|
|||||||
// Handle cell editing to persist changes to the backend
|
// Handle cell editing to persist changes to the backend
|
||||||
const handleCellEditStop = async (params: GridCellEditStopParams) => {
|
const handleCellEditStop = async (params: GridCellEditStopParams) => {
|
||||||
const { id, field, value } = params;
|
const { id, field, value } = params;
|
||||||
|
|
||||||
|
// Validation to ensure we have valid data from the cell edit
|
||||||
if (!id || !field || value === undefined) {
|
if (!id || !field || value === undefined) {
|
||||||
console.error("Invalid edit inputs");
|
console.error("Invalid edit inputs:", { id, field, value });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Fetch the current row data (old state) based on its ID
|
||||||
|
const updatedRow = rows.find((row) => row.id === id);
|
||||||
|
|
||||||
|
if (!updatedRow) {
|
||||||
|
console.error("Row not found for ID:", id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the updated sample, force-overwriting the changed cell value
|
||||||
|
const updatedSample = {
|
||||||
|
...updatedRow, // Include other fields from the existing row
|
||||||
|
[field]: value, // Explicitly overwrite the updated field with new value
|
||||||
|
};
|
||||||
|
|
||||||
|
console.log("Payload sent to the backend:", updatedSample); // Log fixed payload
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Call the update_sample API endpoint
|
// Optimistically update UI for better experience
|
||||||
await DewarsService.updateSampleSampleIdPut(id as number, {
|
setRows((prevRows) =>
|
||||||
[field]: value,
|
prevRows.map((row) =>
|
||||||
});
|
row.id === id ? { ...row, [field]: value } : row
|
||||||
console.log("Sample updated successfully");
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
// API call to persist changes
|
||||||
|
await DewarsService.updateSampleDewarsSamplesSampleIdPut(Number(id), updatedSample);
|
||||||
|
|
||||||
|
console.log(`Sample with ID ${id} successfully updated.`);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(`Error updating sample (id: ${id}):`, error);
|
console.error(`Failed to update sample with ID ${id}:`, error);
|
||||||
|
|
||||||
|
// Revert optimistic update on error
|
||||||
|
setRows((prevRows) =>
|
||||||
|
prevRows.map((row) => (row.id === id ? updatedRow : row))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const processRowUpdate = async (newRow: GridRowModel, oldRow: GridRowModel) => {
|
||||||
|
try {
|
||||||
|
console.log("Old row:", oldRow); // Log the original row
|
||||||
|
console.log("Updated row:", newRow); // Log the updated data from the grid
|
||||||
|
|
||||||
|
// Reconstruct 'data_collection_parameters' from the flat table structure
|
||||||
|
const updatedDataCollectionParameters = {
|
||||||
|
...(oldRow.data_collection_parameters || {}), // Preserve old values
|
||||||
|
directory: newRow.directory ?? oldRow.data_collection_parameters?.directory,
|
||||||
|
oscillation: newRow.oscillation ?? oldRow.data_collection_parameters?.oscillation,
|
||||||
|
exposure: newRow.exposure ?? oldRow.data_collection_parameters?.exposure,
|
||||||
|
totalrange: newRow.totalRange ?? oldRow.data_collection_parameters?.totalrange,
|
||||||
|
transmission: newRow.transmission ?? oldRow.data_collection_parameters?.transmission,
|
||||||
|
dose: newRow.dose ?? oldRow.data_collection_parameters?.dose,
|
||||||
|
targetresolution: newRow.targetresolution ?? oldRow.data_collection_parameters?.targetresolution,
|
||||||
|
aperture: newRow.aperture ?? oldRow.data_collection_parameters?.aperture,
|
||||||
|
datacollectiontype: newRow.datacollectiontype ?? oldRow.data_collection_parameters?.datacollectiontype,
|
||||||
|
processingpipeline: newRow.processingpipeline ?? oldRow.data_collection_parameters?.processingpipeline,
|
||||||
|
spacegroupnumber: newRow.spacegroupnumber ?? oldRow.data_collection_parameters?.spacegroupnumber,
|
||||||
|
//cellparameters: newRow.cellparameters ?? oldRow.data_collection_parameters?.cellparameters,
|
||||||
|
rescutkey: newRow.rescutkey ?? oldRow.data_collection_parameters?.rescutkey,
|
||||||
|
rescutvalue: newRow.rescutvalue ?? oldRow.data_collection_parameters?.rescutvalue,
|
||||||
|
userresolution: newRow.userresolution ?? oldRow.data_collection_parameters?.userresolution,
|
||||||
|
pdbid: newRow.pdbid ?? oldRow.data_collection_parameters?.pdbid,
|
||||||
|
autoprocfull: newRow.autoprocfull ?? oldRow.data_collection_parameters?.autoprocfull,
|
||||||
|
procfull: newRow.procfull ?? oldRow.data_collection_parameters?.procfull,
|
||||||
|
adpenabled: newRow.adpenabled ?? oldRow.data_collection_parameters?.adpenabled,
|
||||||
|
noano: newRow.noano ?? oldRow.data_collection_parameters?.noano,
|
||||||
|
ffcscampaig: newRow.ffcscampaig ?? oldRow.data_collection_parameters?.ffcscampaig,
|
||||||
|
trustedhigh: newRow.trustedhigh ?? oldRow.data_collection_parameters?.trustedhigh,
|
||||||
|
//autoprocextraparams: newRow.autoprocextraparams ?? oldRow.data_collection_parameters?.autoprocextraparams,
|
||||||
|
chiphiangles: newRow.chiphiangles ?? oldRow.data_collection_parameters?.chiphiangles,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Assemble the final payload
|
||||||
|
const payload = {
|
||||||
|
...oldRow, // Include all original fields
|
||||||
|
...newRow, // Overwrite or add updated fields
|
||||||
|
data_collection_parameters: updatedDataCollectionParameters, // Include the merged/validated structure
|
||||||
|
};
|
||||||
|
|
||||||
|
console.log("Final payload sent to backend:", payload);
|
||||||
|
|
||||||
|
// Optimistically update the UI
|
||||||
|
setRows((prevRows) =>
|
||||||
|
prevRows.map((row) =>
|
||||||
|
row.id === newRow.id ? { ...row, ...payload } : row
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Send the payload to the backend
|
||||||
|
await DewarsService.updateSampleDewarsSamplesSampleIdPut(Number(newRow.id), payload);
|
||||||
|
|
||||||
|
console.log(`Successfully updated sample with ID ${newRow.id}.`);
|
||||||
|
return payload; // Return the updated row
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`Failed to update sample with ID ${newRow.id}:`, error);
|
||||||
|
|
||||||
|
// On failure, revert to the old row
|
||||||
|
return oldRow;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -120,7 +256,7 @@ const SampleSpreadsheet: React.FC<SampleSpreadsheetProps> = ({ dewarId }) => {
|
|||||||
rows={rows}
|
rows={rows}
|
||||||
columns={columns}
|
columns={columns}
|
||||||
pageSize={10}
|
pageSize={10}
|
||||||
onCellEditStop={handleCellEditStop}
|
processRowUpdate={processRowUpdate} // Exclusively handle updates
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -3506,8 +3506,8 @@
|
|||||||
{
|
{
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"ExecuteTime": {
|
"ExecuteTime": {
|
||||||
"end_time": "2025-01-09T19:33:01.143326Z",
|
"end_time": "2025-01-09T19:41:14.264895Z",
|
||||||
"start_time": "2025-01-09T19:33:01.128023Z"
|
"start_time": "2025-01-09T19:41:14.245643Z"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
@ -3518,9 +3518,9 @@
|
|||||||
" api_instance = aareDBclient.SamplesApi(api_client)\n",
|
" api_instance = aareDBclient.SamplesApi(api_client)\n",
|
||||||
"\n",
|
"\n",
|
||||||
" # Define the sample ID and event payload using the expected model\n",
|
" # Define the sample ID and event payload using the expected model\n",
|
||||||
" sample_id = 260\n",
|
" sample_id = 261\n",
|
||||||
" event_payload = SampleEventCreate(\n",
|
" event_payload = SampleEventCreate(\n",
|
||||||
" event_type=\"Unmounted\" # Replace with actual event type if different\n",
|
" event_type=\"Failed\" # Replace with actual event type if different\n",
|
||||||
" )\n",
|
" )\n",
|
||||||
"\n",
|
"\n",
|
||||||
" try:\n",
|
" try:\n",
|
||||||
@ -3543,7 +3543,7 @@
|
|||||||
"text": [
|
"text": [
|
||||||
"The response of post_sample_event:\n",
|
"The response of post_sample_event:\n",
|
||||||
"\n",
|
"\n",
|
||||||
"SampleEventResponse(id=417, sample_id=260, event_type='Unmounted', timestamp=datetime.datetime(2025, 1, 9, 20, 33, 1))\n"
|
"SampleEventResponse(id=418, sample_id=261, event_type='Failed', timestamp=datetime.datetime(2025, 1, 9, 20, 41, 14))\n"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -3555,13 +3555,13 @@
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"execution_count": 67
|
"execution_count": 70
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"ExecuteTime": {
|
"ExecuteTime": {
|
||||||
"end_time": "2025-01-09T19:33:04.470152Z",
|
"end_time": "2025-01-09T19:41:23.052434Z",
|
||||||
"start_time": "2025-01-09T19:33:04.454152Z"
|
"start_time": "2025-01-09T19:41:23.036108Z"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
@ -3573,7 +3573,7 @@
|
|||||||
"\n",
|
"\n",
|
||||||
" try:\n",
|
" try:\n",
|
||||||
" # Get the last sample event\n",
|
" # Get the last sample event\n",
|
||||||
" last_event_response = api_instance.get_last_sample_event_samples_samples_sample_id_events_last_get(260)\n",
|
" last_event_response = api_instance.get_last_sample_event_samples_samples_sample_id_events_last_get(261)\n",
|
||||||
" print(\"The response of get_last_sample_event:\\n\")\n",
|
" print(\"The response of get_last_sample_event:\\n\")\n",
|
||||||
" pprint(last_event_response)\n",
|
" pprint(last_event_response)\n",
|
||||||
"\n",
|
"\n",
|
||||||
@ -3588,7 +3588,7 @@
|
|||||||
"text": [
|
"text": [
|
||||||
"The response of get_last_sample_event:\n",
|
"The response of get_last_sample_event:\n",
|
||||||
"\n",
|
"\n",
|
||||||
"SampleEventResponse(id=417, sample_id=260, event_type='Unmounted', timestamp=datetime.datetime(2025, 1, 9, 20, 33, 1))\n"
|
"SampleEventResponse(id=418, sample_id=261, event_type='Failed', timestamp=datetime.datetime(2025, 1, 9, 20, 41, 14))\n"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -3600,7 +3600,7 @@
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"execution_count": 68
|
"execution_count": 71
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"metadata": {
|
"metadata": {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user