meteostat 1.7.6__py3-none-any.whl → 2.0.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.
Files changed (94) hide show
  1. meteostat/__init__.py +38 -19
  2. meteostat/api/config.py +158 -0
  3. meteostat/api/daily.py +76 -0
  4. meteostat/api/hourly.py +80 -0
  5. meteostat/api/interpolate.py +378 -0
  6. meteostat/api/inventory.py +59 -0
  7. meteostat/api/merge.py +103 -0
  8. meteostat/api/monthly.py +73 -0
  9. meteostat/api/normals.py +144 -0
  10. meteostat/api/point.py +30 -0
  11. meteostat/api/stations.py +234 -0
  12. meteostat/api/timeseries.py +334 -0
  13. meteostat/core/cache.py +212 -59
  14. meteostat/core/data.py +203 -0
  15. meteostat/core/logger.py +9 -0
  16. meteostat/core/network.py +82 -0
  17. meteostat/core/parameters.py +112 -0
  18. meteostat/core/providers.py +184 -0
  19. meteostat/core/schema.py +170 -0
  20. meteostat/core/validator.py +38 -0
  21. meteostat/enumerations.py +149 -0
  22. meteostat/interpolation/idw.py +120 -0
  23. meteostat/interpolation/lapserate.py +91 -0
  24. meteostat/interpolation/nearest.py +31 -0
  25. meteostat/parameters.py +354 -0
  26. meteostat/providers/dwd/climat.py +166 -0
  27. meteostat/providers/dwd/daily.py +144 -0
  28. meteostat/providers/dwd/hourly.py +218 -0
  29. meteostat/providers/dwd/monthly.py +138 -0
  30. meteostat/providers/dwd/mosmix.py +351 -0
  31. meteostat/providers/dwd/poi.py +117 -0
  32. meteostat/providers/dwd/shared.py +155 -0
  33. meteostat/providers/eccc/daily.py +87 -0
  34. meteostat/providers/eccc/hourly.py +104 -0
  35. meteostat/providers/eccc/monthly.py +66 -0
  36. meteostat/providers/eccc/shared.py +45 -0
  37. meteostat/providers/index.py +496 -0
  38. meteostat/providers/meteostat/daily.py +65 -0
  39. meteostat/providers/meteostat/daily_derived.py +110 -0
  40. meteostat/providers/meteostat/hourly.py +66 -0
  41. meteostat/providers/meteostat/monthly.py +45 -0
  42. meteostat/providers/meteostat/monthly_derived.py +106 -0
  43. meteostat/providers/meteostat/shared.py +93 -0
  44. meteostat/providers/metno/forecast.py +186 -0
  45. meteostat/providers/noaa/ghcnd.py +228 -0
  46. meteostat/providers/noaa/isd_lite.py +142 -0
  47. meteostat/providers/noaa/metar.py +163 -0
  48. meteostat/typing.py +113 -0
  49. meteostat/utils/conversions.py +231 -0
  50. meteostat/utils/data.py +194 -0
  51. meteostat/utils/geo.py +28 -0
  52. meteostat/utils/guards.py +51 -0
  53. meteostat/utils/parsers.py +161 -0
  54. meteostat/utils/types.py +113 -0
  55. meteostat/utils/validators.py +31 -0
  56. meteostat-2.0.1.dist-info/METADATA +130 -0
  57. meteostat-2.0.1.dist-info/RECORD +64 -0
  58. {meteostat-1.7.6.dist-info → meteostat-2.0.1.dist-info}/WHEEL +1 -2
  59. meteostat/core/loader.py +0 -103
  60. meteostat/core/warn.py +0 -34
  61. meteostat/enumerations/granularity.py +0 -22
  62. meteostat/interface/base.py +0 -39
  63. meteostat/interface/daily.py +0 -118
  64. meteostat/interface/hourly.py +0 -154
  65. meteostat/interface/meteodata.py +0 -210
  66. meteostat/interface/monthly.py +0 -109
  67. meteostat/interface/normals.py +0 -245
  68. meteostat/interface/point.py +0 -143
  69. meteostat/interface/stations.py +0 -252
  70. meteostat/interface/timeseries.py +0 -237
  71. meteostat/series/aggregate.py +0 -48
  72. meteostat/series/convert.py +0 -28
  73. meteostat/series/count.py +0 -17
  74. meteostat/series/coverage.py +0 -20
  75. meteostat/series/fetch.py +0 -28
  76. meteostat/series/interpolate.py +0 -47
  77. meteostat/series/normalize.py +0 -76
  78. meteostat/series/stations.py +0 -22
  79. meteostat/units.py +0 -149
  80. meteostat/utilities/__init__.py +0 -0
  81. meteostat/utilities/aggregations.py +0 -37
  82. meteostat/utilities/endpoint.py +0 -33
  83. meteostat/utilities/helpers.py +0 -70
  84. meteostat/utilities/mutations.py +0 -89
  85. meteostat/utilities/validations.py +0 -30
  86. meteostat-1.7.6.dist-info/METADATA +0 -112
  87. meteostat-1.7.6.dist-info/RECORD +0 -39
  88. meteostat-1.7.6.dist-info/top_level.txt +0 -1
  89. /meteostat/{core → api}/__init__.py +0 -0
  90. /meteostat/{enumerations → interpolation}/__init__.py +0 -0
  91. /meteostat/{interface → providers}/__init__.py +0 -0
  92. /meteostat/{interface/interpolate.py → py.typed} +0 -0
  93. /meteostat/{series → utils}/__init__.py +0 -0
  94. {meteostat-1.7.6.dist-info → meteostat-2.0.1.dist-info/licenses}/LICENSE +0 -0
meteostat/__init__.py CHANGED
@@ -2,34 +2,53 @@
2
2
  █▀▄▀█ █▀▀ ▀█▀ █▀▀ █▀█ █▀ ▀█▀ ▄▀█ ▀█▀
3
3
  █░▀░█ ██▄ ░█░ ██▄ █▄█ ▄█ ░█░ █▀█ ░█░
4
4
 
5
- A Python library for accessing open weather and climate data
5
+ A Python library for accessing open weather and climate data.
6
6
 
7
7
  Meteorological data provided by Meteostat (https://dev.meteostat.net)
8
- under the terms of the Creative Commons Attribution-NonCommercial
9
- 4.0 International Public License.
8
+ under the terms of the Creative Commons Attribution 4.0 International
9
+ License.
10
10
 
11
11
  The code is licensed under the MIT license.
12
12
  """
13
13
 
14
14
  __appname__ = "meteostat"
15
- __version__ = "1.7.6"
15
+ __version__ = "2.0.1"
16
16
 
17
- from .interface.base import Base
18
- from .interface.timeseries import TimeSeries
19
- from .interface.stations import Stations
20
- from .interface.point import Point
21
- from .interface.hourly import Hourly
22
- from .interface.daily import Daily
23
- from .interface.monthly import Monthly
24
- from .interface.normals import Normals
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
25
32
 
33
+ # Export public API
26
34
  __all__ = [
27
- "Base",
28
- "TimeSeries",
29
- "Stations",
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",
30
47
  "Point",
31
- "Hourly",
32
- "Daily",
33
- "Monthly",
34
- "Normals",
48
+ "Provider",
49
+ "purge",
50
+ "Station",
51
+ "stations",
52
+ "TimeSeries",
53
+ "UnitSystem",
35
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")
meteostat/api/daily.py ADDED
@@ -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)