Spaces:
Runtime error
Runtime error
File size: 5,169 Bytes
a31ad35 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 |
from fastapi import APIRouter, HTTPException, BackgroundTasks, Query
from typing import Optional
import logging
from db.geocoding_repository import GeocodingRepository
from config.settings import GEOAPIFY_API_KEY
router = APIRouter(prefix="/geocoding", tags=["Geocoding"])
logger = logging.getLogger(__name__)
# Global variable to track geocoding status
geocoding_status = {
"running": False,
"last_run": None,
"last_result": None
}
async def run_geocoding_task(api_key: str = None):
"""Background task to run geocoding"""
global geocoding_status
try:
geocoding_status["running"] = True
geocoding_status["last_result"] = None
async with GeocodingRepository() as repo:
result = await repo.batch_geocode_stores(api_key=api_key)
geocoding_status["last_result"] = result
geocoding_status["last_run"] = "completed"
except Exception as e:
logger.error(f"Error in geocoding task: {e}")
geocoding_status["last_result"] = {"error": str(e)}
geocoding_status["last_run"] = "failed"
finally:
geocoding_status["running"] = False
@router.post("/start")
async def start_geocoding(
background_tasks: BackgroundTasks,
api_key: Optional[str] = Query(None, description="Geoapify API key (optional - will use settings if not provided)")
):
"""
Start the geocoding process for all stores without coordinates using Geoapify.
- **api_key**: Geoapify API key (optional - will use environment variable if not provided)
"""
if geocoding_status["running"]:
raise HTTPException(
status_code=400,
detail="Geocoding process is already running"
)
# Use provided API key or fallback to settings
final_api_key = api_key or GEOAPIFY_API_KEY
if not final_api_key:
raise HTTPException(
status_code=400,
detail="Geoapify API key is required. Provide it as parameter or set GEOAPIFY_API_KEY environment variable."
)
# Start background task
background_tasks.add_task(run_geocoding_task, final_api_key)
return {
"message": "Geocoding process started",
"status": "running",
"service": "Geoapify"
}
@router.get("/status")
async def get_geocoding_status():
"""Get the current status of the geocoding process"""
return {
"running": geocoding_status["running"],
"last_run": geocoding_status["last_run"],
"last_result": geocoding_status["last_result"]
}
@router.get("/stores-without-coordinates")
async def get_stores_without_coordinates():
"""Get count of stores that still need geocoding"""
try:
async with GeocodingRepository() as repo:
stores = repo.get_stores_without_coordinates()
return {
"count": len(stores),
"stores": stores[:10] # Return first 10 as sample
}
except Exception as e:
logger.error(f"Error getting stores without coordinates: {e}")
raise HTTPException(status_code=500, detail=str(e))
@router.post("/geocode-single/{store_id}")
async def geocode_single_store(
store_id: str,
api_key: Optional[str] = Query(None, description="Geoapify API key")
):
"""Geocode a single store by ID"""
try:
# Use provided API key or fallback to settings
final_api_key = api_key or GEOAPIFY_API_KEY
if not final_api_key:
raise HTTPException(
status_code=400,
detail="Geoapify API key is required"
)
async with GeocodingRepository() as repo:
# Get store details
store_response = repo.supabase.table('stores').select('*').eq('store_id', store_id).execute()
if not store_response.data:
raise HTTPException(status_code=404, detail="Store not found")
store = store_response.data[0]
address = store.get('store_address', '')
if not address:
raise HTTPException(status_code=400, detail="Store has no address")
# Geocode address using Geoapify
coordinates = await repo.geocode_address_geoapify(address, store_id, final_api_key)
if coordinates:
lat, lng = coordinates
if repo.update_store_coordinates(store_id, lat, lng):
return {
"message": "Store geocoded successfully",
"store_id": store_id,
"coordinates": {"lat": lat, "lng": lng}
}
else:
raise HTTPException(status_code=500, detail="Failed to update coordinates")
else:
raise HTTPException(status_code=400, detail="Failed to geocode address")
except HTTPException:
raise
except Exception as e:
logger.error(f"Error geocoding single store: {e}")
raise HTTPException(status_code=500, detail=str(e))
|