V2
This commit is contained in:
+102
@@ -0,0 +1,102 @@
|
||||
import os
|
||||
import requests
|
||||
import logging
|
||||
from collections import defaultdict
|
||||
from datetime import datetime
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
WEATHER_API_KEY = os.getenv("WEATHER_API_KEY")
|
||||
BASE_URL = "https://api.openweathermap.org/data/2.5"
|
||||
TIMEOUT = 10
|
||||
|
||||
def get_current_weather(city: str) -> dict:
|
||||
url = f"{BASE_URL}/weather"
|
||||
params = {
|
||||
"q": city,
|
||||
"appid": WEATHER_API_KEY,
|
||||
"units": "metric",
|
||||
"lang": "ru"
|
||||
}
|
||||
|
||||
try:
|
||||
response = requests.get(url, params=params, timeout=TIMEOUT)
|
||||
if response.status_code == 200:
|
||||
data = response.json()
|
||||
return {
|
||||
"success": True,
|
||||
"city": data["name"],
|
||||
"temp": data["main"]["temp"],
|
||||
"desc": data["weather"][0]["description"].capitalize()
|
||||
}
|
||||
elif response.status_code == 404:
|
||||
return {"success": False, "error": f"Город '{city}' не найден."}
|
||||
else:
|
||||
logger.error(f"API Error: Code {response.status_code} for city {city}")
|
||||
return {"success": False, "error": "Ошибка связи с сервером погоды."}
|
||||
except requests.exceptions.RequestException as e:
|
||||
logger.error(f"Request exception: {e}")
|
||||
return {"success": False, "error": "Превышено время ожидания или ошибка сети."}
|
||||
|
||||
def get_forecast(city: str, days: int) -> dict:
|
||||
url = f"{BASE_URL}/forecast"
|
||||
params = {
|
||||
"q": city,
|
||||
"appid": WEATHER_API_KEY,
|
||||
"units": "metric",
|
||||
"lang": "ru"
|
||||
}
|
||||
|
||||
try:
|
||||
response = requests.get(url, params=params, timeout=TIMEOUT)
|
||||
if response.status_code == 200:
|
||||
data = response.json()
|
||||
city_name = data["city"]["name"]
|
||||
|
||||
# Агрегация данных по дням
|
||||
daily_data = defaultdict(lambda: {"temps": [], "descs": []})
|
||||
|
||||
for item in data["list"]:
|
||||
# дата в формате 'YYYY-MM-DD HH:MM:SS'
|
||||
date_str = item["dt_txt"].split(" ")[0]
|
||||
daily_data[date_str]["temps"].append(item["main"]["temp"])
|
||||
daily_data[date_str]["descs"].append(item["weather"][0]["description"])
|
||||
|
||||
# Сортируем дни
|
||||
sorted_dates = sorted(daily_data.keys())
|
||||
|
||||
# Ограничиваем количество дней
|
||||
target_dates = sorted_dates[:days]
|
||||
|
||||
result = []
|
||||
for date_str in target_dates:
|
||||
temps = daily_data[date_str]["temps"]
|
||||
descs = daily_data[date_str]["descs"]
|
||||
|
||||
min_temp = min(temps)
|
||||
max_temp = max(temps)
|
||||
|
||||
# Самое частое описание погоды за день
|
||||
most_common_desc = max(set(descs), key=descs.count).capitalize()
|
||||
|
||||
# Перевод даты в читаемый формат
|
||||
date_obj = datetime.strptime(date_str, "%Y-%m-%d")
|
||||
formatted_date = date_obj.strftime("%d.%m.%Y")
|
||||
|
||||
result.append({
|
||||
"date": formatted_date,
|
||||
"min_temp": min_temp,
|
||||
"max_temp": max_temp,
|
||||
"desc": most_common_desc
|
||||
})
|
||||
|
||||
return {"success": True, "city": city_name, "forecast": result}
|
||||
|
||||
elif response.status_code == 404:
|
||||
return {"success": False, "error": f"Город '{city}' не найден."}
|
||||
else:
|
||||
logger.error(f"API Error (Forecast): Code {response.status_code} for city {city}")
|
||||
return {"success": False, "error": "Ошибка связи с сервером погоды."}
|
||||
except requests.exceptions.RequestException as e:
|
||||
logger.error(f"Request exception (Forecast): {e}")
|
||||
return {"success": False, "error": "Превышено время ожидания или ошибка сети."}
|
||||
Reference in New Issue
Block a user