meteo-lt-pkg 0.5.0__tar.gz → 0.5.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: meteo_lt-pkg
3
- Version: 0.5.0
3
+ Version: 0.5.1
4
4
  Summary: A library to fetch weather data from api.meteo.lt
5
5
  Author-email: Brunas <brunonas@gmail.com>
6
6
  Project-URL: Homepage, https://github.com/Brunas/meteo_lt-pkg
@@ -12,17 +12,17 @@ Classifier: Development Status :: 4 - Beta
12
12
  Requires-Python: >=3.10
13
13
  Description-Content-Type: text/markdown
14
14
  License-File: LICENSE
15
- Requires-Dist: aiohttp
15
+ Requires-Dist: aiohttp>=3.13
16
16
  Provides-Extra: dev
17
- Requires-Dist: pytest; extra == "dev"
18
- Requires-Dist: pytest-cov; extra == "dev"
19
- Requires-Dist: pytest-asyncio; extra == "dev"
20
- Requires-Dist: black; extra == "dev"
21
- Requires-Dist: coverage; extra == "dev"
22
- Requires-Dist: flake8; extra == "dev"
23
- Requires-Dist: pyflakes; extra == "dev"
24
- Requires-Dist: pylint; extra == "dev"
25
- Requires-Dist: build; extra == "dev"
17
+ Requires-Dist: pytest>=9.0; extra == "dev"
18
+ Requires-Dist: pytest-cov>=7.0; extra == "dev"
19
+ Requires-Dist: pytest-asyncio>=1.3; extra == "dev"
20
+ Requires-Dist: black>=26.0; extra == "dev"
21
+ Requires-Dist: coverage>=7.0; extra == "dev"
22
+ Requires-Dist: flake8>=7.0; extra == "dev"
23
+ Requires-Dist: pyflakes>=3.0; extra == "dev"
24
+ Requires-Dist: pylint>=4.0; extra == "dev"
25
+ Requires-Dist: build>=1.0; extra == "dev"
26
26
  Dynamic: license-file
27
27
 
28
28
  # Meteo.Lt Lithuanian weather forecast package
