meteo-lt-pkg 0.5.0b0__py3-none-any.whl → 0.5.1__py3-none-any.whl

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.
meteo_lt/client.py CHANGED
@@ -93,35 +93,23 @@ class MeteoLtClient:
93
93
  session = await self._get_session()
94
94
  async with session.get(f"{BASE_URL}/hydro-stations") as resp:
95
95
  if resp.status == 200:
96
+ resp.encoding = ENCODING
96
97
  response = await resp.json()
97
98
  stations = []
98
99
  for station_data in response:
99
- stations.append(
100
- HydroStation(
101
- code=station_data.get("code"),
102
- name=station_data.get("name"),
103
- water_body=station_data.get("waterBody"),
104
- coordinates=station_data.get("coordinates", {}),
105
- )
106
- )
100
+ stations.append(HydroStation.from_dict(station_data))
107
101
  return stations
108
- else:
109
- raise Exception(f"API returned status {resp.status}")
102
+ raise aiohttp.ClientError(f"API returned status {resp.status}")
110
103
 
111
104
  async def fetch_hydro_station(self, station_code: str) -> HydroStation:
112
105
  """Get information about a specific hydrological station."""
113
106
  session = await self._get_session()
114
107
  async with session.get(f"{BASE_URL}/hydro-stations/{station_code}") as resp:
115
108
  if resp.status == 200:
109
+ resp.encoding = ENCODING
116
110
  response = await resp.json()
117
- return HydroStation(
118
- code=response.get("code"),
119
- name=response.get("name"),
120
- water_body=response.get("waterBody"),
121
- coordinates=response.get("coordinates", {}),
122
- )
123
- else:
124
- raise Exception(f"API returned status {resp.status}")
111
+ return HydroStation.from_dict(response)
112
+ raise aiohttp.ClientError(f"API returned status {resp.status}")
125
113
 
126
114
  async def fetch_hydro_observation_data(
127
115
  self,
@@ -136,28 +124,15 @@ class MeteoLtClient:
136
124
  ) as resp:
137
125
  if resp.status == 200:
138
126
  response = await resp.json()
139
- station = HydroStation(
140
- code=response["station"].get("code"),
141
- name=response["station"].get("name"),
142
- water_body=response["station"].get("waterBody"),
143
- coordinates=response["station"].get("coordinates", {}),
144
- )
127
+ station = HydroStation.from_dict(response.get("station"))
145
128
 
146
129
  observations = []
147
130
  for obs_data in response.get("observations", []):
148
- observations.append(
149
- HydroObservation(
150
- observation_datetime=obs_data.get("observationTimeUtc"),
151
- water_level=obs_data.get("waterLevel"),
152
- water_temperature=obs_data.get("waterTemperature"),
153
- water_discharge=obs_data.get("waterDischarge"),
154
- )
155
- )
131
+ observations.append(HydroObservation.from_dict(obs_data))
156
132
 
157
133
  return HydroObservationData(
158
134
  station=station,
159
135
  observations_data_range=response.get("observationsDataRange"),
160
136
  observations=observations,
161
137
  )
162
- else:
163
- raise Exception(f"API returned status {resp.status}")
138
+ raise aiohttp.ClientError(f"API returned status {resp.status}")
meteo_lt/models.py CHANGED
@@ -65,17 +65,17 @@ class WeatherWarning:
65
65
  class HydroStation(LocationBase):
66
66
  """Hydrological station data."""
67
67
 
68
- water_body: str
68
+ water_body: str = field(metadata={"json_key": "waterBody"})
69
69
 
70
70
 
71
71
  @dataclass
72
72
  class HydroObservation:
73
73
  """Single hydrological observation."""
74
74
 
75
- observation_datetime: Optional[str] = None
76
- water_level: Optional[float] = None # cm
77
- water_temperature: Optional[float] = None # °C
78
- water_discharge: Optional[float] = None # m3/s
75
+ observation_datetime: Optional[str] = field(default=None, metadata={"json_key": "observationTimeUtc"})
76
+ water_level: Optional[float] = field(default=None, metadata={"json_key": "waterLevel"}) # cm
77
+ water_temperature: Optional[float] = field(default=None, metadata={"json_key": "waterTemperature"}) # °C
78
+ water_discharge: Optional[float] = field(default=None, metadata={"json_key": "waterDischarge"}) # m3/s
79
79
 
80
80
 
81
81
  @dataclass
@@ -83,7 +83,7 @@ class HydroObservationData:
83
83
  """Observation data response."""
84
84
 
85
85
  station: HydroStation
86
- observations_data_range: Optional[dict] = None
86
+ observations_data_range: Optional[dict] = field(default=None, metadata={"json_key": "observationsDataRange"})
87
87
  observations: List[HydroObservation] = field(default_factory=list)
88
88
 
89
89
 
meteo_lt/utils.py CHANGED
@@ -1,9 +1,8 @@
1
1
  """utils.py"""
2
2
 
