95 lines
3.5 KiB
Python
95 lines
3.5 KiB
Python
import requests
|
|
|
|
|
|
def get_local_weather(
|
|
fallback_lat=40.59,
|
|
fallback_lon=-74.62,
|
|
fallback_city="Bridgewater",
|
|
fallback_region="New Jersey",
|
|
fallback_country_code="US"
|
|
):
|
|
"""
|
|
Fetches the user's current location and automatically determines
|
|
whether to return Metric or Imperial units based on their country.
|
|
"""
|
|
lat, lon = fallback_lat, fallback_lon
|
|
city, region = fallback_city, fallback_region
|
|
country_code = fallback_country_code
|
|
|
|
# Geolocation Lookup
|
|
try:
|
|
geo_url = "http://ip-api.com/json"
|
|
geo_response = requests.get(geo_url, timeout=5).json()
|
|
|
|
if geo_response.get("status") == "success":
|
|
lat = geo_response["lat"]
|
|
lon = geo_response["lon"]
|
|
city = geo_response["city"]
|
|
region = geo_response["regionName"]
|
|
country_code = geo_response.get("countryCode", "US")
|
|
else:
|
|
print("IP lookup API returned an error status. Using fallback coordinates.")
|
|
except Exception:
|
|
print("Network error during IP lookup. Using fallback coordinates.")
|
|
|
|
# Unit System 'n Weather URL
|
|
is_imperial = country_code in ["US", "LR", "MM"]
|
|
|
|
unit_suffix = ""
|
|
if is_imperial:
|
|
unit_suffix = "&temperature_unit=fahrenheit&precipitation_unit=inch"
|
|
|
|
weather_url = (
|
|
f"https://api.open-meteo.com/v1/forecast?"
|
|
f"latitude={lat}&longitude={lon}"
|
|
f"¤t=temperature_2m,precipitation,cloud_cover"
|
|
f"&daily=temperature_2m_max,temperature_2m_min"
|
|
f"&timezone=auto"
|
|
f"{unit_suffix}"
|
|
)
|
|
|
|
try:
|
|
response = requests.get(weather_url, timeout=5)
|
|
|
|
if response.status_code == 200:
|
|
data = response.json()
|
|
current = data["current"]
|
|
daily = data["daily"]
|
|
|
|
temp_unit = "°F" if is_imperial else "°C"
|
|
precip_unit = "inch" if is_imperial else "mm"
|
|
|
|
return {
|
|
"location": {
|
|
"city": city,
|
|
"region": region,
|
|
"country_code": country_code,
|
|
"lat": lat,
|
|
"lon": lon
|
|
},
|
|
"unit_system": "imperial" if is_imperial else "metric",
|
|
"units": {"temp": temp_unit, "precipitation": precip_unit},
|
|
"current_temp": current['temperature_2m'],
|
|
"high_temp": daily['temperature_2m_max'][0],
|
|
"low_temp": daily['temperature_2m_min'][0],
|
|
"precipitation": current['precipitation'],
|
|
"cloud_cover_pct": current['cloud_cover']
|
|
}
|
|
else:
|
|
print(f"Weather API returned error code: {response.status_code}")
|
|
return None
|
|
|
|
except Exception as e:
|
|
print(f"Network error while fetching weather: {e}")
|
|
return None
|
|
|
|
if __name__ == "__main__":
|
|
# Test block
|
|
weather_data = get_local_weather()
|
|
if weather_data:
|
|
u = weather_data["units"]
|
|
print(f"\n--- Location: {weather_data['location']['city']}, {weather_data['location']['region']} ({weather_data['location']['country_code']}) ---")
|
|
print(f"System Chosen: {weather_data['unit_system'].upper()}")
|
|
print(f"Current Temperature: {weather_data['current_temp']}{u['temp']}")
|
|
print(f"Today's High: {weather_data['high_temp']}{u['temp']}")
|
|
print(f"Precipitation: {weather_data['precipitation']} {u['precipitation']}") |