Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -97,6 +97,75 @@ def get_open_meteo_weather(city: str) -> str:
|
|
| 97 |
except Exception as e:
|
| 98 |
return f"Error fetching weather data: {str(e)}"
|
| 99 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 100 |
|
| 101 |
final_answer = FinalAnswerTool()
|
| 102 |
|
|
|
|
| 97 |
except Exception as e:
|
| 98 |
return f"Error fetching weather data: {str(e)}"
|
| 99 |
|
| 100 |
+
@tool
|
| 101 |
+
def stargazing_advisor_by_city(city: str) -> str:
|
| 102 |
+
"""
|
| 103 |
+
Provides a stargazing recommendation for a given city by checking the forecasted cloud cover
|
| 104 |
+
and moon phase using the Open-Meteo API.
|
| 105 |
+
|
| 106 |
+
Args:
|
| 107 |
+
city: The name of the city (e.g., "Berlin").
|
| 108 |
+
|
| 109 |
+
Returns:
|
| 110 |
+
A string with the forecast details and a recommendation on stargazing conditions.
|
| 111 |
+
"""
|
| 112 |
+
try:
|
| 113 |
+
# Step 1: Convert city name to coordinates using Open-Meteo's geocoding API.
|
| 114 |
+
geo_url = f"https://geocoding-api.open-meteo.com/v1/search?name={city}"
|
| 115 |
+
geo_resp = requests.get(geo_url)
|
| 116 |
+
geo_resp.raise_for_status()
|
| 117 |
+
geo_data = geo_resp.json()
|
| 118 |
+
results = geo_data.get("results")
|
| 119 |
+
if not results:
|
| 120 |
+
return f"Could not find coordinates for {city}."
|
| 121 |
+
first_result = results[0]
|
| 122 |
+
latitude = first_result.get("latitude")
|
| 123 |
+
longitude = first_result.get("longitude")
|
| 124 |
+
resolved_city = first_result.get("name", city)
|
| 125 |
+
|
| 126 |
+
# Step 2: Request daily forecast data (sunrise, sunset, moon phase, and average cloud cover)
|
| 127 |
+
forecast_url = (
|
| 128 |
+
f"https://api.open-meteo.com/v1/forecast?"
|
| 129 |
+
f"latitude={latitude}&longitude={longitude}"
|
| 130 |
+
f"&daily=sunrise,sunset,moon_phase,cloudcover_mid"
|
| 131 |
+
f"&timezone=auto"
|
| 132 |
+
)
|
| 133 |
+
forecast_resp = requests.get(forecast_url)
|
| 134 |
+
forecast_resp.raise_for_status()
|
| 135 |
+
forecast_data = forecast_resp.json()
|
| 136 |
+
daily = forecast_data.get("daily", {})
|
| 137 |
+
|
| 138 |
+
# Ensure we have forecast data
|
| 139 |
+
times = daily.get("time", [])
|
| 140 |
+
if not times:
|
| 141 |
+
return "No daily forecast data available."
|
| 142 |
+
|
| 143 |
+
# We'll use the forecast for the first available day.
|
| 144 |
+
forecast_date = times[0]
|
| 145 |
+
moon_phase = daily.get("moon_phase", [])[0]
|
| 146 |
+
cloudcover = daily.get("cloudcover_mid", [])[0]
|
| 147 |
+
sunrise = daily.get("sunrise", [])[0]
|
| 148 |
+
sunset = daily.get("sunset", [])[0]
|
| 149 |
+
|
| 150 |
+
# Step 3: Determine stargazing quality.
|
| 151 |
+
# For ideal stargazing, you want low cloud cover (<20%) and a moon phase close to new moon (<=0.2 or >=0.8).
|
| 152 |
+
if cloudcover < 20 and (moon_phase <= 0.2 or moon_phase >= 0.8):
|
| 153 |
+
recommendation = "excellent"
|
| 154 |
+
elif cloudcover < 40 and (moon_phase <= 0.3 or moon_phase >= 0.7):
|
| 155 |
+
recommendation = "good"
|
| 156 |
+
else:
|
| 157 |
+
recommendation = "not ideal"
|
| 158 |
+
|
| 159 |
+
return (
|
| 160 |
+
f"Stargazing Advisor for {resolved_city}:\n"
|
| 161 |
+
f"Forecast Date: {forecast_date}\n"
|
| 162 |
+
f"Sunrise: {sunrise}, Sunset: {sunset}\n"
|
| 163 |
+
f"Moon Phase: {moon_phase:.2f} (0=new, 0.5=full)\n"
|
| 164 |
+
f"Average Cloud Cover (midday): {cloudcover}%\n"
|
| 165 |
+
f"Tonight's stargazing conditions are {recommendation}."
|
| 166 |
+
)
|
| 167 |
+
except Exception as e:
|
| 168 |
+
return f"Error fetching forecast: {str(e)}"
|
| 169 |
|
| 170 |
final_answer = FinalAnswerTool()
|
| 171 |
|