python-weather 2.0.5__tar.gz → 2.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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: python-weather
3
- Version: 2.0.5
3
+ Version: 2.0.7
4
4
  Summary: A free and asynchronous weather API wrapper made in Python, for Python.
5
5
  Author: null8626
6
6
  License: MIT
@@ -3,7 +3,7 @@ requires = ["setuptools"]
3
3
 
4
4
  [project]
5
5
  name = "python-weather"
6
- version = "2.0.5"
6
+ version = "2.0.7"
7
7
  description = "A free and asynchronous weather API wrapper made in Python, for Python."
8
8
  readme = "README.md"
9
9
  license = { text = "MIT" }
@@ -31,7 +31,7 @@ __title__ = 'python-weather'
31
31
  __author__ = 'null8626'
32
32
  __license__ = 'MIT'
33
33
  __copyright__ = 'Copyright (c) 2021-2024 null8626'
34
- __version__ = '2.0.5'
34
+ __version__ = '2.0.7'
35
35
  __all__ = (
36
36
  'METRIC',
37
37
  'IMPERIAL',
@@ -22,7 +22,6 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
22
  SOFTWARE.
23
23
  """
24
24
 
25
- from enum import auto
26
25
  from typing import Tuple
27
26
 
28
27
  from .errors import Error
@@ -38,7 +37,7 @@ class CustomizableBase:
38
37
  self.locale = locale
39
38
 
40
39
  @property
41
- def unit(self) -> auto:
40
+ def unit(self) -> _Unit:
42
41
  """The measuring unit used to display information in this object."""
43
42
 
44
43
  return self.__unit
@@ -68,9 +67,9 @@ class CustomizableBase:
68
67
  """
69
68
  Sets the default localization used to display information in this object.
70
69
 
71
- :param to: The new :class:`Locale` to be used to display information in this object.
70
+ :param to: The new :class:`~python_weather.enums.Locale` to be used to display information in this object.
72
71
  :type to: Locale
73
- :exception Error: If the ``to`` argument is not a part of the :class:`Locale` enum.
72
+ :exception Error: If the ``to`` argument is not a part of the :class:`~python_weather.enums.Locale` enum.
74
73
  """
75
74
 
76
75
  if not isinstance(to, Locale):
@@ -26,7 +26,6 @@ from aiohttp import ClientSession, ClientTimeout, TCPConnector
26
26
  from urllib.parse import quote_plus
27
27
  from typing import Optional, Tuple
28
28
  from asyncio import sleep
29
- from enum import auto
30
29
 
31
30
  from .errors import Error, RequestError
32
31
  from .constants import _Unit, METRIC
@@ -40,23 +39,26 @@ class Client(CustomizableBase):
40
39
  The class that lets you interact with the API.
41
40
 
42
41
  :param unit: Whether to use the metric or imperial/customary system (``IMPERIAL``). Defaults to ``METRIC``.
43
- :type unit: Optional[:py:class:`enum.auto`]
42
+ :type unit: _Unit
44
43
  :param locale: Whether to use a different locale/language as the description for the returned forecast. Defaults to ``Locale.ENGLISH``.
45
- :type locale: Optional[Locale]
46
- :param session: Whether to use an existing aiohttp client session for requesting or not. Defaults to ``None`` (creates a new one instead)
47
- :type session: Optional[:class:`aiohttp.ClientSession`]
44
+ :type locale: Locale
45
+ :param session: Whether to use an existing aiohttp client session for requesting or not. Defaults to ``None`` (creates a new one instead).
46
+ :type session: Optional[:class:`~aiohttp.ClientSession`]
47
+ :param max_retries: Maximum amount of retries upon receiving HTTP request failure before raising a :class:`~python_weather.errors.RequestError`. To have infinite retries, use ``-1`` (NOT recommended). Defaults to ``None`` (or 3 retries).
48
+ :type max_retries: Optional[:class:`int`]
48
49
 
49
- :raises Error: If ``unit`` is not ``METRIC`` or ``IMPERIAL``, or if ``locale`` is not ``None`` and not a part of the :class:`Locale` enum.
50
+ :raises Error: If ``unit`` is not ``METRIC`` or ``IMPERIAL``, or if ``locale`` is not ``None`` and not a part of the :class:`~python_weather.enums.Locale` enum.
50
51
  """
51
52
 
52
- __slots__: Tuple[str, ...] = ('__own_session', '__session')
53
+ __slots__: Tuple[str, ...] = ('__own_session', '__session', '__max_retries')
53
54
 
54
55
  def __init__(
55
56
  self,
56
57
  *,
57
- unit: Optional[auto] = METRIC,
58
- locale: Optional[Locale] = Locale.ENGLISH,
58
+ unit: _Unit = METRIC,
59
+ locale: Locale = Locale.ENGLISH,
59
60
  session: Optional[ClientSession] = None,
61
+ max_retries: Optional[int] = None,
60
62
  ):
61
63
  super().__init__(unit, locale)
62
64
 
@@ -65,6 +67,7 @@ class Client(CustomizableBase):
65
67
  timeout=ClientTimeout(total=5000.0),
66
68
  connector=TCPConnector(verify_ssl=False),
67
69
  )
