159 lines
4.8 KiB
Python
Raw Normal View History

from fastapi import FastAPI, File, UploadFile
from fastapi.responses import FileResponse, PlainTextResponse, JSONResponse
from fastapi.middleware.cors import CORSMiddleware
from pydantic import BaseModel
import zipfile
import os
import shutil
from pathlib import Path
from qc_validator import validate_shapefiles
from verofy_uploader import upload_to_verofy
app = FastAPI()
# Enable CORS for frontend
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
TEMP_DIR = Path("../temp")
TEMP_DIR.mkdir(exist_ok=True)
class VerofyMapRequest(BaseModel):
mapId: int
verofyEmail: str
verofyPassword: str
@app.post("/upload")
async def upload_shapefile(file: UploadFile = File(...)):
"""Handle shapefile ZIP upload and QC validation"""
# Clear temp directory
for item in TEMP_DIR.glob("*"):
if item.is_file():
item.unlink()
elif item.is_dir():
shutil.rmtree(item)
# Save uploaded file
zip_path = TEMP_DIR / file.filename
with open(zip_path, "wb") as f:
content = await file.read()
f.write(content)
# Unzip file
try:
with zipfile.ZipFile(zip_path, 'r') as zip_ref:
zip_ref.extractall(TEMP_DIR)
# Check if files are in a subdirectory and flatten if needed
shp_files = list(TEMP_DIR.glob("*.shp"))
if len(shp_files) == 0:
# Look for shapefiles in subdirectories
subdirs = [d for d in TEMP_DIR.iterdir() if d.is_dir()]
if len(subdirs) == 1:
# Move all files from subdirectory to temp root
subdir = subdirs[0]
for item in subdir.iterdir():
shutil.move(str(item), str(TEMP_DIR / item.name))
# Remove empty subdirectory
subdir.rmdir()
except Exception as e:
return PlainTextResponse(f"Error extracting ZIP file: {str(e)}", status_code=400)
# Run QC validation
qc_result = validate_shapefiles(TEMP_DIR)
if qc_result["passed"]:
return {"message": "success"}
else:
# Generate QC report
report_path = TEMP_DIR / "QC_report.txt"
with open(report_path, "w") as f:
f.write("QC VALIDATION FAILED\n")
f.write("=" * 50 + "\n\n")
for error in qc_result["errors"]:
f.write(f"{error}\n")
return FileResponse(
path=report_path,
media_type="text/plain",
filename="QC_report.txt"
)
@app.post("/push-to-verofy")
async def push_to_verofy(request: VerofyMapRequest):
"""Push shapefiles from temp folder to Verofy"""
# Use credentials from the request
verofy_email = request.verofyEmail
verofy_password = request.verofyPassword
if not verofy_email or not verofy_password:
return JSONResponse(
status_code=400,
content={
"success": False,
"error": "Verofy credentials are required. Please provide your email and password."
}
)
# Check if temp directory has shapefiles
shapefile_count = len(list(TEMP_DIR.glob("*.shp")))
if shapefile_count == 0:
return JSONResponse(
status_code=400,
content={
"success": False,
"error": "No shapefiles found in temp directory. Please upload files first."
}
)
# Upload to Verofy
try:
result = upload_to_verofy(
temp_dir=str(TEMP_DIR),
map_id=request.mapId,
email=verofy_email,
password=verofy_password,
limit=None # Upload ALL records (no limit)
)
if result["success"]:
return JSONResponse(
status_code=200,
content={
"success": True,
"message": "Successfully uploaded to Verofy",
"uploaded": result["uploaded"],
"errors": result.get("errors", [])
}
)
else:
return JSONResponse(
status_code=500,
content={
"success": False,
"error": "Upload to Verofy failed",
"details": result.get("errors", [])
}
)
except Exception as e:
return JSONResponse(
status_code=500,
content={
"success": False,
"error": f"Error uploading to Verofy: {str(e)}"
}
)
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=8000)