from geopy.geocoders import Nominatim from geopy.exc import GeocoderTimedOut, GeocoderUnavailable from models.location_models import LocationData, Coordinates, ErrorResponse import google.generativeai as genai import requests from dotenv import load_dotenv load_dotenv() import json import os GOOGLE_API_KEY = os.getenv("GOOGLE_API_KEY") genai.configure(api_key=GOOGLE_API_KEY) model = genai.GenerativeModel('gemini-1.5-flash') class LocationService: @staticmethod def extract_location_entities(ner_results): city, state, country = None, None, None for entity in ner_results: word = entity['word'].replace("##", "").strip() if entity['entity_group'] == 'CITY' and word.isalpha(): city = word elif entity['entity_group'] == 'STATE' and word.isalpha(): state = word elif entity['entity_group'] == 'COUNTRY' and word.isalpha(): country = word if city or state or country: return {k: v for k, v in {"city": city, "state": state, "country": country}.items() if v is not None} else: return None @staticmethod def get_llm_response(system_prompt) -> str: url = "https://api.openai.com/v1/chat/completions" headers = { "Content-Type": "application/json", "Authorization": f"Bearer {os.getenv('OPENAI_API_KEY')}", "OpenAI-Organization": os.getenv('ORG_ID') } data = { "model": "gpt-4o-mini", "max_tokens": 2000, "messages": [{"role": "user", "content": f"{system_prompt}"}], "temperature": 0.0 } try: response = requests.post(url, headers=headers, json=data) output = response.json() except Exception as e: print(f"Error Occurred {e}") return f"Error Occurred {e}" return output['choices'][0]['message']['content'] @staticmethod def system_prompt(location : str) -> str: return f"""You are a Text Analyser where you will extract city , state , country from given piece of text given below.You will strictly extract following keys from the text country , state , city. {location} \n Rules: 1. You will analyse the text and extract the country , city or state from the text , lets say if you have 'Udhampur, JK, India' , here JK means Jammu and Kashmir , so if you get any initials extract the exact name. 2. If any value is not found, return null. 3. If all values are null, return null. Ensure the strictly that output is a valid JSON object containing strictly the above keys, without any explanations. Generate a JSON response in the following format without using the ```json block. Ensure the output is properly formatted as plain text JSON. """ @staticmethod def get_lat_lng(data:dict): try: location = data.get('location') except: return Coordinates(latitude=None, longitude=None) url = f"https://maps.googleapis.com/maps/api/geocode/json?address={location}&key={os.getenv('GOOGLE_GEO_API_KEY')}" try: response = requests.get(url) json_data = response.json() lat = json_data.get('results',None)[0].get('geometry',None).get('location',None).get('lat') long = json_data.get('results',None)[0].get('geometry',None).get('location',None).get('lng') return Coordinates( latitude=lat, longitude=long ) except Exception as e: return Coordinates(latitude=None , longitude=None) @staticmethod def get_coordinates(data:dict) -> Coordinates | ErrorResponse: print("Inside get coordinates") print(data) try: location = data.get('location') except: return Coordinates(latitude=None, longitude=None) city = None state = None country = None if location: # Assuming `app.nlp` is already initialized elsewhere and accessible llm_prompt = LocationService.system_prompt(location) response = LocationService.get_llm_response(llm_prompt) # Extract city, state, and country using the logic from extract_location_entities location_entities = json.loads(response) if location_entities: city = location_entities.get('city') state = location_entities.get('state') country = location_entities.get('country') # Create the location string location_string = ' '.join(filter(None, [city, state, country])) if not location_string: location_string = location else: return ErrorResponse(error="No location information provided") geolocator = Nominatim(user_agent="Geolocation") print("Printing location string") print(location_string) if city or state or country : location_string = city elif country is None: location_string = city elif city is None: location_string = state elif state is None: location_string = city try: getLoc = geolocator.geocode(location_string) print(getLoc.latitude) print(getLoc.longitude) return Coordinates( latitude=getLoc.latitude, longitude=getLoc.longitude ) except Exception as e: print(f"Error {e}") return Coordinates(latitude=None , longitude=None)