Now with working validation and correction feedback
This commit is contained in:
parent
1fa61f0e78
commit
dbebfd6d5a
@ -5,11 +5,13 @@ from app.services.spreadsheet_service import SampleSpreadsheetImporter, Spreadsh
|
||||
from fastapi.responses import FileResponse
|
||||
import os
|
||||
from pydantic import ValidationError # Import ValidationError here
|
||||
|
||||
from app.row_storage import row_storage # Import the RowStorage instance
|
||||
|
||||
router = APIRouter()
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
importer = SampleSpreadsheetImporter() # assuming this is a singleton or manageable instance
|
||||
|
||||
|
||||
@router.get("/download-template", response_class=FileResponse)
|
||||
async def download_template():
|
||||
@ -36,7 +38,6 @@ async def upload_file(file: UploadFile = File(...)):
|
||||
raise HTTPException(status_code=400, detail="Invalid file format. Please upload an .xlsx file.")
|
||||
|
||||
# Initialize the importer and process the spreadsheet
|
||||
importer = SampleSpreadsheetImporter()
|
||||
validated_model, errors, raw_data, headers = importer.import_spreadsheet_with_errors(file)
|
||||
|
||||
# Extract unique values for dewars, pucks, and samples
|
||||
@ -58,6 +59,11 @@ async def upload_file(file: UploadFile = File(...)):
|
||||
headers=headers # Include headers in the response
|
||||
)
|
||||
|
||||
# Store row data for future use
|
||||
for idx, row in enumerate(validated_model):
|
||||
row_num = idx + 4 # Adjust row numbering if necessary
|
||||
row_storage.set_row(row_num, row.dict())
|
||||
|
||||
logger.info(f"Returning response with {len(validated_model)} records and {len(errors)} errors.")
|
||||
return response_data
|
||||
|
||||
@ -72,27 +78,28 @@ async def upload_file(file: UploadFile = File(...)):
|
||||
|
||||
@router.post("/validate-cell")
|
||||
async def validate_cell(data: dict):
|
||||
"""Validate a single cell value based on expected column type."""
|
||||
row_num = data.get("row")
|
||||
col_name = data.get("column")
|
||||
value = data.get("value")
|
||||
|
||||
importer = SampleSpreadsheetImporter()
|
||||
# Get the full data for the row
|
||||
current_row_data = row_storage.get_row(row_num)
|
||||
|
||||
# Ensure we've cleaned the value before validation
|
||||
expected_type = importer.get_expected_type(col_name)
|
||||
cleaned_value = importer._clean_value(value, expected_type)
|
||||
# Update the cell value
|
||||
current_row_data[col_name] = importer._clean_value(value, importer.get_expected_type(col_name))
|
||||
|
||||
logger.info(f"Validating cell: row {row_num}, column {col_name}, value {cleaned_value}")
|
||||
# Temporarily store the updated row data
|
||||
row_storage.set_row(row_num, current_row_data)
|
||||
|
||||
logger.info(f"Validating cell: row {row_num}, column {col_name}, value {value}")
|
||||
|
||||
try:
|
||||
# Construct a dictionary with the expected format for validation
|
||||
validation_data = {col_name: cleaned_value}
|
||||
SpreadsheetModel(**validation_data)
|
||||
# Ensure we're using the full row data context for validation
|
||||
validated_row = SpreadsheetModel(**current_row_data)
|
||||
logger.info(f"Validation succeeded for row {row_num}, column {col_name}")
|
||||
return {"is_valid": True, "message": ""}
|
||||
except ValidationError as e:
|
||||
# Extract the first error message
|
||||
message = e.errors()[0]['msg']
|
||||
logger.error(f"Validation failed for row {row_num}, column {col_name}: {message}")
|
||||
return {"is_valid": False, "message": message}
|
||||
return {"is_valid": False, "message": message}
|
||||
|
12
backend/app/row_storage.py
Normal file
12
backend/app/row_storage.py
Normal file
@ -0,0 +1,12 @@
|
||||
class RowStorage:
|
||||
def __init__(self):
|
||||
self.data = {}
|
||||
|
||||
def get_row(self, row_num):
|
||||
return self.data.get(row_num, {})
|
||||
|
||||
def set_row(self, row_num, row_data):
|
||||
self.data[row_num] = row_data
|
||||
|
||||
|
||||
row_storage = RowStorage() # Singleton instance for storing row data
|
@ -209,4 +209,4 @@ class SampleSpreadsheetImporter:
|
||||
|
||||
self.model = model
|
||||
logger.info(f"Finished processing {len(model)} records with {len(errors)} errors")
|
||||
return self.model, errors, raw_data, headers # Include headers in the response
|
||||
return self.model, errors, raw_data, headers # Include headers in the response
|
Loading…
x
Reference in New Issue
Block a user