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))