meteostat 1.7.6__tar.gz → 2.0.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.
- meteostat-2.0.1/PKG-INFO +130 -0
- meteostat-2.0.1/README.md +113 -0
- meteostat-2.0.1/meteostat/__init__.py +54 -0
- meteostat-2.0.1/meteostat/api/config.py +158 -0
- meteostat-2.0.1/meteostat/api/daily.py +76 -0
- meteostat-2.0.1/meteostat/api/hourly.py +80 -0
- meteostat-2.0.1/meteostat/api/interpolate.py +378 -0
- meteostat-2.0.1/meteostat/api/inventory.py +59 -0
- meteostat-2.0.1/meteostat/api/merge.py +103 -0
- meteostat-2.0.1/meteostat/api/monthly.py +73 -0
- meteostat-2.0.1/meteostat/api/normals.py +144 -0
- meteostat-2.0.1/meteostat/api/point.py +30 -0
- meteostat-2.0.1/meteostat/api/stations.py +234 -0
- meteostat-2.0.1/meteostat/api/timeseries.py +334 -0
- meteostat-2.0.1/meteostat/core/cache.py +224 -0
- meteostat-2.0.1/meteostat/core/data.py +203 -0
- meteostat-2.0.1/meteostat/core/logger.py +9 -0
- meteostat-2.0.1/meteostat/core/network.py +82 -0
- meteostat-2.0.1/meteostat/core/parameters.py +112 -0
- meteostat-2.0.1/meteostat/core/providers.py +184 -0
- meteostat-2.0.1/meteostat/core/schema.py +170 -0
- meteostat-2.0.1/meteostat/core/validator.py +38 -0
- meteostat-2.0.1/meteostat/enumerations.py +149 -0
- meteostat-2.0.1/meteostat/interpolation/idw.py +120 -0
- meteostat-2.0.1/meteostat/interpolation/lapserate.py +91 -0
- meteostat-2.0.1/meteostat/interpolation/nearest.py +31 -0
- meteostat-2.0.1/meteostat/parameters.py +354 -0
- meteostat-2.0.1/meteostat/providers/dwd/climat.py +166 -0
- meteostat-2.0.1/meteostat/providers/dwd/daily.py +144 -0
- meteostat-2.0.1/meteostat/providers/dwd/hourly.py +218 -0
- meteostat-2.0.1/meteostat/providers/dwd/monthly.py +138 -0
- meteostat-2.0.1/meteostat/providers/dwd/mosmix.py +351 -0
- meteostat-2.0.1/meteostat/providers/dwd/poi.py +117 -0
- meteostat-2.0.1/meteostat/providers/dwd/shared.py +155 -0
- meteostat-2.0.1/meteostat/providers/eccc/daily.py +87 -0
- meteostat-2.0.1/meteostat/providers/eccc/hourly.py +104 -0
- meteostat-2.0.1/meteostat/providers/eccc/monthly.py +66 -0
- meteostat-2.0.1/meteostat/providers/eccc/shared.py +45 -0
- meteostat-2.0.1/meteostat/providers/index.py +496 -0
- meteostat-2.0.1/meteostat/providers/meteostat/daily.py +65 -0
- meteostat-2.0.1/meteostat/providers/meteostat/daily_derived.py +110 -0
- meteostat-2.0.1/meteostat/providers/meteostat/hourly.py +66 -0
- meteostat-2.0.1/meteostat/providers/meteostat/monthly.py +45 -0
- meteostat-2.0.1/meteostat/providers/meteostat/monthly_derived.py +106 -0
- meteostat-2.0.1/meteostat/providers/meteostat/shared.py +93 -0
- meteostat-2.0.1/meteostat/providers/metno/forecast.py +186 -0
- meteostat-2.0.1/meteostat/providers/noaa/ghcnd.py +228 -0
- meteostat-2.0.1/meteostat/providers/noaa/isd_lite.py +142 -0
- meteostat-2.0.1/meteostat/providers/noaa/metar.py +163 -0
- meteostat-2.0.1/meteostat/typing.py +113 -0
- meteostat-2.0.1/meteostat/utils/conversions.py +231 -0
- meteostat-2.0.1/meteostat/utils/data.py +194 -0
- meteostat-2.0.1/meteostat/utils/geo.py +28 -0
- meteostat-2.0.1/meteostat/utils/guards.py +51 -0
- meteostat-2.0.1/meteostat/utils/parsers.py +161 -0
- meteostat-2.0.1/meteostat/utils/types.py +113 -0
- meteostat-2.0.1/meteostat/utils/validators.py +31 -0
- meteostat-2.0.1/pyproject.toml +29 -0
- meteostat-1.7.6/PKG-INFO +0 -109
- meteostat-1.7.6/README.md +0 -89
- meteostat-1.7.6/meteostat/__init__.py +0 -35
- meteostat-1.7.6/meteostat/core/cache.py +0 -71
- meteostat-1.7.6/meteostat/core/loader.py +0 -103
- meteostat-1.7.6/meteostat/core/warn.py +0 -34
- meteostat-1.7.6/meteostat/enumerations/granularity.py +0 -22
- meteostat-1.7.6/meteostat/interface/base.py +0 -39
- meteostat-1.7.6/meteostat/interface/daily.py +0 -118
- meteostat-1.7.6/meteostat/interface/hourly.py +0 -154
- meteostat-1.7.6/meteostat/interface/meteodata.py +0 -210
- meteostat-1.7.6/meteostat/interface/monthly.py +0 -109
- meteostat-1.7.6/meteostat/interface/normals.py +0 -245
- meteostat-1.7.6/meteostat/interface/point.py +0 -143
- meteostat-1.7.6/meteostat/interface/stations.py +0 -252
- meteostat-1.7.6/meteostat/interface/timeseries.py +0 -237
- meteostat-1.7.6/meteostat/series/aggregate.py +0 -48
- meteostat-1.7.6/meteostat/series/convert.py +0 -28
- meteostat-1.7.6/meteostat/series/count.py +0 -17
- meteostat-1.7.6/meteostat/series/coverage.py +0 -20
- meteostat-1.7.6/meteostat/series/fetch.py +0 -28
- meteostat-1.7.6/meteostat/series/interpolate.py +0 -47
- meteostat-1.7.6/meteostat/series/normalize.py +0 -76
- meteostat-1.7.6/meteostat/series/stations.py +0 -22
- meteostat-1.7.6/meteostat/units.py +0 -149
- meteostat-1.7.6/meteostat/utilities/__init__.py +0 -0
- meteostat-1.7.6/meteostat/utilities/aggregations.py +0 -37
- meteostat-1.7.6/meteostat/utilities/endpoint.py +0 -33
- meteostat-1.7.6/meteostat/utilities/helpers.py +0 -70
- meteostat-1.7.6/meteostat/utilities/mutations.py +0 -89
- meteostat-1.7.6/meteostat/utilities/validations.py +0 -30
- meteostat-1.7.6/meteostat.egg-info/PKG-INFO +0 -109
- meteostat-1.7.6/meteostat.egg-info/SOURCES.txt +0 -42
- meteostat-1.7.6/meteostat.egg-info/dependency_links.txt +0 -1
- meteostat-1.7.6/meteostat.egg-info/requires.txt +0 -3
- meteostat-1.7.6/meteostat.egg-info/top_level.txt +0 -1
- meteostat-1.7.6/setup.cfg +0 -4
- meteostat-1.7.6/setup.py +0 -40
- {meteostat-1.7.6 → meteostat-2.0.1}/LICENSE +0 -0
- {meteostat-1.7.6/meteostat/core → meteostat-2.0.1/meteostat/api}/__init__.py +0 -0
- {meteostat-1.7.6/meteostat/enumerations → meteostat-2.0.1/meteostat/interpolation}/__init__.py +0 -0
- {meteostat-1.7.6/meteostat/interface → meteostat-2.0.1/meteostat/providers}/__init__.py +0 -0
- /meteostat-1.7.6/meteostat/interface/interpolate.py → /meteostat-2.0.1/meteostat/py.typed +0 -0
- {meteostat-1.7.6/meteostat/series → meteostat-2.0.1/meteostat/utils}/__init__.py +0 -0
meteostat-2.0.1/PKG-INFO
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: meteostat
|
|
3
|
+
Version: 2.0.1
|
|
4
|
+
Summary: Access and analyze historical weather and climate data with Python.
|
|
5
|
+
License-File: LICENSE
|
|
6
|
+
Author: Meteostat
|
|
7
|
+
Requires-Python: >=3.11,<4.0
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
13
|
+
Requires-Dist: pandas (>=2.3.3,<3.0.0)
|
|
14
|
+
Requires-Dist: pytz (>=2023.3.post1,<2024.0)
|
|
15
|
+
Requires-Dist: requests (>=2.31.0,<3.0.0)
|
|
16
|
+
Description-Content-Type: text/markdown
|
|
17
|
+
|
|
18
|
+
<!-- PROJECT SHIELDS -->
|
|
19
|
+
<div align="center">
|
|
20
|
+
|
|
21
|
+
[![Downloads][downloads-shield]][downloads-url]
|
|
22
|
+
[![Provider Tests][provider-tests-shield]][provider-tests-url]
|
|
23
|
+
[![Issues][issues-shield]][issues-url]
|
|
24
|
+
[![MIT License][license-shield]][license-url]
|
|
25
|
+
[![Stargazers][stars-shield]][stars-url]
|
|
26
|
+
|
|
27
|
+
</div>
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
<!-- PROJECT LOGO -->
|
|
31
|
+
<br />
|
|
32
|
+
<div align="center">
|
|
33
|
+
<a href="https://github.com/meteostat/meteostat">
|
|
34
|
+
<img src="https://media.meteostat.net/icon.svg" alt="Meteostat Logo" width="80" height="80">
|
|
35
|
+
</a>
|
|
36
|
+
|
|
37
|
+
<h3 align="center">Meteostat Python Package</h3>
|
|
38
|
+
|
|
39
|
+
<p align="center">
|
|
40
|
+
Access and analyze historical weather and climate data with Python.
|
|
41
|
+
<p>
|
|
42
|
+
<a href="https://dev.meteostat.net/python"><strong>Explore the docs »</strong></a>
|
|
43
|
+
</p>
|
|
44
|
+
<p>
|
|
45
|
+
<a href="https://meteostat.net">Visit Website</a>
|
|
46
|
+
·
|
|
47
|
+
<a href="https://github.com/meteostat/meteostat/issues">Report Bug</a>
|
|
48
|
+
·
|
|
49
|
+
<a href="https://github.com/orgs/meteostat/discussions">Request Feature</a>
|
|
50
|
+
</p>
|
|
51
|
+
</p>
|
|
52
|
+
</div>
|
|
53
|
+
|
|
54
|
+
## 📚 Installation
|
|
55
|
+
|
|
56
|
+
The Meteostat Python package is available through [PyPI](https://pypi.org/project/meteostat/):
|
|
57
|
+
|
|
58
|
+
```sh
|
|
59
|
+
pip install meteostat
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## 🚀 Usage
|
|
63
|
+
|
|
64
|
+
Let's plot 2018 temperature data for Frankfurt, Germany:
|
|
65
|
+
|
|
66
|
+
```python
|
|
67
|
+
from datetime import date
|
|
68
|
+
import matplotlib.pyplot as plt
|
|
69
|
+
import meteostat as ms
|
|
70
|
+
|
|
71
|
+
# Specify location and time range
|
|
72
|
+
POINT = ms.Point(50.1155, 8.6842, 113) # Try with your location
|
|
73
|
+
START = date(2018, 1, 1)
|
|
74
|
+
END = date(2018, 12, 31)
|
|
75
|
+
|
|
76
|
+
# Get nearby weather stations
|
|
77
|
+
stations = ms.stations.nearby(POINT, limit=4)
|
|
78
|
+
|
|
79
|
+
# Get daily data & perform interpolation
|
|
80
|
+
ts = ms.daily(stations, START, END)
|
|
81
|
+
df = ms.interpolate(ts, POINT).fetch()
|
|
82
|
+
|
|
83
|
+
# Plot line chart including average, minimum and maximum temperature
|
|
84
|
+
df.plot(y=[ms.Parameter.TEMP, ms.Parameter.TMIN, ms.Parameter.TMAX])
|
|
85
|
+
plt.show()
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Take a look at the expected output:
|
|
89
|
+
|
|
90
|
+
![2018 temperature data for Frankfurt, Germany][product-screenshot]
|
|
91
|
+
|
|
92
|
+
## 🤝 Contributing
|
|
93
|
+
|
|
94
|
+
Please read our [contributing guidelines](https://dev.meteostat.net/python/contributing) for details on how to contribute to the Meteostat Python library.
|
|
95
|
+
|
|
96
|
+
**Top contributors**
|
|
97
|
+
|
|
98
|
+
<a href="https://github.com/meteostat/meteostat/graphs/contributors">
|
|
99
|
+
<img src="https://contrib.rocks/image?repo=meteostat/meteostat" alt="Meteostat Contributors" />
|
|
100
|
+
</a>
|
|
101
|
+
|
|
102
|
+
## 🌟 Featured In
|
|
103
|
+
|
|
104
|
+
Meteostat has been featured and used by various media outlets and organizations, including:
|
|
105
|
+
|
|
106
|
+
- [Towards Data Science](https://towardsdatascience.com/get-temperature-data-by-location-with-python-52ed872dd621/)
|
|
107
|
+
- [ZEIT ONLINE](https://www.zeit.de/digital/internet/2022-03/desinformation-russland-ukraine-fotos-fake-news-falschinformation-echtheit)
|
|
108
|
+
- [Deutsche Presse-Agentur (dpa)](https://dpa-factchecking.com/germany/230103-99-92282/)
|
|
109
|
+
- [heise online](https://www.heise.de/news/Open-Source-Projekt-zu-Klimadaten-Meteostat-Python-Library-1-0-erschienen-4985015.html)
|
|
110
|
+
|
|
111
|
+
Join the growing community of users and researchers relying on Meteostat for their weather data needs.
|
|
112
|
+
|
|
113
|
+
## 📄 License
|
|
114
|
+
|
|
115
|
+
Meteostat is licensed under the [**MIT License**](https://github.com/meteostat/meteostat/blob/main/LICENSE). Data provided by Meteostat is generally licensed under the [**Creative Commons Attribution 4.0 International (CC BY 4.0)**](https://creativecommons.org/licenses/by/4.0) license. Please refer to the [documentation](https://dev.meteostat.net/license) for more information.
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
<!-- MARKDOWN LINKS & IMAGES -->
|
|
119
|
+
<!-- https://www.markdownguide.org/basic-syntax/#reference-style-links -->
|
|
120
|
+
[downloads-shield]: https://img.shields.io/pypi/dm/meteostat
|
|
121
|
+
[downloads-url]: https://pypi.org/project/meteostat/
|
|
122
|
+
[provider-tests-shield]: https://github.com/meteostat/meteostat/actions/workflows/provider-tests.yml/badge.svg
|
|
123
|
+
[provider-tests-url]: https://github.com/meteostat/meteostat/actions/workflows/provider-tests.yml
|
|
124
|
+
[issues-shield]: https://img.shields.io/github/issues/meteostat/meteostat.svg
|
|
125
|
+
[issues-url]: https://github.com/meteostat/meteostat/issues
|
|
126
|
+
[license-shield]: https://img.shields.io/github/license/meteostat/meteostat.svg
|
|
127
|
+
[license-url]: https://github.com/meteostat/meteostat?tab=readme-ov-file#-license
|
|
128
|
+
[product-screenshot]: https://dev.meteostat.net/assets/images/example-8b6cf2a3fe2efa285bc72d7dc72c4865.png
|
|
129
|
+
[stars-shield]: https://img.shields.io/github/stars/meteostat/meteostat.svg
|
|
130
|
+
[stars-url]: https://github.com/meteostat/meteostat/stargazers
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
<!-- PROJECT SHIELDS -->
|
|
2
|
+
<div align="center">
|
|
3
|
+
|
|
4
|
+
[![Downloads][downloads-shield]][downloads-url]
|
|
5
|
+
[![Provider Tests][provider-tests-shield]][provider-tests-url]
|
|
6
|
+
[![Issues][issues-shield]][issues-url]
|
|
7
|
+
[![MIT License][license-shield]][license-url]
|
|
8
|
+
[![Stargazers][stars-shield]][stars-url]
|
|
9
|
+
|
|
10
|
+
</div>
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
<!-- PROJECT LOGO -->
|
|
14
|
+
<br />
|
|
15
|
+
<div align="center">
|
|
16
|
+
<a href="https://github.com/meteostat/meteostat">
|
|
17
|
+
<img src="https://media.meteostat.net/icon.svg" alt="Meteostat Logo" width="80" height="80">
|
|
18
|
+
</a>
|
|
19
|
+
|
|
20
|
+
<h3 align="center">Meteostat Python Package</h3>
|
|
21
|
+
|
|
22
|
+
<p align="center">
|
|
23
|
+
Access and analyze historical weather and climate data with Python.
|
|
24
|
+
<p>
|
|
25
|
+
<a href="https://dev.meteostat.net/python"><strong>Explore the docs »</strong></a>
|
|
26
|
+
</p>
|
|
27
|
+
<p>
|
|
28
|
+
<a href="https://meteostat.net">Visit Website</a>
|
|
29
|
+
·
|
|
30
|
+
<a href="https://github.com/meteostat/meteostat/issues">Report Bug</a>
|
|
31
|
+
·
|
|
32
|
+
<a href="https://github.com/orgs/meteostat/discussions">Request Feature</a>
|
|
33
|
+
</p>
|
|
34
|
+
</p>
|
|
35
|
+
</div>
|
|
36
|
+
|
|
37
|
+
## 📚 Installation
|
|
38
|
+
|
|
39
|
+
The Meteostat Python package is available through [PyPI](https://pypi.org/project/meteostat/):
|
|
40
|
+
|
|
41
|
+
```sh
|
|
42
|
+
pip install meteostat
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## 🚀 Usage
|
|
46
|
+
|
|
47
|
+
Let's plot 2018 temperature data for Frankfurt, Germany:
|
|
48
|
+
|
|
49
|
+
```python
|
|
50
|
+
from datetime import date
|
|
51
|
+
import matplotlib.pyplot as plt
|
|
52
|
+
import meteostat as ms
|
|
53
|
+
|
|
54
|
+
# Specify location and time range
|
|
55
|
+
POINT = ms.Point(50.1155, 8.6842, 113) # Try with your location
|
|
56
|
+
START = date(2018, 1, 1)
|
|
57
|
+
END = date(2018, 12, 31)
|
|
58
|
+
|
|
59
|
+
# Get nearby weather stations
|
|
60
|
+
stations = ms.stations.nearby(POINT, limit=4)
|
|
61
|
+
|
|
62
|
+
# Get daily data & perform interpolation
|
|
63
|
+
ts = ms.daily(stations, START, END)
|
|
64
|
+
df = ms.interpolate(ts, POINT).fetch()
|
|
65
|
+
|
|
66
|
+
# Plot line chart including average, minimum and maximum temperature
|
|
67
|
+
df.plot(y=[ms.Parameter.TEMP, ms.Parameter.TMIN, ms.Parameter.TMAX])
|
|
68
|
+
plt.show()
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Take a look at the expected output:
|
|
72
|
+
|
|
73
|
+
![2018 temperature data for Frankfurt, Germany][product-screenshot]
|
|
74
|
+
|
|
75
|
+
## 🤝 Contributing
|
|
76
|
+
|
|
77
|
+
Please read our [contributing guidelines](https://dev.meteostat.net/python/contributing) for details on how to contribute to the Meteostat Python library.
|
|
78
|
+
|
|
79
|
+
**Top contributors**
|
|
80
|
+
|
|
81
|
+
<a href="https://github.com/meteostat/meteostat/graphs/contributors">
|
|
82
|
+
<img src="https://contrib.rocks/image?repo=meteostat/meteostat" alt="Meteostat Contributors" />
|
|
83
|
+
</a>
|
|
84
|
+
|
|
85
|
+
## 🌟 Featured In
|
|
86
|
+
|
|
87
|
+
Meteostat has been featured and used by various media outlets and organizations, including:
|
|
88
|
+
|
|
89
|
+
- [Towards Data Science](https://towardsdatascience.com/get-temperature-data-by-location-with-python-52ed872dd621/)
|
|
90
|
+
- [ZEIT ONLINE](https://www.zeit.de/digital/internet/2022-03/desinformation-russland-ukraine-fotos-fake-news-falschinformation-echtheit)
|
|
91
|
+
- [Deutsche Presse-Agentur (dpa)](https://dpa-factchecking.com/germany/230103-99-92282/)
|
|
92
|
+
- [heise online](https://www.heise.de/news/Open-Source-Projekt-zu-Klimadaten-Meteostat-Python-Library-1-0-erschienen-4985015.html)
|
|
93
|
+
|
|
94
|
+
Join the growing community of users and researchers relying on Meteostat for their weather data needs.
|
|
95
|
+
|
|
96
|
+
## 📄 License
|
|
97
|
+
|
|
98
|
+
Meteostat is licensed under the [**MIT License**](https://github.com/meteostat/meteostat/blob/main/LICENSE). Data provided by Meteostat is generally licensed under the [**Creative Commons Attribution 4.0 International (CC BY 4.0)**](https://creativecommons.org/licenses/by/4.0) license. Please refer to the [documentation](https://dev.meteostat.net/license) for more information.
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
<!-- MARKDOWN LINKS & IMAGES -->
|
|
102
|
+
<!-- https://www.markdownguide.org/basic-syntax/#reference-style-links -->
|
|
103
|
+
[downloads-shield]: https://img.shields.io/pypi/dm/meteostat
|
|
104
|
+
[downloads-url]: https://pypi.org/project/meteostat/
|
|
105
|
+
[provider-tests-shield]: https://github.com/meteostat/meteostat/actions/workflows/provider-tests.yml/badge.svg
|
|
106
|
+
[provider-tests-url]: https://github.com/meteostat/meteostat/actions/workflows/provider-tests.yml
|
|
107
|
+
[issues-shield]: https://img.shields.io/github/issues/meteostat/meteostat.svg
|
|
108
|
+
[issues-url]: https://github.com/meteostat/meteostat/issues
|
|
109
|
+
[license-shield]: https://img.shields.io/github/license/meteostat/meteostat.svg
|
|
110
|
+
[license-url]: https://github.com/meteostat/meteostat?tab=readme-ov-file#-license
|
|
111
|
+
[product-screenshot]: https://dev.meteostat.net/assets/images/example-8b6cf2a3fe2efa285bc72d7dc72c4865.png
|
|
112
|
+
[stars-shield]: https://img.shields.io/github/stars/meteostat/meteostat.svg
|
|
113
|
+
[stars-url]: https://github.com/meteostat/meteostat/stargazers
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"""
|
|
2
|
+
█▀▄▀█ █▀▀ ▀█▀ █▀▀ █▀█ █▀ ▀█▀ ▄▀█ ▀█▀
|
|
3
|
+
█░▀░█ ██▄ ░█░ ██▄ █▄█ ▄█ ░█░ █▀█ ░█░
|
|
4
|
+
|
|
5
|
+
A Python library for accessing open weather and climate data.
|
|
6
|
+
|
|
7
|
+
Meteorological data provided by Meteostat (https://dev.meteostat.net)
|
|
8
|
+
under the terms of the Creative Commons Attribution 4.0 International
|
|
9
|
+
License.
|
|
10
|
+
|
|
11
|
+
The code is licensed under the MIT license.
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
__appname__ = "meteostat"
|
|
15
|
+
__version__ = "2.0.1"
|
|
16
|
+
|
|
17
|
+
from meteostat.api.daily import daily
|
|
18
|
+
from meteostat.api.hourly import hourly
|
|
19
|
+
from meteostat.api.interpolate import interpolate
|
|
20
|
+
from meteostat.api.inventory import Inventory
|
|
21
|
+
from meteostat.api.merge import merge
|
|
22
|
+
from meteostat.api.monthly import monthly
|
|
23
|
+
from meteostat.api.normals import normals
|
|
24
|
+
from meteostat.api.point import Point
|
|
25
|
+
from meteostat.api.stations import stations
|
|
26
|
+
from meteostat.api.timeseries import TimeSeries
|
|
27
|
+
from meteostat.core.cache import purge
|
|
28
|
+
from meteostat.api.config import config
|
|
29
|
+
from meteostat.enumerations import Granularity, Parameter, Provider, UnitSystem
|
|
30
|
+
from meteostat.interpolation.lapserate import lapse_rate
|
|
31
|
+
from meteostat.typing import Station, License
|
|
32
|
+
|
|
33
|
+
# Export public API
|
|
34
|
+
__all__ = [
|
|
35
|
+
"config",
|
|
36
|
+
"daily",
|
|
37
|
+
"hourly",
|
|
38
|
+
"Granularity",
|
|
39
|
+
"interpolate",
|
|
40
|
+
"Inventory",
|
|
41
|
+
"lapse_rate",
|
|
42
|
+
"License",
|
|
43
|
+
"merge",
|
|
44
|
+
"monthly",
|
|
45
|
+
"normals",
|
|
46
|
+
"Parameter",
|
|
47
|
+
"Point",
|
|
48
|
+
"Provider",
|
|
49
|
+
"purge",
|
|
50
|
+
"Station",
|
|
51
|
+
"stations",
|
|
52
|
+
"TimeSeries",
|
|
53
|
+
"UnitSystem",
|
|
54
|
+
]
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Configuration Service
|
|
3
|
+
|
|
4
|
+
Manages configuration settings for Meteostat, including cache, network,
|
|
5
|
+
stations, interpolation, and provider-specific settings. Configuration can be
|
|
6
|
+
loaded from environment variables with the MS_ prefix.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import os
|
|
10
|
+
import json
|
|
11
|
+
from typing import Any, List, Optional
|
|
12
|
+
|
|
13
|
+
from meteostat.core.logger import logger
|
|
14
|
+
from meteostat.enumerations import TTL, Parameter
|
|
15
|
+
from meteostat.utils.types import extract_property_type, validate_parsed_value
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class ConfigService:
|
|
19
|
+
"""
|
|
20
|
+
Configuration Service for Meteostat
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
prefix: str
|
|
24
|
+
|
|
25
|
+
@property
|
|
26
|
+
def _prefix(self) -> str:
|
|
27
|
+
"""
|
|
28
|
+
The environment variable prefix
|
|
29
|
+
"""
|
|
30
|
+
return f"{self.prefix}_" if self.prefix else ""
|
|
31
|
+
|
|
32
|
+
def _parse_env_value(self, key: str, value: str) -> Any:
|
|
33
|
+
"""
|
|
34
|
+
Parse an environment variable value and validate against property type
|
|
35
|
+
"""
|
|
36
|
+
# Extract the expected type for the property
|
|
37
|
+
expected_type, original_type = extract_property_type(self.__class__, key)
|
|
38
|
+
|
|
39
|
+
if expected_type is None:
|
|
40
|
+
# Fallback to JSON parsing if no type annotation is available
|
|
41
|
+
try:
|
|
42
|
+
return json.loads(value)
|
|
43
|
+
except (json.JSONDecodeError, TypeError, ValueError):
|
|
44
|
+
logger.error("Failed to parse environment variable '%s'", key)
|
|
45
|
+
return None
|
|
46
|
+
|
|
47
|
+
# Parse the value using JSON
|
|
48
|
+
try:
|
|
49
|
+
parsed_value = json.loads(value)
|
|
50
|
+
except (json.JSONDecodeError, TypeError, ValueError):
|
|
51
|
+
logger.error("Failed to parse environment variable '%s'", key)
|
|
52
|
+
return None
|
|
53
|
+
|
|
54
|
+
# Validate and potentially convert the parsed value
|
|
55
|
+
return validate_parsed_value(parsed_value, expected_type, original_type, key)
|
|
56
|
+
|
|
57
|
+
def _set_env_value(self, key: str, value: Any) -> None:
|
|
58
|
+
"""
|
|
59
|
+
Set a configuration using a key-value pair
|
|
60
|
+
"""
|
|
61
|
+
setattr(self, key, value)
|
|
62
|
+
|
|
63
|
+
def __init__(self, prefix: str = "MS") -> None:
|
|
64
|
+
"""
|
|
65
|
+
Initialize configuration service
|
|
66
|
+
"""
|
|
67
|
+
self.prefix = prefix
|
|
68
|
+
self.load_env()
|
|
69
|
+
|
|
70
|
+
def get_env_name(self, key: str) -> str:
|
|
71
|
+
"""
|
|
72
|
+
Get the environment variable name for a given key
|
|
73
|
+
"""
|
|
74
|
+
if not hasattr(self, key):
|
|
75
|
+
raise KeyError(f"Configuration has no key '{key}'")
|
|
76
|
+
|
|
77
|
+
key = f"{self._prefix}{key}"
|
|
78
|
+
return key.upper()
|
|
79
|
+
|
|
80
|
+
def load_env(self) -> None:
|
|
81
|
+
"""
|
|
82
|
+
Update configuration from environment variables with a given prefix.
|
|
83
|
+
"""
|
|
84
|
+
for key, value in os.environ.items():
|
|
85
|
+
if not key.startswith(self._prefix):
|
|
86
|
+
continue
|
|
87
|
+
|
|
88
|
+
key = key.replace(self._prefix, "").lower()
|
|
89
|
+
value = self._parse_env_value(key, value)
|
|
90
|
+
|
|
91
|
+
if value is not None:
|
|
92
|
+
self._set_env_value(key, value)
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
class Config(ConfigService):
|
|
96
|
+
"""
|
|
97
|
+
Meteostat Configuration
|
|
98
|
+
|
|
99
|
+
Manages all configuration settings including cache, network, stations,
|
|
100
|
+
interpolation, and provider-specific settings. Supports loading configuration
|
|
101
|
+
from environment variables.
|
|
102
|
+
"""
|
|
103
|
+
|
|
104
|
+
# General settings
|
|
105
|
+
block_large_requests: bool = True # Block requests that include too many stations
|
|
106
|
+
|
|
107
|
+
# Cache settings
|
|
108
|
+
cache_enable: bool = True
|
|
109
|
+
cache_directory: str = (
|
|
110
|
+
os.path.expanduser("~") + os.sep + ".meteostat" + os.sep + "cache"
|
|
111
|
+
)
|
|
112
|
+
cache_ttl: int = TTL.MONTH
|
|
113
|
+
cache_autoclean: bool = True
|
|
114
|
+
|
|
115
|
+
# Network settings
|
|
116
|
+
network_proxies: Optional[dict] = None
|
|
117
|
+
|
|
118
|
+
# Station meta data settings
|
|
119
|
+
stations_db_ttl: int = TTL.WEEK
|
|
120
|
+
stations_db_endpoints: List[str] = [
|
|
121
|
+
"https://data.meteostat.net/stations.db",
|
|
122
|
+
"https://raw.githubusercontent.com/meteostat/weather-stations/master/stations.db",
|
|
123
|
+
]
|
|
124
|
+
stations_db_file: str = (
|
|
125
|
+
os.path.expanduser("~") + os.sep + ".meteostat" + os.sep + "stations.db"
|
|
126
|
+
)
|
|
127
|
+
|
|
128
|
+
# Interpolation settings
|
|
129
|
+
lapse_rate_parameters = [Parameter.TEMP, Parameter.TMIN, Parameter.TMAX]
|
|
130
|
+
|
|
131
|
+
# [Provider] Meteostat settings
|
|
132
|
+
include_model_data: bool = True
|
|
133
|
+
hourly_endpoint: str = "https://data.meteostat.net/hourly/{year}/{station}.csv.gz"
|
|
134
|
+
daily_endpoint: str = "https://data.meteostat.net/daily/{year}/{station}.csv.gz"
|
|
135
|
+
monthly_endpoint: str = "https://data.meteostat.net/monthly/{station}.csv.gz"
|
|
136
|
+
|
|
137
|
+
# [Provider] DWD settings
|
|
138
|
+
dwd_ftp_host: str = "opendata.dwd.de"
|
|
139
|
+
dwd_hourly_modes: Optional[List[str]] = None
|
|
140
|
+
dwd_daily_modes: Optional[List[str]] = None
|
|
141
|
+
dwd_climat_modes: Optional[List[str]] = None
|
|
142
|
+
|
|
143
|
+
# [Provider] NOAA settings
|
|
144
|
+
aviationweather_endpoint: str = (
|
|
145
|
+
"https://aviationweather.gov/api/data/metar?"
|
|
146
|
+
"ids={station}&format=raw&taf=false&hours=24"
|
|
147
|
+
)
|
|
148
|
+
aviationweather_user_agent: Optional[str] = None
|
|
149
|
+
|
|
150
|
+
# [Provider] Met.no settings
|
|
151
|
+
metno_forecast_endpoint: str = (
|
|
152
|
+
"https://api.met.no/weatherapi/locationforecast/2.0/compact?"
|
|
153
|
+
"lat={latitude}&lon={longitude}&altitude={elevation}"
|
|
154
|
+
)
|
|
155
|
+
metno_user_agent: Optional[str] = None
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
config = Config("MS")
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Daily Time Series Data
|
|
3
|
+
|
|
4
|
+
Access daily time series data for one or multiple weather stations.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from typing import List, Optional
|
|
8
|
+
from datetime import datetime, date
|
|
9
|
+
|
|
10
|
+
import pandas as pd
|
|
11
|
+
|
|
12
|
+
from meteostat.core.data import data_service
|
|
13
|
+
from meteostat.enumerations import Parameter, Provider, Granularity
|
|
14
|
+
from meteostat.typing import Station, Request
|
|
15
|
+
from meteostat.api.point import Point
|
|
16
|
+
from meteostat.utils.parsers import parse_station, parse_time
|
|
17
|
+
|
|
18
|
+
DEFAULT_PARAMETERS = [
|
|
19
|
+
Parameter.TEMP,
|
|
20
|
+
Parameter.TMIN,
|
|
21
|
+
Parameter.TMAX,
|
|
22
|
+
Parameter.RHUM,
|
|
23
|
+
Parameter.PRCP,
|
|
24
|
+
Parameter.SNWD,
|
|
25
|
+
Parameter.WSPD,
|
|
26
|
+
Parameter.WPGT,
|
|
27
|
+
Parameter.PRES,
|
|
28
|
+
Parameter.TSUN,
|
|
29
|
+
Parameter.CLDC,
|
|
30
|
+
]
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def daily(
|
|
34
|
+
station: str | Station | Point | List[str | Station | Point] | pd.DataFrame,
|
|
35
|
+
start: Optional[datetime | date],
|
|
36
|
+
end: Optional[datetime | date],
|
|
37
|
+
parameters: Optional[List[Parameter]] = None,
|
|
38
|
+
providers: Optional[List[Provider]] = None,
|
|
39
|
+
):
|
|
40
|
+
"""
|
|
41
|
+
Access daily time series data.
|
|
42
|
+
|
|
43
|
+
Parameters
|
|
44
|
+
----------
|
|
45
|
+
station : str, Station, Point, List[str | Station | Point], pd.Index, pd.Series
|
|
46
|
+
Weather station(s) or Point(s) to query data for. Can be a single station/point or a list.
|
|
47
|
+
Points are converted to virtual stations with IDs like $0001, $0002, etc.
|
|
48
|
+
start : datetime, date, optional
|
|
49
|
+
Start date for the data query. If None, the earliest available date will be used.
|
|
50
|
+
end : datetime, date, optional
|
|
51
|
+
End date for the data query. If None, the latest available date will be used.
|
|
52
|
+
parameters : List[Parameter], optional
|
|
53
|
+
List of parameters to include in the data query. Defaults to a set of common parameters.
|
|
54
|
+
providers : List[Provider], optional
|
|
55
|
+
List of data providers to use for the query. Defaults to the daily provider.
|
|
56
|
+
|
|
57
|
+
Returns
|
|
58
|
+
-------
|
|
59
|
+
TimeSeries
|
|
60
|
+
A TimeSeries object containing the daily data for the specified stations and parameters.
|
|
61
|
+
"""
|
|
62
|
+
if parameters is None:
|
|
63
|
+
parameters = DEFAULT_PARAMETERS
|
|
64
|
+
if providers is None:
|
|
65
|
+
providers = [Provider.DAILY]
|
|
66
|
+
|
|
67
|
+
req = Request(
|
|
68
|
+
granularity=Granularity.DAILY,
|
|
69
|
+
providers=providers,
|
|
70
|
+
parameters=parameters,
|
|
71
|
+
station=parse_station(station),
|
|
72
|
+
start=parse_time(start),
|
|
73
|
+
end=parse_time(end, is_end=True),
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
return data_service.fetch(req)
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Hourly Time Series Data
|
|
3
|
+
|
|
4
|
+
Access hourly time series data for one or multiple weather stations.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from typing import List, Optional
|
|
8
|
+
from datetime import datetime, date
|
|
9
|
+
|
|
10
|
+
import pandas as pd
|
|
11
|
+
|
|
12
|
+
from meteostat.core.data import data_service
|
|
13
|
+
from meteostat.enumerations import Parameter, Provider, Granularity
|
|
14
|
+
from meteostat.typing import Station, Request
|
|
15
|
+
from meteostat.api.point import Point
|
|
16
|
+
from meteostat.utils.parsers import parse_station, parse_time
|
|
17
|
+
|
|
18
|
+
DEFAULT_PARAMETERS = [
|
|
19
|
+
Parameter.TEMP,
|
|
20
|
+
Parameter.RHUM,
|
|
21
|
+
Parameter.PRCP,
|
|
22
|
+
Parameter.SNWD,
|
|
23
|
+
Parameter.WDIR,
|
|
24
|
+
Parameter.WSPD,
|
|
25
|
+
Parameter.WPGT,
|
|
26
|
+
Parameter.PRES,
|
|
27
|
+
Parameter.TSUN,
|
|
28
|
+
Parameter.CLDC,
|
|
29
|
+
Parameter.COCO,
|
|
30
|
+
]
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def hourly(
|
|
34
|
+
station: str | Station | Point | List[str | Station | Point] | pd.DataFrame,
|
|
35
|
+
start: Optional[datetime | date],
|
|
36
|
+
end: Optional[datetime | date],
|
|
37
|
+
timezone: Optional[str] = None,
|
|
38
|
+
parameters: Optional[List[Parameter]] = None,
|
|
39
|
+
providers: Optional[List[Provider]] = None,
|
|
40
|
+
):
|
|
41
|
+
"""
|
|
42
|
+
Access hourly time series data.
|
|
43
|
+
|
|
44
|
+
Parameters
|
|
45
|
+
----------
|
|
46
|
+
station : str, Station, Point, List[str | Station | Point], pd.Index, pd.Series
|
|
47
|
+
Weather station(s) or Point(s) to query data for. Can be a single station/point or a list.
|
|
48
|
+
Points are converted to virtual stations with IDs like $0001, $0002, etc.
|
|
49
|
+
start : datetime, date, optional
|
|
50
|
+
Start date for the data query. If None, the earliest available date will be used.
|
|
51
|
+
end : datetime, date, optional
|
|
52
|
+
End date for the data query. If None, the latest available date will be used.
|
|
53
|
+
timezone : str, optional
|
|
54
|
+
Time zone for the data query. If None, UTC will be used.
|
|
55
|
+
parameters : List[Parameter], optional
|
|
56
|
+
List of parameters to include in the data query. Defaults to a set of common parameters.
|
|
57
|
+
providers : List[Provider], optional
|
|
58
|
+
List of data providers to use for the query. Defaults to the hourly provider.
|
|
59
|
+
|
|
60
|
+
Returns
|
|
61
|
+
-------
|
|
62
|
+
TimeSeries
|
|
63
|
+
A TimeSeries object containing the hourly data for the specified stations and parameters.
|
|
64
|
+
"""
|
|
65
|
+
if parameters is None:
|
|
66
|
+
parameters = DEFAULT_PARAMETERS
|
|
67
|
+
if providers is None:
|
|
68
|
+
providers = [Provider.HOURLY]
|
|
69
|
+
|
|
70
|
+
req = Request(
|
|
71
|
+
granularity=Granularity.HOURLY,
|
|
72
|
+
providers=providers,
|
|
73
|
+
parameters=parameters,
|
|
74
|
+
station=parse_station(station),
|
|
75
|
+
start=parse_time(start, timezone),
|
|
76
|
+
end=parse_time(end, timezone, is_end=True),
|
|
77
|
+
timezone=timezone,
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
return data_service.fetch(req)
|