| from fastapi import APIRouter, UploadFile, File, HTTPException |
| import pandas as pd |
| import io |
| from app.data.data_store import store |
| from app.database import log_activity, log_upload |
|
|
| router = APIRouter(prefix="/upload", tags=["Data Upload"]) |
|
|
|
|
| @router.post("/bms") |
| async def upload_bms(file: UploadFile = File(...)): |
| """Upload BMS telemetry CSV. Required: timestamp, vehicle_id, soc, voltage, current, temperature, cycle_count""" |
| try: |
| contents = await file.read() |
| df = pd.read_csv(io.StringIO(contents.decode('utf-8'))) |
| store.set_bms(df) |
| data = store.get_bms() |
| n_rows = sum(len(v) for v in data.values()) |
|
|
| log_upload("bms", file.filename, n_rows) |
| log_activity( |
| action = f"Uploaded BMS data: {len(data)} vehicles, {n_rows} readings", |
| endpoint = "/upload/bms", |
| method = "POST", |
| details = {"filename": file.filename, "vehicles": len(data), "rows": n_rows} |
| ) |
| return {"message": "BMS data uploaded successfully", "vehicles": len(data), "total_readings": n_rows} |
| except Exception as e: |
| log_upload("bms", file.filename, 0, status="error", error_msg=str(e)) |
| raise HTTPException(status_code=400, detail=str(e)) |
|
|
|
|
| @router.post("/fleet") |
| async def upload_fleet(file: UploadFile = File(...)): |
| """Upload fleet operational data CSV. Required: asset_id, category, route_distance_km, payload_tons, duty_cycle_hrs, dwell_time_hrs, terrain_score, diesel_l_per_100km, age_years""" |
| try: |
| contents = await file.read() |
| df = pd.read_csv(io.StringIO(contents.decode('utf-8'))) |
| records = df.to_dict('records') |
| store.set_fleet(records) |
|
|
| log_upload("fleet", file.filename, len(records)) |
| log_activity( |
| action = f"Uploaded fleet data: {len(records)} assets", |
| endpoint = "/upload/fleet", |
| method = "POST", |
| details = {"filename": file.filename, "assets": len(records)} |
| ) |
| return {"message": "Fleet data uploaded successfully", "assets": len(records)} |
| except Exception as e: |
| log_upload("fleet", file.filename, 0, status="error", error_msg=str(e)) |
| raise HTTPException(status_code=400, detail=str(e)) |
|
|
|
|
| @router.post("/suppliers") |
| async def upload_suppliers(file: UploadFile = File(...)): |
| """Upload supplier master CSV. Required: supplier_id, name, tier, material, country, geopolitical_risk, esg_score, quality_score, lead_time_days, concentration_pct""" |
| try: |
| contents = await file.read() |
| df = pd.read_csv(io.StringIO(contents.decode('utf-8'))) |
| records = df.to_dict('records') |
| store.set_suppliers(records) |
|
|
| log_upload("suppliers", file.filename, len(records)) |
| log_activity( |
| action = f"Uploaded supplier data: {len(records)} suppliers", |
| endpoint = "/upload/suppliers", |
| method = "POST", |
| details = {"filename": file.filename, "suppliers": len(records)} |
| ) |
| return {"message": "Supplier data uploaded successfully", "suppliers": len(records)} |
| except Exception as e: |
| log_upload("suppliers", file.filename, 0, status="error", error_msg=str(e)) |
| raise HTTPException(status_code=400, detail=str(e)) |
|
|
|
|
| @router.post("/inspections") |
| async def upload_inspections(file: UploadFile = File(...)): |
| """Upload incoming inspection CSV. Required: lot_id, supplier_id, material, defect_rate, inspection_date""" |
| try: |
| contents = await file.read() |
| df = pd.read_csv(io.StringIO(contents.decode('utf-8'))) |
| records = df.to_dict('records') |
| store.set_inspections(records) |
|
|
| log_upload("inspections", file.filename, len(records)) |
| log_activity( |
| action = f"Uploaded inspection data: {len(records)} records", |
| endpoint = "/upload/inspections", |
| method = "POST", |
| details = {"filename": file.filename, "inspections": len(records)} |
| ) |
| return {"message": "Inspection data uploaded successfully", "inspections": len(records)} |
| except Exception as e: |
| log_upload("inspections", file.filename, 0, status="error", error_msg=str(e)) |
| raise HTTPException(status_code=400, detail=str(e)) |
|
|
|
|
| @router.post("/reset") |
| async def reset_data(): |
| """Reset all data back to synthetic demo datasets and clear DB tables.""" |
| store.reset() |
| log_activity( |
| action = "Reset all data to synthetic demo datasets", |
| endpoint = "/upload/reset", |
| method = "POST" |
| ) |
| return {"message": "Data reset to synthetic demo datasets"} |
|
|
|
|
| @router.get("/history") |
| def upload_history(): |
| """Return the upload history from the database.""" |
| from app.database import get_upload_history |
| return get_upload_history(limit=50) |
|
|