Spaces:
Runtime error
Runtime error
| 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 | |
| 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" | |
| } | |
| 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"] | |
| } | |
| 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)) | |
| 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)) | |