feat(yandexweather): add yandexweather api
This commit is contained in:
@@ -18,9 +18,11 @@ from .parser import FORECAST_ITEM_PARSER
|
||||
logger = logging.getLogger("openweather")
|
||||
|
||||
|
||||
class OpenWeatherApi(WeatherApi):
|
||||
class OpenWeatherApi(WeatherApi[OpenWeather]):
|
||||
PROVIDER = "openweather"
|
||||
SOURCE = OpenWeather(environ["OPENWEATHER_KEY"])
|
||||
|
||||
def _build_source(self) -> OpenWeather:
|
||||
return OpenWeather(environ["OPENWEATHER_KEY"])
|
||||
|
||||
@classmethod
|
||||
def _parse_location(cls, location_id: str) -> tuple[float, float]:
|
||||
@@ -32,7 +34,7 @@ class OpenWeatherApi(WeatherApi):
|
||||
ttl=TimeUnit.DAY,
|
||||
)
|
||||
async def _get_location(self, location_id: str) -> OpenWeatherLocation:
|
||||
return await self.SOURCE.get_location(*self._parse_location(location_id))
|
||||
return await self.source.get_location(*self._parse_location(location_id))
|
||||
|
||||
@cached(
|
||||
key_builder=lambda fun, self, location_id: f"api.weather.{self.provider}.source.{location_id}.forecast",
|
||||
@@ -40,10 +42,10 @@ class OpenWeatherApi(WeatherApi):
|
||||
ttl=TimeUnit.HOUR,
|
||||
)
|
||||
async def _get_location_forecast(self, location_id: str) -> Forecast:
|
||||
return await self.SOURCE.get_forecast(*self._parse_location(location_id))
|
||||
return await self.source.get_forecast(*self._parse_location(location_id))
|
||||
|
||||
async def find_locations(self, query: str) -> list[Location]:
|
||||
result = await self.SOURCE.find_locations(query)
|
||||
result = await self.source.find_locations(query)
|
||||
return [
|
||||
Location(
|
||||
id=f"{item.lat}:{item.lon}",
|
||||
|
||||
@@ -76,28 +76,28 @@ class Location(Model):
|
||||
local_names: dict[str, str] | None = None
|
||||
|
||||
|
||||
class OpenWeather:
|
||||
class OpenWeather(ApiSource):
|
||||
BASE_URL = "https://api.openweathermap.org"
|
||||
|
||||
def __init__(self, api_key: str):
|
||||
self._api_key = api_key
|
||||
self._source = ApiSource(self.BASE_URL)
|
||||
super().__init__(self.BASE_URL)
|
||||
|
||||
async def get_forecast(self, lat: float, lon: float) -> Forecast:
|
||||
endpoint = f"data/2.5/forecast?lat={lat}&lon={lon}&appid={self._api_key}&units=metric"
|
||||
response = await self._source.request(endpoint)
|
||||
response = await self.request(endpoint)
|
||||
response_data = json.loads(response)
|
||||
return Forecast.model_validate(response_data)
|
||||
|
||||
async def find_locations(self, query: str, limit: int = 5) -> list[Location]:
|
||||
endpoint = f"geo/1.0/direct?q={query}&limit={limit}&appid={self._api_key}"
|
||||
response = await self._source.request(endpoint)
|
||||
response = await self.request(endpoint)
|
||||
response_data = json.loads(response)
|
||||
return [Location.model_validate(item) for item in response_data]
|
||||
|
||||
async def get_location(self, lat: float, lon: float) -> Location:
|
||||
limit = 1
|
||||
endpoint = f"geo/1.0/reverse?lat={lat}&lon={lon}&limit={limit}&appid={self._api_key}"
|
||||
response = await self._source.request(endpoint)
|
||||
response = await self.request(endpoint)
|
||||
response_data = json.loads(response)
|
||||
return Location.model_validate(response_data[0])
|
||||
|
||||
Reference in New Issue
Block a user