3
3
  from math import radians, sin, cos, sqrt, atan2
4
- from typing import TypeVar, List
5
-
6
- LocationT = TypeVar("LocationT") # Type variable for location objects with latitude/longitude
4
+ from typing import List
5
+ from meteo_lt.models import LocationBase
7
6
 
8
7
 
9
8
  def haversine(lat1: float, lon1: float, lat2: float, lon2: float) -> float:
@@ -20,7 +19,7 @@ def haversine(lat1: float, lon1: float, lat2: float, lon2: float) -> float:
20
19
  return r * c
21
20
 
22
21
 
23
- def find_nearest_location(latitude: float, longitude: float, locations: List[LocationT]) -> LocationT:
22
+ def find_nearest_location(latitude: float, longitude: float, locations: List[LocationBase]) -> LocationBase:
24
23
  """Find the nearest location from a list of locations based on the given latitude and longitude."""
25
24
  nearest_location = None
26
25
  min_distance = float("inf")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: meteo_lt-pkg
3
- Version: 0.5.0b0
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
@@ -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).
@@ -0,0 +1,12 @@
1
+ meteo_lt/__init__.py,sha256=HRQ5O9YMn6h2bXkhx6yuPF6voo6SiUZDrY8RZFeLaks,456
2
+ meteo_lt/api.py,sha256=TJrtP2ScPhT30QR9rHs2NzPibQgbkppMDrPh9JiyBoU,4086
3
+ meteo_lt/client.py,sha256=ubo4-jeIi_829xMhng_8hvPkO24UF1ZioGhu3bIIib8,5200
4
+ meteo_lt/const.py,sha256=Mz_8F5k_dVQlGNdYdGQOXqaEye4G5Z0xoBw971O8vBM,2690
5
+ meteo_lt/models.py,sha256=dWgYBwnvFPN6DjavlB4uD9kSCL7gcnw7CG-rUbz6z7w,6000
6
+ meteo_lt/utils.py,sha256=VhXWnqfeBdKrncrsIrSwzsiN3Sg4-kDG5v6Yz-PBOLc,1281
7
+ meteo_lt/warnings.py,sha256=6wYzinhBzXC3apR38LSEGPwsxiVTrVgLvDWql9-w0B0,6141
8
+ meteo_lt_pkg-0.5.1.dist-info/licenses/LICENSE,sha256=3IGi6xn6NUdXGvcdwD0MUbhy3Yz5NRnUjJrwKanFAD4,1073
9
+ meteo_lt_pkg-0.5.1.dist-info/METADATA,sha256=-5Qzyg9aX-QP8TVeZSaZrZpHb_ufYriz8_j-vaHiZzg,14432
10
+ meteo_lt_pkg-0.5.1.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
11
+ meteo_lt_pkg-0.5.1.dist-info/top_level.txt,sha256=-aEdc9FzHhcIH4_0TNdKNxuvDnS3chKoJy6LK9Ud-G4,9
12
+ meteo_lt_pkg-0.5.1.dist-info/RECORD,,
@@ -1,12 +0,0 @@
1
- meteo_lt/__init__.py,sha256=HRQ5O9YMn6h2bXkhx6yuPF6voo6SiUZDrY8RZFeLaks,456
2
- meteo_lt/api.py,sha256=TJrtP2ScPhT30QR9rHs2NzPibQgbkppMDrPh9JiyBoU,4086
3
- meteo_lt/client.py,sha256=LwFRr1GDuVoeFEKj31w0pwmPQegwM-o1prZdtOop5r0,6291
4
- meteo_lt/const.py,sha256=Mz_8F5k_dVQlGNdYdGQOXqaEye4G5Z0xoBw971O8vBM,2690
5
- meteo_lt/models.py,sha256=8mUQek55pVMxjuLheW6T8oGwinf0VJdkC1Y8cWv7TIo,5667
6
- meteo_lt/utils.py,sha256=D2SDbWx0o_iKwJP1tCrHLovWWmT0HUu4C9gNSQEmiDw,1339
7
- meteo_lt/warnings.py,sha256=6wYzinhBzXC3apR38LSEGPwsxiVTrVgLvDWql9-w0B0,6141
8
- meteo_lt_pkg-0.5.0b0.dist-info/licenses/LICENSE,sha256=3IGi6xn6NUdXGvcdwD0MUbhy3Yz5NRnUjJrwKanFAD4,1073
9
- meteo_lt_pkg-0.5.0b0.dist-info/METADATA,sha256=5fBukQnZvFbMZu6XQa4PRAZTxAwivyIFCipoz3uHHhY,10382
10
- meteo_lt_pkg-0.5.0b0.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
11
- meteo_lt_pkg-0.5.0b0.dist-info/top_level.txt,sha256=-aEdc9FzHhcIH4_0TNdKNxuvDnS3chKoJy6LK9Ud-G4,9
12
- meteo_lt_pkg-0.5.0b0.dist-info/RECORD,,