python-google-weather-api 0.0.6__tar.gz → 0.0.7__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.
- {python_google_weather_api-0.0.6/src/python_google_weather_api.egg-info → python_google_weather_api-0.0.7}/PKG-INFO +3 -1
- {python_google_weather_api-0.0.6 → python_google_weather_api-0.0.7}/pyproject.toml +11 -1
- {python_google_weather_api-0.0.6 → python_google_weather_api-0.0.7}/src/google_weather_api/api.py +28 -5
- {python_google_weather_api-0.0.6 → python_google_weather_api-0.0.7}/src/google_weather_api/exceptions.py +17 -17
- {python_google_weather_api-0.0.6 → python_google_weather_api-0.0.7}/src/google_weather_api/model.py +641 -605
- {python_google_weather_api-0.0.6 → python_google_weather_api-0.0.7/src/python_google_weather_api.egg-info}/PKG-INFO +3 -1
- {python_google_weather_api-0.0.6 → python_google_weather_api-0.0.7}/src/python_google_weather_api.egg-info/SOURCES.txt +2 -1
- {python_google_weather_api-0.0.6 → python_google_weather_api-0.0.7}/src/python_google_weather_api.egg-info/requires.txt +2 -0
- python_google_weather_api-0.0.7/tests/test_api.py +269 -0
- python_google_weather_api-0.0.7/tests/test_model.py +143 -0
- python_google_weather_api-0.0.6/tests/test_api.py +0 -6
- {python_google_weather_api-0.0.6 → python_google_weather_api-0.0.7}/LICENSE +0 -0
- {python_google_weather_api-0.0.6 → python_google_weather_api-0.0.7}/README.md +0 -0
- {python_google_weather_api-0.0.6 → python_google_weather_api-0.0.7}/setup.cfg +0 -0
- {python_google_weather_api-0.0.6 → python_google_weather_api-0.0.7}/src/google_weather_api/__init__.py +0 -0
- {python_google_weather_api-0.0.6 → python_google_weather_api-0.0.7}/src/google_weather_api/py.typed +0 -0
- {python_google_weather_api-0.0.6 → python_google_weather_api-0.0.7}/src/python_google_weather_api.egg-info/dependency_links.txt +0 -0
- {python_google_weather_api-0.0.6 → python_google_weather_api-0.0.7}/src/python_google_weather_api.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: python-google-weather-api
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.7
|
|
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
|
|
@@ -13,6 +13,8 @@ Requires-Dist: aiohttp>=3.8
|
|
|
13
13
|
Requires-Dist: mashumaro
|
|
14
14
|
Provides-Extra: test
|
|
15
15
|
Requires-Dist: pytest; extra == "test"
|
|
16
|
+
Requires-Dist: pytest-asyncio; extra == "test"
|
|
17
|
+
Requires-Dist: pytest-cov; extra == "test"
|
|
16
18
|
Dynamic: license-file
|
|
17
19
|
|
|
18
20
|
# python-google-weather-api
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "python-google-weather-api"
|
|
3
|
-
version = "0.0.
|
|
3
|
+
version = "0.0.7"
|
|
4
4
|
license = "Apache-2.0"
|
|
5
5
|
authors = [
|
|
6
6
|
{ name="tronikos", email="tronikos@gmail.com" },
|
|
@@ -16,6 +16,8 @@ dependencies = [
|
|
|
16
16
|
[project.optional-dependencies]
|
|
17
17
|
test = [
|
|
18
18
|
"pytest",
|
|
19
|
+
"pytest-asyncio",
|
|
20
|
+
"pytest-cov",
|
|
19
21
|
]
|
|
20
22
|
|
|
21
23
|
|
|
@@ -27,6 +29,13 @@ test = [
|
|
|
27
29
|
requires = ["setuptools"]
|
|
28
30
|
build-backend = "setuptools.build_meta"
|
|
29
31
|
|
|
32
|
+
[tool.pytest.ini_options]
|
|
33
|
+
asyncio_mode = "auto"
|
|
34
|
+
addopts = "--cov=google_weather_api --cov-report=term-missing --cov-fail-under=90"
|
|
35
|
+
|
|
36
|
+
[tool.coverage.run]
|
|
37
|
+
branch = true
|
|
38
|
+
|
|
30
39
|
[tool.ruff]
|
|
31
40
|
target-version = "py311"
|
|
32
41
|
line-length = 127
|
|
@@ -64,6 +73,7 @@ ignore = [
|
|
|
64
73
|
"D203", # 1 blank line required before class docstring
|
|
65
74
|
"D213", # Multi-line docstring summary should start at the second line
|
|
66
75
|
"PLR0913", # Too many arguments in function definition
|
|
76
|
+
"PLR0917", # Too many positional arguments in function definition
|
|
67
77
|
"PLR1714", # Consider merging multiple comparisons
|
|
68
78
|
"PLR2004", # Magic value used in comparison
|
|
69
79
|
"TRY003", # Avoid specifying long messages outside the exception class
|
{python_google_weather_api-0.0.6 → python_google_weather_api-0.0.7}/src/google_weather_api/api.py
RENAMED
|
@@ -53,11 +53,12 @@ class GoogleWeatherApi:
|
|
|
53
53
|
headers[aiohttp.hdrs.REFERER] = self.referrer
|
|
54
54
|
params = {
|
|
55
55
|
**params,
|
|
56
|
-
"key": self.api_key,
|
|
57
56
|
"language_code": self.language_code,
|
|
58
57
|
"units_system": self.units_system,
|
|
59
58
|
}
|
|
59
|
+
# Log before adding the API key so it doesn't end up in debug logs.
|
|
60
60
|
_LOGGER.debug("GET %s with params: %s", url, params)
|
|
61
|
+
params["key"] = self.api_key
|
|
61
62
|
try:
|
|
62
63
|
async with self.session.get(
|
|
63
64
|
url,
|
|
@@ -87,6 +88,26 @@ class GoogleWeatherApi:
|
|
|
87
88
|
except aiohttp.ClientError as err:
|
|
88
89
|
raise GoogleWeatherApiConnectionError(err) from err
|
|
89
90
|
|
|
91
|
+
async def _async_get_all_pages(
|
|
92
|
+
self, endpoint: str, params: dict[str, Any], records_key: str, limit: int
|
|
93
|
+
) -> dict[str, Any]:
|
|
94
|
+
"""Perform a GET request, following pagination until `limit` records are collected.
|
|
95
|
+
|
|
96
|
+
The API caps the number of records it returns per page (24 for hourly forecasts),
|
|
97
|
+
regardless of the requested page size, so a single request is not enough.
|
|
98
|
+
"""
|
|
99
|
+
params = {**params, "page_size": limit}
|
|
100
|
+
data = await self._async_get(endpoint, params)
|
|
101
|
+
records: list[Any] = data.get(records_key, [])
|
|
102
|
+
while len(records) < limit and (page_token := data.get("nextPageToken")):
|
|
103
|
+
data = await self._async_get(endpoint, {**params, "page_token": page_token})
|
|
104
|
+
page_records: list[Any] = data.get(records_key, [])
|
|
105
|
+
if not page_records:
|
|
106
|
+
break
|
|
107
|
+
records.extend(page_records)
|
|
108
|
+
data[records_key] = records[:limit]
|
|
109
|
+
return data
|
|
110
|
+
|
|
90
111
|
async def async_get_current_conditions(self, latitude: float, longitude: float) -> CurrentConditionsResponse:
|
|
91
112
|
"""Fetch current weather conditions.
|
|
92
113
|
|
|
@@ -106,14 +127,15 @@ class GoogleWeatherApi:
|
|
|
106
127
|
|
|
107
128
|
See https://developers.google.com/maps/documentation/weather/reference/rest/v1/forecast.hours/lookup
|
|
108
129
|
"""
|
|
109
|
-
data = await self.
|
|
130
|
+
data = await self._async_get_all_pages(
|
|
110
131
|
"forecast/hours:lookup",
|
|
111
132
|
{
|
|
112
133
|
"location.latitude": latitude,
|
|
113
134
|
"location.longitude": longitude,
|
|
114
135
|
"hours": hours,
|
|
115
|
-
"page_size": hours,
|
|
116
136
|
},
|
|
137
|
+
"forecastHours",
|
|
138
|
+
hours,
|
|
117
139
|
)
|
|
118
140
|
return HourlyForecastResponse.from_dict(data)
|
|
119
141
|
|
|
@@ -122,13 +144,14 @@ class GoogleWeatherApi:
|
|
|
122
144
|
|
|
123
145
|
See https://developers.google.com/maps/documentation/weather/reference/rest/v1/forecast.days/lookup
|
|
124
146
|
"""
|
|
125
|
-
data = await self.
|
|
147
|
+
data = await self._async_get_all_pages(
|
|
126
148
|
"forecast/days:lookup",
|
|
127
149
|
{
|
|
128
150
|
"location.latitude": latitude,
|
|
129
151
|
"location.longitude": longitude,
|
|
130
152
|
"days": days,
|
|
131
|
-
"page_size": days,
|
|
132
153
|
},
|
|
154
|
+
"forecastDays",
|
|
155
|
+
days,
|
|
133
156
|
)
|
|
134
157
|
return DailyForecastResponse.from_dict(data)
|
|
@@ -1,17 +1,17 @@
|
|
|
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 GoogleWeatherApiAuthError(GoogleWeatherApiError):
|
|
13
|
-
"""Exception raised for authentication errors in the Google Weather API."""
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
class GoogleWeatherApiResponseError(GoogleWeatherApiError):
|
|
17
|
-
"""Exception raised for errors in the Google Weather API response."""
|
|
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 GoogleWeatherApiAuthError(GoogleWeatherApiError):
|
|
13
|
+
"""Exception raised for authentication errors in the Google Weather API."""
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class GoogleWeatherApiResponseError(GoogleWeatherApiError):
|
|
17
|
+
"""Exception raised for errors in the Google Weather API response."""
|