wakeupmh's picture
Update app.py
3451846 verified
raw
history blame
6.89 kB
from smolagents import CodeAgent,DuckDuckGoSearchTool, HfApiModel,load_tool,tool
import datetime
import requests
import pytz
import yaml
from tools.final_answer import FinalAnswerTool
from Gradio_UI import GradioUI
@tool
def find_nearest_meteor(address: str) -> str:
"""A tool that finds the nearest meteor landing site based on a given address.
Args:
address: A string representing an address (e.g., '123 Main St, New York, NY')
"""
import requests
import math
from urllib.parse import quote
def geocode_address(address):
"""Convert address to latitude and longitude using OpenCage API."""
base_url = "https://api.opencagedata.com/geocode/v1/json"
api_key = "03c48dae07364cabb7f121d8c1519492"
# URL encode the address
encoded_address = quote(address)
# Construct the full request URL
url = f"{base_url}?q={encoded_address}&key={api_key}&no_annotations=1&language=en"
headers = {
'accept': 'application/json, text/javascript, */*; q=0.01',
'accept-language': 'pt-BR,pt;q=0.9,en-US;q=0.8,en;q=0.7',
'origin': 'https://www.gps-coordinates.net',
'referer': 'https://www.gps-coordinates.net/',
'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36'
}
try:
response = requests.get(url, headers=headers)
data = response.json()
if data['total_results'] > 0:
location = data['results'][0]['geometry']
return {
'lat': location['lat'],
'lng': location['lng'],
'formatted_address': data['results'][0]['formatted']
}
else:
return None
except Exception as e:
return f"Error geocoding address: {str(e)}"
def get_meteor_data():
"""Fetch meteor landing site data from NASA API."""
url = "https://data.nasa.gov/resource/gh4g-9sfh.json"
try:
response = requests.get(url)
return response.json()
except Exception as e:
return f"Error fetching meteor data: {str(e)}"
def calculate_distance(lat1, lon1, lat2, lon2):
"""Calculate the great circle distance between two points on earth."""
# Radius of earth in kilometers
R = 6371.0
# Convert latitude and longitude from degrees to radians
lat1_rad = math.radians(lat1)
lon1_rad = math.radians(lon1)
lat2_rad = math.radians(lat2)
lon2_rad = math.radians(lon2)
# Difference in coordinates
dlon = lon2_rad - lon1_rad
dlat = lat2_rad - lat1_rad
# Haversine formula
a = math.sin(dlat / 2)**2 + math.cos(lat1_rad) * math.cos(lat2_rad) * math.sin(dlon / 2)**2
c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a))
distance = R * c
return distance
# Geocode the address
location_data = geocode_address(address)
if not location_data or isinstance(location_data, str):
return f"Could not geocode address: {address}. {location_data if isinstance(location_data, str) else ''}"
# Get meteor data
meteor_data = get_meteor_data()
if isinstance(meteor_data, str):
return meteor_data
# Calculate distance to each meteor
nearest_meteor = None
min_distance = float('inf')
for meteor in meteor_data:
# Check if meteor has geolocation data
if 'geolocation' in meteor and meteor['geolocation'] and 'latitude' in meteor['geolocation'] and 'longitude' in meteor['geolocation']:
try:
meteor_lat = float(meteor['geolocation']['latitude'])
meteor_lng = float(meteor['geolocation']['longitude'])
distance = calculate_distance(
location_data['lat'],
location_data['lng'],
meteor_lat,
meteor_lng
)
if distance < min_distance:
min_distance = distance
nearest_meteor = meteor
except (ValueError, TypeError):
# Skip entries with invalid coordinates
continue
if nearest_meteor:
# Format the response
name = nearest_meteor.get('name', 'Unknown')
year = nearest_meteor.get('year', 'Unknown year')
mass = nearest_meteor.get('mass', 'Unknown mass')
recclass = nearest_meteor.get('recclass', 'Unknown classification')
return (
f"Nearest meteor to {location_data['formatted_address']}:\n"
f"Name: {name}\n"
f"Year: {year}\n"
f"Classification: {recclass}\n"
f"Mass (grams): {mass}\n"
f"Distance: {min_distance:.2f} km\n"
f"Coordinates: {nearest_meteor['geolocation']['latitude']}, {nearest_meteor['geolocation']['longitude']}"
)
else:
return "No meteor landing sites found with valid coordinates."
@tool
def get_current_time_in_timezone(timezone: str) -> str:
"""A tool that fetches the current local time in a specified timezone.
Args:
timezone: A string representing a valid timezone (e.g., 'America/New_York').
"""
try:
# Create timezone object
tz = pytz.timezone(timezone)
# Get current time in that timezone
local_time = datetime.datetime.now(tz).strftime("%Y-%m-%d %H:%M:%S")
return f"The current local time in {timezone} is: {local_time}"
except Exception as e:
return f"Error fetching time for timezone '{timezone}': {str(e)}"
final_answer = FinalAnswerTool()
# If the agent does not answer, the model is overloaded, please use another model or the following Hugging Face Endpoint that also contains qwen2.5 coder:
# model_id='https://pflgm2locj2t89co.us-east-1.aws.endpoints.huggingface.cloud'
model = HfApiModel(
max_tokens=2096,
temperature=0.5,
model_id='Qwen/Qwen2.5-Coder-32B-Instruct',# it is possible that this model may be overloaded
custom_role_conversions=None,
)
# Import tool from Hub
image_generation_tool = load_tool("agents-course/text-to-image", trust_remote_code=True)
with open("prompts.yaml", 'r') as stream:
prompt_templates = yaml.safe_load(stream)
agent = CodeAgent(
model=model,
tools=[find_nearest_meteor, final_answer], ## add your tools here (don't remove final answer)
max_steps=6,
verbosity_level=1,
grammar=None,
planning_interval=None,
name=None,
description=None,
prompt_templates=prompt_templates
)
GradioUI(agent).launch()