@@ -310,6 +310,136 @@ warning = WeatherWarning(
310
310
  print(f"Warning for {warning.county}: {warning.description}")
311
311
  ```
312
312
 
313
+ ### HydroStation
314
+
315
+ Represents a hydrological observation station with water body information.
316
+
317
+ ```python
318
+ from meteo_lt import HydroStation
319
+
320
+ station = HydroStation(
321
+ code="klaipedos-juru-uosto-vms",
322
+ name="Klaipėdos jūrų uosto VMS",
323
+ water_body="Baltijos jūra",
324
+ coordinates=coords
325
+ )
326
+ print(f"Station: {station.name} on {station.water_body}")
327
+ ```
328
+
329
+ ### HydroObservation
330
+
331
+ Represents a single hydrological observation with water measurements.
332
+
333
+ ```python
334
+ from meteo_lt import HydroObservation
335
+
336
+ observation = HydroObservation(
337
+ observation_datetime="2024-07-23T12:00:00+00:00",
338
+ water_level=481.8,
339
+ water_temperature=15.5,
340
+ water_discharge=100.0
341
+ )
342
+ print(f"Water level: {observation.water_level} cm")
343
+ print(f"Water temperature: {observation.water_temperature}°C")
344
+ ```
345
+
346
+ ### HydroObservationData
347
+
348
+ Represents a collection of hydrological observations for a specific station.
349
+
350
+ ```python
351
+ from meteo_lt import HydroObservationData
352
+
353
+ data = HydroObservationData(
354
+ station=station,
355
+ observations=[observation],
356
+ observations_data_range={"from": "2024-07-01", "to": "2024-07-23"}
357
+ )
358
+ print(f"Station: {data.station.name}")
359
+ print(f"Observations: {len(data.observations)}")
360
+ ```
361
+
362
+ ## Hydrological Data
363
+
364
+ The package provides access to hydrological data from Lithuanian water monitoring stations.
365
+
366
+ ### Fetching Hydrological Stations
367
+
368
+ To get the list of all hydrological stations:
369
+
370
+ ```python
371
+ async def fetch_hydro_stations():
372
+ async with MeteoLtAPI() as api:
373
+ stations = await api.get_hydro_stations()
374
+ for station in stations:
375
+ print(f"{station.name} ({station.code}) - Water body: {station.water_body}")
376
+
377
+ asyncio.run(fetch_hydro_stations())
378
+ ```
379
+
380
+ ### Finding the Nearest Hydrological Station
381
+
382
+ You can find the nearest hydrological station using coordinates:
383
+
384
+ ```python
385
+ async def find_nearest_hydro_station():
386
+ async with MeteoLtAPI() as api:
387
+ # Example coordinates for Klaipėda, Lithuania
388
+ nearest_station = await api.get_nearest_hydro_station(55.6872, 21.2797)
389
+ print(f"Nearest station: {nearest_station.name}")
390
+ print(f"Water body: {nearest_station.water_body}")
391
+ print(f"Distance: approximately {nearest_station.latitude}, {nearest_station.longitude}")
392
+
393
+ asyncio.run(find_nearest_hydro_station())
394
+ ```
395
+
396
+ ### Fetching Hydrological Observations
397
+
398
+ To get water level and temperature observations for a specific station:
399
+
400
+ ```python
401
+ async def fetch_hydro_observations():
402
+ async with MeteoLtAPI() as api:
403
+ # Get observations for a station
404
+ hydro_data = await api.get_hydro_observation_data("klaipedos-juru-uosto-vms")
405
+
406
+ print(f"Station: {hydro_data.station.name}")
407
+ print(f"Water body: {hydro_data.station.water_body}")
408
+ print(f"\nRecent observations:")
409
+
410
+ for observation in hydro_data.observations[:5]:
411
+ print(f" {observation.observation_datetime}")
412
+ print(f" Water level: {observation.water_level} cm")
413
+ print(f" Water temperature: {observation.water_temperature}°C")
414
+ if observation.water_discharge:
415
+ print(f" Water discharge: {observation.water_discharge} m³/s")
416
+
417
+ asyncio.run(fetch_hydro_observations())
418
+ ```
419
+
420
+ ### Getting Observations for Nearest Station
421
+
422
+ Combine location finding with observation fetching:
423
+
424
+ ```python
425
+ async def get_nearest_station_observations():
426
+ async with MeteoLtAPI() as api:
427
+ # Find nearest hydro station to coordinates
428
+ nearest_station = await api.get_nearest_hydro_station(55.6872, 21.2797)
429
+
430
+ # Get observations for the nearest station
431
+ hydro_data = await api.get_hydro_observation_data(nearest_station.code)
432
+
433
+ print(f"Latest observations from {hydro_data.station.name}:")
434
+ if hydro_data.observations:
435
+ latest = hydro_data.observations[0]
436
+ print(f" Time: {latest.observation_datetime}")
437
+ print(f" Water level: {latest.water_level} cm")
438
+ print(f" Temperature: {latest.water_temperature}°C")
439
+
440
+ asyncio.run(get_nearest_station_observations())
441
+ ```
442
+
313
443
  ## Contributing
314
444
 
315
445
  Contributions are welcome! For major changes please open an issue to discuss or submit a pull request with your changes. If you want to contribute you can use devcontainers in vscode for easiest setup follow [instructions here](.devcontainer/README.md).
@@ -1,30 +1,3 @@
1
- Metadata-Version: 2.4
2
- Name: meteo_lt-pkg
3
- Version: 0.5.0
4
- Summary: A library to fetch weather data from api.meteo.lt
5
- Author-email: Brunas <brunonas@gmail.com>
6
- Project-URL: Homepage, https://github.com/Brunas/meteo_lt-pkg
7
- Project-URL: Issues, https://github.com/Brunas/meteo_lt-pkg/issues
8
- Classifier: Programming Language :: Python :: 3
9
- Classifier: License :: OSI Approved :: MIT License
10
- Classifier: Operating System :: OS Independent
11
- Classifier: Development Status :: 4 - Beta
12
- Requires-Python: >=3.10
13
- Description-Content-Type: text/markdown
14
- License-File: LICENSE
15
- Requires-Dist: aiohttp
16
- Provides-Extra: dev
17
- Requires-Dist: pytest; extra == "dev"
18
- Requires-Dist: pytest-cov; extra == "dev"
19
- Requires-Dist: pytest-asyncio; extra == "dev"
20
- Requires-Dist: black; extra == "dev"
21
- Requires-Dist: coverage; extra == "dev"
22
- Requires-Dist: flake8; extra == "dev"
23
- Requires-Dist: pyflakes; extra == "dev"
24
- Requires-Dist: pylint; extra == "dev"
25
- Requires-Dist: build; extra == "dev"
26
- Dynamic: license-file
27
-
28
1
  # Meteo.Lt Lithuanian weather forecast package
29
2
 
30
3
  [![GitHub Release][releases-shield]][releases]
@@ -310,6 +283,136 @@ warning = WeatherWarning(
310
283
  print(f"Warning for {warning.county}: {warning.description}")
311
284
  ```
312
285
 
286
+ ### HydroStation
287
+
288
+ Represents a hydrological observation station with water body information.
289
+
290
+ ```python
291
+ from meteo_lt import HydroStation
292
+
293
+ station = HydroStation(
294
+ code="klaipedos-juru-uosto-vms",
295
+ name="Klaipėdos jūrų uosto VMS",
296
+ water_body="Baltijos jūra",
297
+ coordinates=coords
298
+ )
299
+ print(f"Station: {station.name} on {station.water_body}")
300
+ ```
301
+
302
+ ### HydroObservation
303
+
304
+ Represents a single hydrological observation with water measurements.
305
+
306
+ ```python
307
+ from meteo_lt import HydroObservation
308
+
309
+ observation = HydroObservation(
310
+ observation_datetime="2024-07-23T12:00:00+00:00",
311
+ water_level=481.8,
312
+ water_temperature=15.5,
313
+ water_discharge=100.0
314
+ )
315
+ print(f"Water level: {observation.water_level} cm")
316
+ print(f"Water temperature: {observation.water_temperature}°C")
317
+ ```
318
+
319
+ ### HydroObservationData
320
+
321
+ Represents a collection of hydrological observations for a specific station.
322
+
323
+ ```python
324
+ from meteo_lt import HydroObservationData
325
+
326
+ data = HydroObservationData(
327
+ station=station,
328
+ observations=[observation],
329
+ observations_data_range={"from": "2024-07-01", "to": "2024-07-23"}
330
+ )
331
+ print(f"Station: {data.station.name}")
332
+ print(f"Observations: {len(data.observations)}")
333
+ ```
334
+
335
+ ## Hydrological Data
336
+
337
+ The package provides access to hydrological data from Lithuanian water monitoring stations.
338
+
339
+ ### Fetching Hydrological Stations
340
+
341
+ To get the list of all hydrological stations:
342
+
343
+ ```python
344
+ async def fetch_hydro_stations():
345
+ async with MeteoLtAPI() as api:
346
+ stations = await api.get_hydro_stations()
347
+ for station in stations:
348
+ print(f"{station.name} ({station.code}) - Water body: {station.water_body}")
349
+
350
+ asyncio.run(fetch_hydro_stations())
351
+ ```
352
+
353
+ ### Finding the Nearest Hydrological Station
354
+
355
+ You can find the nearest hydrological station using coordinates:
356
+
357
+ ```python
358
+ async def find_nearest_hydro_station():
359
+ async with MeteoLtAPI() as api:
360
+ # Example coordinates for Klaipėda, Lithuania
361
+ nearest_station = await api.get_nearest_hydro_station(55.6872, 21.2797)
362
+ print(f"Nearest station: {nearest_station.name}")
363
+ print(f"Water body: {nearest_station.water_body}")
364
+ print(f"Distance: approximately {nearest_station.latitude}, {nearest_station.longitude}")
365
+
366
+ asyncio.run(find_nearest_hydro_station())
367
+ ```
368
+
369
+ ### Fetching Hydrological Observations
370
+
371
+ To get water level and temperature observations for a specific station:
372
+
373
+ ```python
374
+ async def fetch_hydro_observations():
375
+ async with MeteoLtAPI() as api:
376
+ # Get observations for a station
377
+ hydro_data = await api.get_hydro_observation_data("klaipedos-juru-uosto-vms")
378
+
379
+ print(f"Station: {hydro_data.station.name}")
380
+ print(f"Water body: {hydro_data.station.water_body}")
381
+ print(f"\nRecent observations:")
382
+
383
+ for observation in hydro_data.observations[:5]:
384
+ print(f" {observation.observation_datetime}")
385
+ print(f" Water level: {observation.water_level} cm")
386
+ print(f" Water temperature: {observation.water_temperature}°C")
387
+ if observation.water_discharge:
388
+ print(f" Water discharge: {observation.water_discharge} m³/s")
389
+
390
+ asyncio.run(fetch_hydro_observations())
391
+ ```
392
+
393
+ ### Getting Observations for Nearest Station
394
+
395
+ Combine location finding with observation fetching:
396
+
397
+ ```python
398
+ async def get_nearest_station_observations():
399
+ async with MeteoLtAPI() as api:
400
+ # Find nearest hydro station to coordinates
401
+ nearest_station = await api.get_nearest_hydro_station(55.6872, 21.2797)
402
+
403
+ # Get observations for the nearest station
404
+ hydro_data = await api.get_hydro_observation_data(nearest_station.code)
405
+
406
+ print(f"Latest observations from {hydro_data.station.name}:")
407
+ if hydro_data.observations:
408
+ latest = hydro_data.observations[0]
409
+ print(f" Time: {latest.observation_datetime}")
410
+ print(f" Water level: {latest.water_level} cm")
411
+ print(f" Temperature: {latest.water_temperature}°C")
412
+
413
+ asyncio.run(get_nearest_station_observations())
414
+ ```
415
+
313
416
  ## Contributing
314
417
 
315
418
  Contributions are welcome! For major changes please open an issue to discuss or submit a pull request with your changes. If you want to contribute you can use devcontainers in vscode for easiest setup follow [instructions here](.devcontainer/README.md).
@@ -321,4 +424,4 @@ Contributions are welcome! For major changes please open an issue to discuss or
321
424
  [license-shield]: https://img.shields.io/github/license/Brunas/meteo_lt-pkg.svg?style=flat-square
322
425
  [maintenance-shield]: https://img.shields.io/badge/maintainer-Brunas%20%40Brunas-blue.svg?style=flat-square
323
426
  [releases-shield]: https://img.shields.io/github/release/Brunas/meteo_lt-pkg.svg?style=flat-square
324
- [releases]: https://github.com/Brunas/meteo_lt-pkg/releases
427
+ [releases]: https://github.com/Brunas/meteo_lt-pkg/releases
@@ -0,0 +1,27 @@
1
+ """init.py"""
2
+
3
+ from .api import MeteoLtAPI
4
+ from .models import (
5
+ Coordinates,
6
+ LocationBase,
7
+ Place,
8
+ ForecastTimestamp,
9
+ Forecast,
10
+ WeatherWarning,
11
+ HydroStation,
12
+ HydroObservation,
13
+ HydroObservationData,
14
+ )
15
+
16
+ __all__ = [
17
+ "MeteoLtAPI",
18
+ "Coordinates",
19
+ "LocationBase",
20
+ "Place",
21
+ "ForecastTimestamp",
22
+ "Forecast",
23
+ "WeatherWarning",
24
+ "HydroStation",
25
+ "HydroObservation",
26
+ "HydroObservationData",
27
+ ]
@@ -0,0 +1,109 @@
1
+ """Main API class script"""
2
+
3
+ from typing import List, Optional
4
+
5
+ from .models import (
6
+ Forecast,
7
+ Place,
8
+ WeatherWarning,
9
+ HydroStation,
10
+ HydroObservationData,
11
+ )
12
+ from .utils import find_nearest_location
13
+ from .client import MeteoLtClient
14
+ from .warnings import WeatherWarningsProcessor
15
+
16
+
17
+ class MeteoLtAPI:
18
+ """Main API class that orchestrates external API calls and warning processing"""
19
+
20
+ def __init__(self, session=None):
21
+ self.places = []
22
+ self.client = MeteoLtClient(session)
23
+ self.warnings_processor = WeatherWarningsProcessor(self.client)
24
+
25
+ async def __aenter__(self):
26
+ """Async context manager entry"""
27
+ await self.client.__aenter__()
28
+ return self
29
+
30
+ async def __aexit__(
31
+ self,
32
+ exc_type: Optional[type],
33
+ exc_val: Optional[Exception],
34
+ exc_tb: Optional[object],
35
+ ) -> None:
36
+ """Async context manager exit"""
37
+ await self.client.__aexit__(exc_type, exc_val, exc_tb)
38
+
39
+ async def close(self):
40
+ """Close the API client and cleanup resources"""
41
+ await self.client.close()
42
+
43
+ async def fetch_places(self) -> None:
44
+ """Gets all places from API"""
45
+ self.places = await self.client.fetch_places()
46
+
47
+ async def get_nearest_place(self, latitude: float, longitude: float) -> Optional[Place]:
48
+ """Finds nearest place using provided coordinates"""
49
+ if not self.places:
50
+ await self.fetch_places()
51
+ return find_nearest_location(latitude, longitude, self.places)
52
+
53
+ async def get_forecast_with_warnings(
54
+ self,
55
+ latitude: Optional[float] = None,
56
+ longitude: Optional[float] = None,
57
+ place_code: Optional[str] = None,
58
+ ) -> Forecast:
59
+ """Get forecast with weather warnings for a location"""
60
+ if place_code is None:
61
+ if latitude is None or longitude is None:
62
+ raise ValueError("Either place_code or both latitude and longitude must be provided")
63
+ place = await self.get_nearest_place(latitude, longitude)
64
+ place_code = place.code
65
+
66
+ return await self.get_forecast(place_code, include_warnings=True)
67
+
68
+ async def get_forecast(self, place_code: str, include_warnings: bool = True) -> Forecast:
69
+ """Retrieves forecast data from API"""
70
+ forecast = await self.client.fetch_forecast(place_code)
71
+
72
+ if include_warnings:
73
+ await self._enrich_forecast_with_warnings(forecast)
74
+
75
+ return forecast
76
+
77
+ async def get_weather_warnings(self, administrative_division: str = None) -> List[WeatherWarning]:
78
+ """Fetches weather warnings from meteo.lt JSON API"""
79
+ return await self.warnings_processor.get_weather_warnings(administrative_division)
80
+
81
+ async def _enrich_forecast_with_warnings(self, forecast: Forecast) -> None:
82
+ """Enrich forecast timestamps with relevant weather warnings"""
83
+ if not forecast or not forecast.place or not forecast.place.administrative_division:
84
+ return
85
+
86
+ warnings = await self.get_weather_warnings(forecast.place.administrative_division)
87
+
88
+ if warnings:
89
+ self.warnings_processor.enrich_forecast_with_warnings(forecast, warnings)
90
+
91
+ async def get_hydro_stations(self) -> List[HydroStation]:
92
+ """Get list of all hydrological stations"""
93
+ return await self.client.fetch_hydro_stations()
94
+
95
+ async def get_nearest_hydro_station(self, latitude: float, longitude: float) -> Optional[HydroStation]:
96
+ """Find the nearest hydrological station to given coordinates"""
97
+ stations = await self.get_hydro_stations()
98
+ if not stations:
99
+ return None
100
+ return find_nearest_location(latitude, longitude, stations)
101
+
102
+ async def get_hydro_observation_data(
103
+ self,
104
+ station_code: str,
105
+ observation_type: str = "measured",
106
+ date: str = "latest",
107
+ ) -> HydroObservationData:
108
+ """Get hydrological observation data for a station"""
109
+ return await self.client.fetch_hydro_observation_data(station_code, observation_type, date)
@@ -0,0 +1,138 @@
1
+ """MeteoLt API client for external API calls"""
2
+
3
+ import json
4
+ from typing import List, Optional, Dict, Any
5
+
6
+ import aiohttp
7
+
8
+ from .models import (
9
+ Place,
10
+ Forecast,
11
+ HydroStation,
12
+ HydroObservationData,
13
+ HydroObservation,
14
+ )
15
+ from .const import BASE_URL, WARNINGS_URL, TIMEOUT, ENCODING
16
+
17
+
18
+ class MeteoLtClient:
19
+ """Client for external API calls to meteo.lt"""
20
+
21
+ def __init__(self, session: Optional[aiohttp.ClientSession] = None):
22
+ self._session = session
23
+ self._owns_session = session is None
24
+
25
+ async def __aenter__(self):
26
+ """Async context manager entry"""
27
+ if self._session is None:
28
+ self._session = aiohttp.ClientSession(
29
+ timeout=aiohttp.ClientTimeout(total=TIMEOUT),
30
+ raise_for_status=True,
31
+ )
32
+ return self
33
+
34
+ async def __aexit__(
35
+ self,
36
+ exc_type: Optional[type],
37
+ exc_val: Optional[Exception],
38
+ exc_tb: Optional[Any],
39
+ ) -> None:
40
+ """Async context manager exit"""
41
+ await self.close()
42
+
43
+ async def close(self) -> None:
44
+ """Close the client session if we own it"""
45
+ if self._session and self._owns_session:
46
+ await self._session.close()
47
+ self._session = None
48
+
49
+ async def _get_session(self) -> aiohttp.ClientSession:
50
+ """Get or create a session"""
51
+ if self._session is None:
52
+ self._session = aiohttp.ClientSession(
53
+ timeout=aiohttp.ClientTimeout(total=TIMEOUT),
54
+ raise_for_status=True,
55
+ )
56
+ return self._session
57
+
58
+ async def fetch_places(self) -> List[Place]:
59
+ """Gets all places from API"""
60
+ session = await self._get_session()
61
+ async with session.get(f"{BASE_URL}/places") as response:
62
+ response.encoding = ENCODING
63
+ response_json = await response.json()
64
+ return [Place.from_dict(place) for place in response_json]
65
+
66
+ async def fetch_forecast(self, place_code: str) -> Forecast:
67
+ """Retrieves forecast data from API"""
68
+ session = await self._get_session()
69
+ async with session.get(f"{BASE_URL}/places/{place_code}/forecasts/long-term") as response:
70
+ response.encoding = ENCODING
71
+ response_json = await response.json()
72
+ return Forecast.from_dict(response_json)
73
+
74
+ async def fetch_weather_warnings(self) -> Dict[str, Any]:
75
+ """Fetches raw weather warnings data from meteo.lt JSON API"""
76
+ session = await self._get_session()
77
+
78
+ # Get the latest warnings file
79
+ async with session.get(WARNINGS_URL) as response:
80
+ file_list = await response.json()
81
+
82
+ if not file_list:
83
+ return []
84
+
85
+ # Fetch the latest warnings data
86
+ latest_file_url = file_list[0] # First file is the most recent
87
+ async with session.get(latest_file_url) as response:
88
+ text_data = await response.text()
89
+ return json.loads(text_data)
90
+
91
+ async def fetch_hydro_stations(self) -> List[HydroStation]:
92
+ """Get list of all hydrological stations."""
93
+ session = await self._get_session()
94
+ async with session.get(f"{BASE_URL}/hydro-stations") as resp:
95
+ if resp.status == 200:
96
+ resp.encoding = ENCODING
97
+ response = await resp.json()
98
+ stations = []
99
+ for station_data in response:
100
+ stations.append(HydroStation.from_dict(station_data))
101
+ return stations
102
+ raise aiohttp.ClientError(f"API returned status {resp.status}")
103
+
104
+ async def fetch_hydro_station(self, station_code: str) -> HydroStation:
105
+ """Get information about a specific hydrological station."""
106
+ session = await self._get_session()
107
+ async with session.get(f"{BASE_URL}/hydro-stations/{station_code}") as resp:
108
+ if resp.status == 200:
109
+ resp.encoding = ENCODING
110
+ response = await resp.json()
111
+ return HydroStation.from_dict(response)
112
+ raise aiohttp.ClientError(f"API returned status {resp.status}")
113
+
114
+ async def fetch_hydro_observation_data(
115
+ self,
116
+ station_code: str,
117
+ observation_type: str = "measured",
118
+ date: str = "latest",
119
+ ) -> HydroObservationData:
120
+ """Get hydrological observation data for a station."""
121
+ session = await self._get_session()
122
+ async with session.get(
123
+ f"{BASE_URL}/hydro-stations/{station_code}/observations/{observation_type}/{date}"
124
+ ) as resp:
125
+ if resp.status == 200:
126
+ response = await resp.json()
127
+ station = HydroStation.from_dict(response.get("station"))
128
+
129
+ observations = []
130
+ for obs_data in response.get("observations", []):
131
+ observations.append(HydroObservation.from_dict(obs_data))
132
+
133
+ return HydroObservationData(
134
+ station=station,
135
+ observations_data_range=response.get("observationsDataRange"),
136
+ observations=observations,
137
+ )
138
+ raise aiohttp.ClientError(f"API returned status {resp.status}")
@@ -1,10 +1,7 @@
1
1
  """const.py"""
2
2
 
3
3
  BASE_URL = "https://api.meteo.lt/v1"
4
- WARNINGS_URL = (
5
- "https://www.meteo.lt/app/mu-plugins/Meteo/Components/"
6
- "WeatherWarningsNew/list_JSON.php"
7
- )
4
+ WARNINGS_URL = "https://www.meteo.lt/app/mu-plugins/Meteo/Components/" "WeatherWarningsNew/list_JSON.php"
8
5
  TIMEOUT = 30
9
6
  ENCODING = "utf-8"
10
7