70
+ self.__max_retries = max_retries or 3
68
71
 
69
72
  def __repr__(self) -> str:
70
73
  return f'<{__class__.__name__} {self.__session!r}>'
@@ -73,7 +76,7 @@ class Client(CustomizableBase):
73
76
  self,
74
77
  location: str,
75
78
  *,
76
- unit: Optional[auto] = None,
79
+ unit: Optional[_Unit] = None,
77
80
  locale: Optional[Locale] = None,
78
81
  ) -> Forecast:
79
82
  """
@@ -82,11 +85,12 @@ class Client(CustomizableBase):
82
85
  :param location: The requested location name for said weather forecast.
83
86
  :type location: str
84
87
  :param unit: Overrides the unit used by this object. Defaults to the one used by this object.
85
- :type unit: Optional[:py:class:`enum.auto`]
88
+ :type unit: Optional[``_Unit``]
86
89
  :param locale: Overrides the locale used by this object. Defaults to the one used by this object.
87
- :type locale: Optional[Locale]
90
+ :type locale: Optional[:class:`~python_weather.enums.Locale`]
88
91
 
89
- :exception Error: If the aiohttp client session used by the :class:`Client` object is already closed, if the ``unit`` argument is not ``None`` and it's also not ``METRIC`` or ``IMPERIAL``, if the ``locale`` argument is not ``None`` and it's also not a part of the :class:`Locale` enum, or if the :class:`Client` cannot send a web request to the web server.
92
+ :exception Error: If the aiohttp client session used by the :class:`~python_weather.client.Client` object is already closed, if the ``unit`` argument is not ``None`` and it's also not ``METRIC`` or ``IMPERIAL``, if the ``locale`` argument is not ``None`` and it's also not a part of the :class:`~python_weather.enums.Locale` enum.
93
+ :exception RequestError: If the :class:`~python_weather.client.Client` can't send a web request to the web server.
90
94
 
91
95
  :returns: The requested weather forecast.
92
96
  :rtype: Forecast
@@ -105,6 +109,7 @@ class Client(CustomizableBase):
105
109
 
106
110
  subdomain = f'{locale.value}.' if locale != Locale.ENGLISH else ''
107
111
  delay = 0.5
112
+ attempts = 0
108
113
 
109
114
  while True:
110
115
  try:
@@ -115,14 +120,15 @@ class Client(CustomizableBase):
115
120
 
116
121
  return Forecast(await resp.json(), unit, locale)
117
122
  except Exception as err:
118
- if delay == 4:
123
+ if attempts == self.__max_retries:
119
124
  raise RequestError(err)
120
125
 
121
126
  await sleep(delay)
127
+ attempts += 1
122
128
  delay *= 2
123
129
 
124
130
  async def close(self) -> None:
125
- """Closes the :class:`Client` object. Nothing will happen if the client uses a pre-existing :class:`aiohttp.ClientSession` or if the session is already closed."""
131
+ """Closes the :class:`~python_weather.client.Client` object. Nothing will happen if the client uses a pre-existing :class:`~aiohttp.ClientSession` or if the session is already closed."""
126
132
 
127
133
  if self.__own_session and not self.__session.closed:
128
134
  await self.__session.close()
@@ -130,5 +136,5 @@ class Client(CustomizableBase):
130
136
  async def __aenter__(self) -> 'Client':
131
137
  return self
132
138
 
133
- async def __aexit__(self, *_, **__):
139
+ async def __aexit__(self, *_, **__) -> None:
134
140
  await self.close()
@@ -186,14 +186,17 @@ class WindDirection(BasicEnum):
186
186
  else:
187
187
  return 326.25 < other <= 348.75
188
188
 
189
+ def __int__(self) -> int:
190
+ return int(self.degrees)
191
+
189
192
  def __float__(self) -> float:
190
- return self.__degrees
193
+ return self.degrees
191
194
 
192
195
  @property
193
196
  def emoji(self) -> str:
194
197
  """The emoji representing this enum."""
195
198
 
196
- return WIND_DIRECTION_EMOJIS[int(((self.__degrees + 22.5) % 360) / 45.0)]
199
+ return WIND_DIRECTION_EMOJIS[int(((self.degrees + 22.5) % 360) / 45.0)]
197
200
 
198
201
 
199
202
  class Locale(Enum):
@@ -308,38 +311,29 @@ class Kind(BasicEnum):
308
311
 
309
312
  @classmethod
310
313
  def _missing_(self, value: int) -> 'Kind':
311
- if value == 248 or value == 260:
314
+ if value in (248, 260):
312
315
  return self.FOG
313
- elif value == 263 or value == 353:
316
+ elif value in (263, 353):
314
317
  return self.LIGHT_SHOWERS
315
- elif value == 362 or value == 365 or value == 374:
318
+ elif value in (362, 365, 374):
316
319
  return self.LIGHT_SLEET_SHOWERS
317
- elif (
318
- value == 185
319
- or value == 281
320
- or value == 284
321
- or value == 311
322
- or value == 314
323
- or value == 317
324
- or value == 350
325
- or value == 377
326
- ):
320
+ elif value in (185, 281, 284, 311, 314, 317, 350, 377):
327
321
  return self.LIGHT_SLEET
328
322
  elif value == 386:
329
323
  return self.THUNDERY_SHOWERS
330
324
  elif value == 320:
331
325
  return self.LIGHT_SNOW
332
- elif value == 329 or value == 332 or value == 338:
326
+ elif value in (329, 332, 338):
333
327
  return self.HEAVY_SNOW
334
- elif value == 293 or value == 296:
328
+ elif value in (293, 296):
335
329
  return self.LIGHT_RAIN
336
- elif value == 305 or value == 356:
330
+ elif value in (305, 356):
337
331
  return self.HEAVY_SHOWERS
338
- elif value == 308 or value == 359:
332
+ elif value in (308, 359):
339
333
  return self.HEAVY_RAIN
340
- elif value == 326 or value == 368:
334
+ elif value in (326, 368):
341
335
  return self.LIGHT_SNOW_SHOWERS
342
- elif value == 371 or value == 395:
336
+ elif value in (371, 395):
343
337
  return self.HEAVY_SNOW_SHOWERS
344
338
 
345
339
  @property
@@ -32,12 +32,12 @@ class Error(Exception):
32
32
 
33
33
 
34
34
  class RequestError(Error):
35
- """Thrown upon HTTP request failure. Extends :class:`Error`."""
35
+ """Thrown upon HTTP request failure. Extends :class:`~python_weather.errors.Error`."""
36
36
 
37
37
  __slots__: Tuple[str, ...] = ('source',)
38
38
 
39
39
  source: Exception
40
- """The :class:`Exception` instance causing this exception."""
40
+ """The :py:class:`Exception` instance causing this exception."""
41
41
 
42
42
  def __init__(self, source: Exception):
43
43
  self.source = source
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: python-weather
3
- Version: 2.0.5
3
+ Version: 2.0.7
4
4
  Summary: A free and asynchronous weather API wrapper made in Python, for Python.
5
5
  Author: null8626
6
6
  License: MIT
File without changes
File without changes
File without changes