update to aws location services
This commit is contained in:
parent
ab068cac8b
commit
387b71e4e8
@ -2,54 +2,90 @@ import logging
|
|||||||
import json
|
import json
|
||||||
from typing import Dict, Any
|
from typing import Dict, Any
|
||||||
from http import HTTPStatus
|
from http import HTTPStatus
|
||||||
import urllib.request
|
import boto3
|
||||||
|
from botocore.exceptions import ClientError
|
||||||
|
import os
|
||||||
|
|
||||||
|
REGION = os.environ['AWS_REGION']
|
||||||
|
|
||||||
logger = logging.getLogger()
|
logger = logging.getLogger()
|
||||||
logger.setLevel(logging.INFO)
|
logger.setLevel(logging.INFO)
|
||||||
|
|
||||||
|
# Replace with the name of your AWS Location Place Index
|
||||||
|
PLACE_INDEX_NAME = 'helpngoindex'
|
||||||
|
|
||||||
|
def ensure_place_index_exists(index_name: str):
|
||||||
|
client = boto3.client('location', region_name=REGION)
|
||||||
|
|
||||||
|
# Check if index exists
|
||||||
|
try:
|
||||||
|
response = client.list_place_indexes()
|
||||||
|
if any(entry['IndexName'] == index_name for entry in response['Entries']):
|
||||||
|
print(f"✅ Place index '{index_name}' already exists.")
|
||||||
|
return
|
||||||
|
except ClientError as e:
|
||||||
|
print(f"❌ Error listing indexes: {e}")
|
||||||
|
return
|
||||||
|
|
||||||
|
# Create the index
|
||||||
|
try:
|
||||||
|
print(f"🆕 Creating place index '{index_name}' in region '{region}'...")
|
||||||
|
client.create_place_index(
|
||||||
|
IndexName=index_name,
|
||||||
|
DataSource='Here',
|
||||||
|
Description='Auto-created place index for geocoding',
|
||||||
|
PricingPlan='RequestBasedUsage'
|
||||||
|
)
|
||||||
|
except ClientError as e:
|
||||||
|
print(f"❌ Error creating index: {e}")
|
||||||
|
return
|
||||||
|
|
||||||
|
# Wait until ACTIVE
|
||||||
|
print("⏳ Waiting for index to become ACTIVE...")
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
status = client.describe_place_index(IndexName=index_name)['Status']
|
||||||
|
print(f"Status: {status}")
|
||||||
|
if status == 'ACTIVE':
|
||||||
|
print(f"✅ Place index '{index_name}' is now ACTIVE.")
|
||||||
|
break
|
||||||
|
time.sleep(2)
|
||||||
|
except ClientError as e:
|
||||||
|
print(f"❌ Error checking status: {e}")
|
||||||
|
break
|
||||||
|
|
||||||
|
# Initialize the AWS Location client
|
||||||
|
location_client = boto3.client('location', region_name=REGION)
|
||||||
|
|
||||||
def lambda_handler(event: Dict[str, Any], context: Any) -> Dict[str, Any]:
|
def lambda_handler(event: Dict[str, Any], context: Any) -> Dict[str, Any]:
|
||||||
"""
|
"""
|
||||||
AWS Lambda handler for processing Bedrock agent requests and geocoding location names using Nominatim.
|
AWS Lambda handler for processing Bedrock agent requests and geocoding location names using AWS Location Service.
|
||||||
|
|
||||||
Args:
|
|
||||||
event (Dict[str, Any]): The Lambda event containing action details
|
|
||||||
context (Any): The Lambda context object
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
Dict[str, Any]: Response formatted for Bedrock Agents
|
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
action_group = event['actionGroup']
|
action_group = event['actionGroup']
|
||||||
function = event['function']
|
function = event['function']
|
||||||
message_version = event.get('messageVersion', 1)
|
message_version = event.get('messageVersion', 1)
|
||||||
parameters = event.get('parameters', [])
|
parameters = event.get('parameters', [])
|
||||||
print(parameters)
|
|
||||||
parameters_dict = {parameter["name"]: parameter["value"] for parameter in parameters}
|
parameters_dict = {parameter["name"]: parameter["value"] for parameter in parameters}
|
||||||
location_name = parameters_dict.get('location_name')
|
location_name = parameters_dict.get('location_name')
|
||||||
if not location_name:
|
if not location_name:
|
||||||
raise KeyError("Missing required parameter: 'location_name'")
|
raise KeyError("Missing required parameter: 'location_name'")
|
||||||
|
|
||||||
# Call Nominatim API to geocode the location
|
# Use AWS Location Service to geocode the location
|
||||||
query = urllib.parse.urlencode({
|
ensure_place_index_exists(PLACE_INDEX_NAME)
|
||||||
"q": location_name,
|
response = location_client.search_place_index_for_text(
|
||||||
"format": "json",
|
IndexName=PLACE_INDEX_NAME,
|
||||||
"limit": 1
|
Text=location_name,
|
||||||
})
|
MaxResults=1
|
||||||
headers = {
|
)
|
||||||
"User-Agent": "aws-lambda-geocoder/1.0"
|
|
||||||
}
|
|
||||||
url = f"https://nominatim.openstreetmap.org/search?{query}"
|
|
||||||
|
|
||||||
req = urllib.request.Request(url, headers=headers)
|
results = response.get("Results", [])
|
||||||
with urllib.request.urlopen(req) as response:
|
|
||||||
response_data = response.read()
|
|
||||||
print(response_data)
|
|
||||||
results = json.loads(response_data)
|
|
||||||
if not results:
|
if not results:
|
||||||
raise ValueError(f"No coordinates found for '{location_name}'")
|
raise ValueError(f"No coordinates found for '{location_name}'")
|
||||||
|
|
||||||
lat = float(results[0]["lat"])
|
# Extract coordinates [Longitude, Latitude]
|
||||||
lon = float(results[0]["lon"])
|
lon, lat = results[0]['Place']['Geometry']['Point']
|
||||||
|
|
||||||
# Prepare Bedrock-compatible response
|
# Prepare Bedrock-compatible response
|
||||||
response_body = {
|
response_body = {
|
||||||
@ -80,6 +116,14 @@ def lambda_handler(event: Dict[str, Any], context: Any) -> Dict[str, Any]:
|
|||||||
'statusCode': HTTPStatus.BAD_REQUEST,
|
'statusCode': HTTPStatus.BAD_REQUEST,
|
||||||
'body': f'Error: {str(e)}'
|
'body': f'Error: {str(e)}'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
except ClientError as e:
|
||||||
|
logger.error('AWS Location error: %s', str(e))
|
||||||
|
return {
|
||||||
|
'statusCode': HTTPStatus.INTERNAL_SERVER_ERROR,
|
||||||
|
'body': f'AWS Location error: {str(e)}'
|
||||||
|
}
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error('Unexpected error: %s', str(e))
|
logger.error('Unexpected error: %s', str(e))
|
||||||
return {
|
return {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user