python-google-weather-api 0.0.2__py3-none-any.whl → 0.0.3__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.
@@ -1,15 +1,70 @@
1
1
  """A python client library for Google Weather API."""
2
2
 
3
- from .api import (
4
- GoogleWeatherApi,
3
+ from .api import GoogleWeatherApi
4
+ from .exceptions import (
5
5
  GoogleWeatherApiConnectionError,
6
6
  GoogleWeatherApiError,
7
7
  GoogleWeatherApiResponseError,
8
8
  )
9
+ from .model import (
10
+ AirPressure,
11
+ CurrentConditionsHistory,
12
+ CurrentConditionsResponse,
13
+ DailyForecastResponse,
14
+ Date,
15
+ DateTime,
16
+ ForecastDay,
17
+ ForecastDayPart,
18
+ ForecastHour,
19
+ HourlyForecastResponse,
20
+ IceThickness,
21
+ Interval,
22
+ LocalizedText,
23
+ MoonEvents,
24
+ Precipitation,
25
+ PrecipitationProbability,
26
+ QuantitativePrecipitationForecast,
27
+ SunEvents,
28
+ Temperature,
29
+ TimeZone,
30
+ Visibility,
31
+ WeatherCondition,
32
+ Wind,
33
+ WindDirection,
34
+ WindSpeed,
35
+ )
9
36
 
10
37
  __all__ = [
38
+ # API
11
39
  "GoogleWeatherApi",
40
+ # Exceptions
12
41
  "GoogleWeatherApiConnectionError",
13
42
  "GoogleWeatherApiError",
14
43
  "GoogleWeatherApiResponseError",
44
+ # Models
45
+ "AirPressure",
46
+ "CurrentConditionsHistory",
47
+ "CurrentConditionsResponse",
48
+ "Date",
49
+ "DailyForecastResponse",
50
+ "DateTime",
51
+ "ForecastDay",
52
+ "ForecastDayPart",
53
+ "ForecastHour",
54
+ "HourlyForecastResponse",
55
+ "IceThickness",
56
+ "Interval",
57
+ "LocalizedText",
58
+ "MoonEvents",
59
+ "Precipitation",
60
+ "PrecipitationProbability",
61
+ "QuantitativePrecipitationForecast",
62
+ "SunEvents",
63
+ "Temperature",
64
+ "TimeZone",
65
+ "Visibility",
66
+ "WeatherCondition",
67
+ "Wind",
68
+ "WindDirection",
69
+ "WindSpeed",
15
70
  ]
google_weather_api/api.py CHANGED
@@ -8,18 +8,15 @@ from typing import Any
8
8
 
9
9
  import aiohttp
10
10
 
11
-
12
- class GoogleWeatherApiError(Exception):
13
- """Exception talking to the Google Weather API."""
14
-
15
-
16
- class GoogleWeatherApiConnectionError(GoogleWeatherApiError):
17
- """Exception connecting to the Google Weather API."""
18
-
19
-
20
- class GoogleWeatherApiResponseError(GoogleWeatherApiError):
21
- """Exception raised for errors in the Google Weather API response."""
22
-
11
+ from .exceptions import (
12
+ GoogleWeatherApiConnectionError,
13
+ GoogleWeatherApiResponseError,
14
+ )
15
+ from .model import (
16
+ CurrentConditionsResponse,
17
+ DailyForecastResponse,
18
+ HourlyForecastResponse,
19
+ )
23
20
 
24
21
  _LOGGER = logging.getLogger(__name__)
25
22
 
@@ -79,21 +76,28 @@ class GoogleWeatherApi:
79
76
 
80
77
  async def async_get_current_conditions(
81
78
  self, latitude: float, longitude: float
82
- ) -> dict[str, Any]:
83
- """Fetch current weather conditions."""
84
- return await self._async_get(
79
+ ) -> CurrentConditionsResponse:
80
+ """Fetch current weather conditions.
81
+
82
+ See https://developers.google.com/maps/documentation/weather/reference/rest/v1/currentConditions/lookup
83
+ """
84
+ data = await self._async_get(
85
85
  "currentConditions:lookup",
86
86
  {
87
87
  "location.latitude": latitude,
88
88
  "location.longitude": longitude,
89
89
  },
90
90
  )
91
+ return CurrentConditionsResponse.from_dict(data)
91
92
 
92
93
  async def async_get_hourly_forecast(
93
94
  self, latitude: float, longitude: float, hours: int = 48
94
- ) -> dict[str, Any]:
95
- """Fetch hourly weather forecast."""
96
- return await self._async_get(
95
+ ) -> HourlyForecastResponse:
96
+ """Fetch hourly weather forecast.
97
+
98
+ See https://developers.google.com/maps/documentation/weather/reference/rest/v1/forecast.hours/lookup
99
+ """
100
+ data = await self._async_get(
97
101
  "forecast/hours:lookup",
98
102
  {
99
103
  "location.latitude": latitude,
@@ -102,12 +106,16 @@ class GoogleWeatherApi:
102
106
  "page_size": hours,
103
107
  },
104
108
  )
109
+ return HourlyForecastResponse.from_dict(data)
105
110
 
106
111
  async def async_get_daily_forecast(
107
112
  self, latitude: float, longitude: float, days: int = 10
108
- ) -> dict[str, Any]:
109
- """Fetch daily weather forecast."""
110
- return await self._async_get(
113
+ ) -> DailyForecastResponse:
114
+ """Fetch daily weather forecast.
115
+
116
+ See https://developers.google.com/maps/documentation/weather/reference/rest/v1/forecast.days/lookup
117
+ """
118
+ data = await self._async_get(
111
119
  "forecast/days:lookup",
112
120
  {
113
121
  "location.latitude": latitude,
@@ -116,3 +124,4 @@ class GoogleWeatherApi:
116
124
  "page_size": days,
117
125
  },
118
126
  )
127
+ return DailyForecastResponse.from_dict(data)
@@ -0,0 +1,13 @@
1
+ """Exceptions for Google Weather API."""
2
+
3
+
4
+ class GoogleWeatherApiError(Exception):
5
+ """Exception talking to the Google Weather API."""
6
+
7
+
8
+ class GoogleWeatherApiConnectionError(GoogleWeatherApiError):
9
+ """Exception connecting to the Google Weather API."""
10
+
11
+
12
+ class GoogleWeatherApiResponseError(GoogleWeatherApiError):
13
+ """Exception raised for errors in the Google Weather API response."""
@@ -0,0 +1,617 @@
1
+ """Models for the Google Weather API."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from dataclasses import dataclass, field
6
+ from enum import StrEnum
7
+
8
+ from mashumaro.mixins.json import DataClassJSONMixin
9
+
10
+
11
+ @dataclass
12
+ class AirPressure(DataClassJSONMixin):
13
+ """Represents the atmospheric air pressure conditions."""
14
+
15
+ mean_sea_level_millibars: float = field(metadata={"alias": "meanSeaLevelMillibars"})
16
+ """The mean sea level air pressure in millibars."""
17
+
18
+
19
+ @dataclass
20
+ class Interval(DataClassJSONMixin):
21
+ """Represents a time interval."""
22
+
23
+ start_time: str = field(metadata={"alias": "startTime"})
24
+ """Inclusive start of the interval in RFC 3339 format."""
25
+
26
+ end_time: str | None = field(default=None, metadata={"alias": "endTime"})
27
+ """Optional. Exclusive end of the interval in RFC 3339 format."""
28
+
29
+
30
+ @dataclass
31
+ class TimeZone(DataClassJSONMixin):
32
+ """Represents a time zone from the IANA Time Zone Database."""
33
+
34
+ id: str
35
+ """IANA Time Zone Database time zone. For example "America/New_York"."""
36
+
37
+ version: str | None = None
38
+ """Optional. IANA Time Zone Database version number. For example "2019a"."""
39
+
40
+
41
+ @dataclass
42
+ class LocalizedText(DataClassJSONMixin):
43
+ """Localized variant of a text in a particular language."""
44
+
45
+ text: str
46
+ """Localized string in the language corresponding to languageCode below."""
47
+
48
+ language_code: str = field(metadata={"alias": "languageCode"})
49
+ """The text's BCP-47 language code, such as "en-US" or "sr-Latn"."""
50
+
51
+
52
+ @dataclass
53
+ class Temperature(DataClassJSONMixin):
54
+ """Represents a temperature value."""
55
+
56
+ class TemperatureUnit(StrEnum):
57
+ """Represents a unit used to measure temperatures."""
58
+
59
+ TEMPERATURE_UNIT_UNSPECIFIED = "TEMPERATURE_UNIT_UNSPECIFIED"
60
+ CELSIUS = "CELSIUS"
61
+ FAHRENHEIT = "FAHRENHEIT"
62
+
63
+ degrees: float
64
+ """The temperature value (in degrees) in the specified unit."""
65
+
66
+ unit: TemperatureUnit
67
+ """The code for the unit used to measure the temperature value."""
68
+
69
+
70
+ @dataclass
71
+ class QuantitativePrecipitationForecast(DataClassJSONMixin):
72
+ """Represents the expected amount of melted precipitation."""
73
+
74
+ class Unit(StrEnum):
75
+ """Represents the unit used to measure the amount of accumulated precipitation."""
76
+
77
+ UNIT_UNSPECIFIED = "UNIT_UNSPECIFIED"
78
+ MILLIMETERS = "MILLIMETERS"
79
+ INCHES = "INCHES"
80
+
81
+ quantity: float
82
+ """The amount of precipitation, measured as liquid water equivalent."""
83
+
84
+ unit: Unit
85
+ """The code of the unit used to measure the amount of accumulated precipitation."""
86
+
87
+
88
+ @dataclass
89
+ class PrecipitationProbability(DataClassJSONMixin):
90
+ """Represents the probability of precipitation at a given location."""
91
+
92
+ class PrecipitationType(StrEnum):
93
+ """Represents the type of precipitation at a given location."""
94
+
95
+ PRECIPITATION_TYPE_UNSPECIFIED = "PRECIPITATION_TYPE_UNSPECIFIED"
96
+ NONE = "NONE"
97
+ SNOW = "SNOW"
98
+ RAIN = "RAIN"
99
+ LIGHT_RAIN = "LIGHT_RAIN"
100
+ HEAVY_RAIN = "HEAVY_RAIN"
101
+ RAIN_AND_SNOW = "RAIN_AND_SNOW"
102
+ SLEET = "SLEET"
103
+ FREEZING_RAIN = "FREEZING_RAIN"
104
+
105
+ type: PrecipitationType
106
+ """A code that indicates the type of precipitation."""
107
+
108
+ percent: int
109
+ """A percentage from 0 to 100 that indicates the chances of precipitation."""
110
+
111
+
112
+ @dataclass
113
+ class Precipitation(DataClassJSONMixin):
114
+ """Represents a set of precipitation values at a given location."""
115
+
116
+ probability: PrecipitationProbability
117
+ """The probability of precipitation (values from 0 to 100)."""
118
+
119
+ qpf: QuantitativePrecipitationForecast
120
+ """The amount of precipitation (rain or snow), measured as liquid water."""
121
+
122
+
123
+ @dataclass
124
+ class WindSpeed(DataClassJSONMixin):
125
+ """Represents the speed of the wind."""
126
+
127
+ class SpeedUnit(StrEnum):
128
+ """Represents the unit used to measure speed."""
129
+
130
+ SPEED_UNIT_UNSPECIFIED = "SPEED_UNIT_UNSPECIFIED"
131
+ KILOMETERS_PER_HOUR = "KILOMETERS_PER_HOUR"
132
+ MILES_PER_HOUR = "MILES_PER_HOUR"
133
+
134
+ value: float
135
+ """The value of the wind speed."""
136
+
137
+ unit: SpeedUnit
138
+ """The code that represents the unit used to measure the wind speed."""
139
+
140
+
141
+ @dataclass
142
+ class WindDirection(DataClassJSONMixin):
143
+ """Represents the direction from which the wind originates."""
144
+
145
+ class CardinalDirection(StrEnum):
146
+ """Represents a cardinal direction (including ordinal directions)."""
147
+
148
+ CARDINAL_DIRECTION_UNSPECIFIED = "CARDINAL_DIRECTION_UNSPECIFIED"
149
+ NORTH = "NORTH"
150
+ NORTH_NORTHEAST = "NORTH_NORTHEAST"
151
+ NORTHEAST = "NORTHEAST"
152
+ EAST_NORTHEAST = "EAST_NORTHEAST"
153
+ EAST = "EAST"
154
+ EAST_SOUTHEAST = "EAST_SOUTHEAST"
155
+ SOUTHEAST = "SOUTHEAST"
156
+ SOUTH_SOUTHEAST = "SOUTH_SOUTHEAST"
157
+ SOUTH = "SOUTH"
158
+ SOUTH_SOUTHWEST = "SOUTH_SOUTHWEST"
159
+ SOUTHWEST = "SOUTHWEST"
160
+ WEST_SOUTHWEST = "WEST_SOUTHWEST"
161
+ WEST = "WEST"
162
+ WEST_NORTHWEST = "WEST_NORTHWEST"
163
+ NORTHWEST = "NORTHWEST"
164
+ NORTH_NORTHWEST = "NORTH_NORTHWEST"
165
+
166
+ degrees: int
167
+ """The direction of the wind in degrees (values from 0 to 360)."""
168
+
169
+ cardinal: CardinalDirection
170
+ """The code that represents the cardinal direction from which the wind is blowing."""
171
+
172
+
173
+ @dataclass
174
+ class Wind(DataClassJSONMixin):
175
+ """Represents a set of wind properties."""
176
+
177
+ direction: WindDirection
178
+ """The direction of the wind, the angle it is coming from."""
179
+
180
+ speed: WindSpeed
181
+ """The speed of the wind."""
182
+
183
+ gust: WindSpeed
184
+ """The wind gust (sudden increase in the wind speed)."""
185
+
186
+
187
+ @dataclass
188
+ class Visibility(DataClassJSONMixin):
189
+ """Represents visibility conditions, the distance at which objects can be discerned."""
190
+
191
+ class Unit(StrEnum):
192
+ """Represents the unit used to measure the visibility distance."""
193
+
194
+ UNIT_UNSPECIFIED = "UNIT_UNSPECIFIED"
195
+ KILOMETERS = "KILOMETERS"
196
+ MILES = "MILES"
197
+
198
+ distance: float
199
+ """The visibility distance in the specified unit."""
200
+
201
+ unit: Unit
202
+ """The code that represents the unit used to measure the distance."""
203
+
204
+
205
+ @dataclass
206
+ class WeatherCondition(DataClassJSONMixin):
207
+ """Represents a weather condition for a given location at a given period of time."""
208
+
209
+ class Type(StrEnum):
210
+ """Marks the weather condition type in a forecast element's context."""
211
+
212
+ TYPE_UNSPECIFIED = "TYPE_UNSPECIFIED"
213
+ CLEAR = "CLEAR"
214
+ MOSTLY_CLEAR = "MOSTLY_CLEAR"
215
+ PARTLY_CLOUDY = "PARTLY_CLOUDY"
216
+ MOSTLY_CLOUDY = "MOSTLY_CLOUDY"
217
+ CLOUDY = "CLOUDY"
218
+ WINDY = "WINDY"
219
+ WIND_AND_RAIN = "WIND_AND_RAIN"
220
+ LIGHT_RAIN_SHOWERS = "LIGHT_RAIN_SHOWERS"
221
+ CHANCE_OF_SHOWERS = "CHANCE_OF_SHOWERS"
222
+ SCATTERED_SHOWERS = "SCATTERED_SHOWERS"
223
+ RAIN_SHOWERS = "RAIN_SHOWERS"
224
+ HEAVY_RAIN_SHOWERS = "HEAVY_RAIN_SHOWERS"
225
+ LIGHT_TO_MODERATE_RAIN = "LIGHT_TO_MODERATE_RAIN"
226
+ MODERATE_TO_HEAVY_RAIN = "MODERATE_TO_HEAVY_RAIN"
227
+ RAIN = "RAIN"
228
+ LIGHT_RAIN = "LIGHT_RAIN"
229
+ HEAVY_RAIN = "HEAVY_RAIN"
230
+ RAIN_PERIODICALLY_HEAVY = "RAIN_PERIODICALLY_HEAVY"
231
+ LIGHT_SNOW_SHOWERS = "LIGHT_SNOW_SHOWERS"
232
+ CHANCE_OF_SNOW_SHOWERS = "CHANCE_OF_SNOW_SHOWERS"
233
+ SCATTERED_SNOW_SHOWERS = "SCATTERED_SNOW_SHOWERS"
234
+ SNOW_SHOWERS = "SNOW_SHOWERS"
235
+ HEAVY_SNOW_SHOWERS = "HEAVY_SNOW_SHOWERS"
236
+ LIGHT_TO_MODERATE_SNOW = "LIGHT_TO_MODERATE_SNOW"
237
+ MODERATE_TO_HEAVY_SNOW = "MODERATE_TO_HEAVY_SNOW"
238
+ SNOW = "SNOW"
239
+ LIGHT_SNOW = "LIGHT_SNOW"
240
+ HEAVY_SNOW = "HEAVY_SNOW"
241
+ SNOWSTORM = "SNOWSTORM"
242
+ SNOW_PERIODICALLY_HEAVY = "SNOW_PERIODICALLY_HEAVY"
243
+ HEAVY_SNOW_STORM = "HEAVY_SNOW_STORM"
244
+ BLOWING_SNOW = "BLOWING_SNOW"
245
+ RAIN_AND_SNOW = "RAIN_AND_SNOW"
246
+ HAIL = "HAIL"
247
+ HAIL_SHOWERS = "HAIL_SHOWERS"
248
+ THUNDERSTORM = "THUNDERSTORM"
249
+ THUNDERSHOWER = "THUNDERSHOWER"
250
+ LIGHT_THUNDERSTORM_RAIN = "LIGHT_THUNDERSTORM_RAIN"
251
+ SCATTERED_THUNDERSTORMS = "SCATTERED_THUNDERSTORMS"
252
+ HEAVY_THUNDERSTORM = "HEAVY_THUNDERSTORM"
253
+
254
+ icon_base_uri: str = field(metadata={"alias": "iconBaseUri"})
255
+ """The base URI for the icon not including the file type extension."""
256
+
257
+ description: LocalizedText
258
+ """The textual description for this weather condition (localized)."""
259
+
260
+ type: Type
261
+ """The type of weather condition."""
262
+
263
+
264
+ @dataclass
265
+ class IceThickness(DataClassJSONMixin):
266
+ """Represents ice thickness conditions."""
267
+
268
+ class Unit(StrEnum):
269
+ """Represents the unit used to measure the ice thickness."""
270
+
271
+ UNIT_UNSPECIFIED = "UNIT_UNSPECIFIED"
272
+ MILLIMETERS = "MILLIMETERS"
273
+ INCHES = "INCHES"
274
+
275
+ thickness: float
276
+ """The ice thickness value."""
277
+
278
+ unit: Unit
279
+ """The code that represents the unit used to measure the ice thickness."""
280
+
281
+
282
+ @dataclass
283
+ class CurrentConditionsHistory(DataClassJSONMixin):
284
+ """Represents a set of changes in the current conditions over the last 24 hours."""
285
+
286
+ temperature_change: Temperature = field(metadata={"alias": "temperatureChange"})
287
+ """The current temperature minus the temperature 24 hours ago."""
288
+
289
+ max_temperature: Temperature = field(metadata={"alias": "maxTemperature"})
290
+ """The maximum (high) temperature in the past 24 hours."""
291
+
292
+ min_temperature: Temperature = field(metadata={"alias": "minTemperature"})
293
+ """The minimum (low) temperature in the past 24 hours."""
294
+
295
+ qpf: QuantitativePrecipitationForecast
296
+ """The amount of precipitation (rain or snow) accumulated over the last 24 hours."""
297
+
298
+
299
+ @dataclass
300
+ class CurrentConditionsResponse(DataClassJSONMixin):
301
+ """Response model for the currentConditions.lookup method."""
302
+
303
+ current_time: str = field(metadata={"alias": "currentTime"})
304
+ """Current time (UTC) associated with the returned data."""
305
+
306
+ time_zone: TimeZone = field(metadata={"alias": "timeZone"})
307
+ """The time zone at the requested location."""
308
+
309
+ weather_condition: WeatherCondition = field(metadata={"alias": "weatherCondition"})
310
+ """The current weather condition."""
311
+
312
+ temperature: Temperature
313
+ """The current temperature."""
314
+
315
+ feels_like_temperature: Temperature = field(
316
+ metadata={"alias": "feelsLikeTemperature"}
317
+ )
318
+ """The measure of how the temperature currently feels like."""
319
+
320
+ dew_point: Temperature = field(metadata={"alias": "dewPoint"})
321
+ """The current dew point temperature."""
322
+
323
+ heat_index: Temperature = field(metadata={"alias": "heatIndex"})
324
+ """The current heat index temperature."""
325
+
326
+ wind_chill: Temperature = field(metadata={"alias": "windChill"})
327
+ """The current wind chill, air temperature exposed on the skin."""
328
+
329
+ precipitation: Precipitation
330
+ """Current precipitation probability and accumulated amount over the last hour."""
331
+
332
+ air_pressure: AirPressure = field(metadata={"alias": "airPressure"})
333
+ """The current air pressure conditions."""
334
+
335
+ wind: Wind
336
+ """The current wind conditions."""
337
+
338
+ visibility: Visibility
339
+ """The current visibility."""
340
+
341
+ current_conditions_history: CurrentConditionsHistory = field(
342
+ metadata={"alias": "currentConditionsHistory"}
343
+ )
344
+ """The changes in the current conditions over the last 24 hours."""
345
+
346
+ is_daytime: bool = field(metadata={"alias": "isDaytime"})
347
+ """True if the current time is between local sunrise (inclusive) and sunset."""
348
+
349
+ relative_humidity: int = field(metadata={"alias": "relativeHumidity"})
350
+ """The current percent of relative humidity (0-100)."""
351
+
352
+ uv_index: int = field(metadata={"alias": "uvIndex"})
353
+ """The current ultraviolet (UV) index."""
354
+
355
+ thunderstorm_probability: int = field(metadata={"alias": "thunderstormProbability"})
356
+ """The current thunderstorm probability (0-100)."""
357
+
358
+ cloud_cover: int = field(metadata={"alias": "cloudCover"})
359
+ """The current percentage of the sky covered by clouds (0-100)."""
360
+
361
+
362
+ @dataclass
363
+ class Date(DataClassJSONMixin):
364
+ """Represents a whole or partial calendar date."""
365
+
366
+ year: int
367
+ """Year of the date. Must be from 1 to 9999, or 0."""
368
+
369
+ month: int
370
+ """Month of a year. Must be from 1 to 12, or 0."""
371
+
372
+ day: int
373
+ """Day of a month. Must be from 1 to 31, or 0."""
374
+
375
+
376
+ @dataclass
377
+ class ForecastDayPart(DataClassJSONMixin):
378
+ """Represents a forecast record for a part of the day (daytime or nighttime)."""
379
+
380
+ interval: Interval
381
+ """The UTC date and time when this part of the day starts and ends."""
382
+
383
+ weather_condition: WeatherCondition = field(metadata={"alias": "weatherCondition"})
384
+ """The forecasted weather condition."""
385
+
386
+ precipitation: Precipitation
387
+ """The forecasted precipitation."""
388
+
389
+ wind: Wind
390
+ """The average wind direction and maximum speed and gust."""
391
+
392
+ relative_humidity: int = field(metadata={"alias": "relativeHumidity"})
393
+ """The forecasted percent of relative humidity (0-100)."""
394
+
395
+ uv_index: int = field(metadata={"alias": "uvIndex"})
396
+ """The maximum forecasted ultraviolet (UV) index."""
397
+
398
+ thunderstorm_probability: int = field(metadata={"alias": "thunderstormProbability"})
399
+ """The average thunderstorm probability."""
400
+
401
+ cloud_cover: int = field(metadata={"alias": "cloudCover"})
402
+ """Average cloud cover percent."""
403
+
404
+
405
+ @dataclass
406
+ class SunEvents(DataClassJSONMixin):
407
+ """Represents the events related to the sun (e.g. sunrise, sunset)."""
408
+
409
+ sunrise_time: str | None = field(default=None, metadata={"alias": "sunriseTime"})
410
+ """The time when the sun rises. Unset in polar regions."""
411
+
412
+ sunset_time: str | None = field(default=None, metadata={"alias": "sunsetTime"})
413
+ """The time when the sun sets. Unset in polar regions."""
414
+
415
+
416
+ @dataclass
417
+ class MoonEvents(DataClassJSONMixin):
418
+ """Represents the events related to the moon (e.g. moonrise, moonset)."""
419
+
420
+ class MoonPhase(StrEnum):
421
+ """Marks the moon phase (a.k.a. lunar phase)."""
422
+
423
+ MOON_PHASE_UNSPECIFIED = "MOON_PHASE_UNSPECIFIED"
424
+ NEW_MOON = "NEW_MOON"
425
+ WAXING_CRESCENT = "WAXING_CRESCENT"
426
+ FIRST_QUARTER = "FIRST_QUARTER"
427
+ WAXING_GIBBOUS = "WAXING_GIBBOUS"
428
+ FULL_MOON = "FULL_MOON"
429
+ WANING_GIBBOUS = "WANING_GIBBOUS"
430
+ LAST_QUARTER = "LAST_QUARTER"
431
+ WANING_CRESCENT = "WANING_CRESCENT"
432
+
433
+ moonrise_times: list[str] = field(metadata={"alias": "moonriseTimes"})
434
+ """The time(s) when the upper limb of the moon appears above the horizon."""
435
+
436
+ moonset_times: list[str] = field(metadata={"alias": "moonsetTimes"})
437
+ """The time(s) when the upper limb of the moon disappears below the horizon."""
438
+
439
+ moon_phase: MoonPhase = field(metadata={"alias": "moonPhase"})
440
+ """The moon phase (a.k.a. lunar phase)."""
441
+
442
+
443
+ @dataclass
444
+ class ForecastDay(DataClassJSONMixin):
445
+ """Represents a daily forecast record at a given location."""
446
+
447
+ interval: Interval
448
+ """The UTC time interval when this forecasted day starts and ends."""
449
+
450
+ display_date: Date = field(metadata={"alias": "displayDate"})
451
+ """The local date in the time zone of the location."""
452
+
453
+ daytime_forecast: ForecastDayPart = field(metadata={"alias": "daytimeForecast"})
454
+ """The forecasted weather conditions for the daytime part of the day."""
455
+
456
+ nighttime_forecast: ForecastDayPart = field(metadata={"alias": "nighttimeForecast"})
457
+ """The forecasted weather conditions for the nighttime part of the day."""
458
+
459
+ max_temperature: Temperature = field(metadata={"alias": "maxTemperature"})
460
+ """The maximum (high) temperature throughout the day."""
461
+
462
+ min_temperature: Temperature = field(metadata={"alias": "minTemperature"})
463
+ """The minimum (low) temperature throughout the day."""
464
+
465
+ feels_like_max_temperature: Temperature = field(
466
+ metadata={"alias": "feelsLikeMaxTemperature"}
467
+ )
468
+ """The maximum (high) feels-like temperature throughout the day."""
469
+
470
+ feels_like_min_temperature: Temperature = field(
471
+ metadata={"alias": "feelsLikeMinTemperature"}
472
+ )
473
+ """The minimum (low) feels-like temperature throughout the day."""
474
+
475
+ max_heat_index: Temperature = field(metadata={"alias": "maxHeatIndex"})
476
+ """The maximum heat index temperature throughout the day."""
477
+
478
+ sun_events: SunEvents = field(metadata={"alias": "sunEvents"})
479
+ """The events related to the sun (e.g. sunrise, sunset)."""
480
+
481
+ moon_events: MoonEvents = field(metadata={"alias": "moonEvents"})
482
+ """The events related to the moon (e.g. moonrise, moonset)."""
483
+
484
+ ice_thickness: IceThickness | None = field(
485
+ default=None, metadata={"alias": "iceThickness"}
486
+ )
487
+ """The accumulated amount of ice throughout the entire day."""
488
+
489
+
490
+ @dataclass
491
+ class DailyForecastResponse(DataClassJSONMixin):
492
+ """Response model for the forecast.days.lookup method."""
493
+
494
+ forecast_days: list[ForecastDay] = field(metadata={"alias": "forecastDays"})
495
+ """The daily forecast records."""
496
+
497
+ time_zone: TimeZone = field(metadata={"alias": "timeZone"})
498
+ """The time zone at the requested location."""
499
+
500
+ next_page_token: str | None = field(
501
+ default=None, metadata={"alias": "nextPageToken"}
502
+ )
503
+ """The token to retrieve the next page."""
504
+
505
+
506
+ @dataclass
507
+ class DateTime(DataClassJSONMixin):
508
+ """Represents civil time (or occasionally physical time)."""
509
+
510
+ year: int | None = None
511
+ """Optional. Year of date. Must be from 1 to 9999, or 0."""
512
+
513
+ month: int | None = None
514
+ """Optional. Month of year. Must be from 1 to 12, or 0."""
515
+
516
+ day: int | None = None
517
+ """Optional. Day of month. Must be from 1 to 31, or 0."""
518
+
519
+ hours: int | None = None
520
+ """Optional. Hours of day in 24 hour format. Should be from 0 to 23."""
521
+
522
+ minutes: int | None = None
523
+ """Optional. Minutes of hour of day. Must be from 0 to 59."""
524
+
525
+ seconds: int | None = None
526
+ """Optional. Seconds of minutes of the time. Must normally be from 0 to 59."""
527
+
528
+ nanos: int | None = None
529
+ """Optional. Fractions of seconds in nanoseconds."""
530
+
531
+ utc_offset: str | None = field(default=None, metadata={"alias": "utcOffset"})
532
+ """Optional. UTC offset. Must be whole seconds, between -18 and +18 hours."""
533
+
534
+ time_zone: TimeZone | None = field(default=None, metadata={"alias": "timeZone"})
535
+ """Optional. Time zone."""
536
+
537
+
538
+ @dataclass
539
+ class ForecastHour(DataClassJSONMixin):
540
+ """Represents an hourly forecast record at a given location."""
541
+
542
+ interval: Interval
543
+ """The one hour interval (in UTC time) this forecast data is valid for."""
544
+
545
+ display_date_time: DateTime = field(metadata={"alias": "displayDateTime"})
546
+ """The local date and time in the time zone of the location."""
547
+
548
+ weather_condition: WeatherCondition = field(metadata={"alias": "weatherCondition"})
549
+ """The forecasted weather condition."""
550
+
551
+ temperature: Temperature
552
+ """The forecasted temperature."""
553
+
554
+ feels_like_temperature: Temperature = field(
555
+ metadata={"alias": "feelsLikeTemperature"}
556
+ )
557
+ """The measure of how the temperature will feel like."""
558
+
559
+ dew_point: Temperature = field(metadata={"alias": "dewPoint"})
560
+ """The forecasted dew point temperature."""
561
+
562
+ heat_index: Temperature = field(metadata={"alias": "heatIndex"})
563
+ """The forecasted heat index temperature."""
564
+
565
+ wind_chill: Temperature = field(metadata={"alias": "windChill"})
566
+ """The forecasted wind chill, air temperature exposed on the skin."""
567
+
568
+ wet_bulb_temperature: Temperature = field(metadata={"alias": "wetBulbTemperature"})
569
+ """The forecasted wet bulb temperature, lowest temperature achievable by evaporating water."""
570
+
571
+ precipitation: Precipitation
572
+ """The forecasted precipitation probability and amount over the last hour."""
573
+
574
+ air_pressure: AirPressure = field(metadata={"alias": "airPressure"})
575
+ """The forecasted air pressure conditions."""
576
+
577
+ wind: Wind
578
+ """The forecasted wind conditions."""
579
+
580
+ visibility: Visibility
581
+ """The forecasted visibility."""
582
+
583
+ is_daytime: bool = field(metadata={"alias": "isDaytime"})
584
+ """True if this hour is between the local sunrise (inclusive) and sunset."""
585
+
586
+ relative_humidity: int = field(metadata={"alias": "relativeHumidity"})
587
+ """The forecasted percent of relative humidity (0-100)."""
588
+
589
+ uv_index: int = field(metadata={"alias": "uvIndex"})
590
+ """The forecasted ultraviolet (UV) index."""
591
+
592
+ thunderstorm_probability: int = field(metadata={"alias": "thunderstormProbability"})
593
+ """The forecasted thunderstorm probability (0-100)."""
594
+
595
+ cloud_cover: int = field(metadata={"alias": "cloudCover"})
596
+ """The forecasted percentage of the sky covered by clouds (0-100)."""
597
+
598
+ ice_thickness: IceThickness | None = field(
599
+ default=None, metadata={"alias": "iceThickness"}
600
+ )
601
+ """The forecasted ice thickness."""
602
+
603
+
604
+ @dataclass
605
+ class HourlyForecastResponse(DataClassJSONMixin):
606
+ """Response model for the forecast.hours.lookup method."""
607
+
608
+ forecast_hours: list[ForecastHour] = field(metadata={"alias": "forecastHours"})
609
+ """The hourly forecast records."""
610
+
611
+ time_zone: TimeZone = field(metadata={"alias": "timeZone"})
612
+ """The time zone at the requested location."""
613
+
614
+ next_page_token: str | None = field(
615
+ default=None, metadata={"alias": "nextPageToken"}
616
+ )
617
+ """The token to retrieve the next page."""
@@ -1,15 +1,16 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-google-weather-api
3
- Version: 0.0.2
3
+ Version: 0.0.3
4
4
  Summary: A python client library for Google Weather API
5
5
  Author-email: tronikos <tronikos@gmail.com>
6
6
  License-Expression: Apache-2.0
7
7
  Project-URL: Homepage, https://github.com/tronikos/python-google-weather-api
8
8
  Project-URL: Bug Tracker, https://github.com/tronikos/python-google-weather-api/issues
9
- Requires-Python: >=3.10
9
+ Requires-Python: >=3.11
10
10
  Description-Content-Type: text/markdown
11
11
  License-File: LICENSE
12
12
  Requires-Dist: aiohttp>=3.8
13
+ Requires-Dist: mashumaro
13
14
  Provides-Extra: dev
14
15
  Requires-Dist: pytest>=7; extra == "dev"
15
16
  Dynamic: license-file
@@ -0,0 +1,10 @@
1
+ google_weather_api/__init__.py,sha256=-QhZtqKdRYohLgaw5DwSa81EnrRWQ6Wb0j5A0SS5Qcs,1465
2
+ google_weather_api/api.py,sha256=_exNxMthEln2iho93Uk_P7-zKJDj-oAZu77yQPau_zk,4271
3
+ google_weather_api/exceptions.py,sha256=RnF47YwX0K-COrEi1E9r5xoBXPPOHBGr_unpHzlje2U,409
4
+ google_weather_api/model.py,sha256=yGQ1qquAKuYloS1nYgCd8-LQ_Ta_zC4jMOkq149_WNI,21868
5
+ google_weather_api/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
+ python_google_weather_api-0.0.3.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
7
+ python_google_weather_api-0.0.3.dist-info/METADATA,sha256=AwaW5jWlszGwUTnpEmghiR3k0tqpQd05Cfqzs1puZqw,1498
8
+ python_google_weather_api-0.0.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
9
+ python_google_weather_api-0.0.3.dist-info/top_level.txt,sha256=ZkFbtKDHz3vUJhH6DGEPVLj3PPeNpR9-Wg0f4HqGD78,19
10
+ python_google_weather_api-0.0.3.dist-info/RECORD,,
@@ -1,8 +0,0 @@
1
- google_weather_api/__init__.py,sha256=StgTuTikqdXIOy3irBdYqJs-MdACKiz7rbDbwfnraVE,341
2
- google_weather_api/api.py,sha256=cxppiiV20mgh4E1a28MHTeGxbEYI7qPQB5yjVZ1OqnQ,3868
3
- google_weather_api/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
- python_google_weather_api-0.0.2.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
5
- python_google_weather_api-0.0.2.dist-info/METADATA,sha256=BWUd_LcbefaSU1k5XKVExygyi-krYqL-TAo8FDKGXEc,1473
6
- python_google_weather_api-0.0.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
7
- python_google_weather_api-0.0.2.dist-info/top_level.txt,sha256=ZkFbtKDHz3vUJhH6DGEPVLj3PPeNpR9-Wg0f4HqGD78,19
8
- python_google_weather_api-0.0.2.dist-info/RECORD,,