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 +9 -34
- meteo_lt/models.py +6 -6
- meteo_lt/utils.py +3 -4
- {meteo_lt_pkg-0.5.0b0.dist-info → meteo_lt_pkg-0.5.1.dist-info}/METADATA +131 -1
- meteo_lt_pkg-0.5.1.dist-info/RECORD +12 -0
- meteo_lt_pkg-0.5.0b0.dist-info/RECORD +0 -12
- {meteo_lt_pkg-0.5.0b0.dist-info → meteo_lt_pkg-0.5.1.dist-info}/WHEEL +0 -0
- {meteo_lt_pkg-0.5.0b0.dist-info → meteo_lt_pkg-0.5.1.dist-info}/licenses/LICENSE +0 -0
- {meteo_lt_pkg-0.5.0b0.dist-info → meteo_lt_pkg-0.5.1.dist-info}/top_level.txt +0 -0
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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[
|
|
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.
|
|
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,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|