dycw-utilities 0.114.3__py3-none-any.whl → 0.114.4__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,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dycw-utilities
3
- Version: 0.114.3
3
+ Version: 0.114.4
4
4
  Author-email: Derek Wan <d.wan@icloud.com>
5
5
  License-File: LICENSE
6
6
  Requires-Python: >=3.12
@@ -1,7 +1,7 @@
1
- utilities/__init__.py,sha256=SWDkfIOyhgygmyWsgThn0Boll445H7CW7YAsVtIjpMY,60
1
+ utilities/__init__.py,sha256=tJolUL8rPFxB39Y9tDrGxZfStHDwKSYDM0b1ZF2U11Q,60
2
2
  utilities/altair.py,sha256=Gpja-flOo-Db0PIPJLJsgzAlXWoKUjPU1qY-DQ829ek,9156
3
3
  utilities/astor.py,sha256=xuDUkjq0-b6fhtwjhbnebzbqQZAjMSHR1IIS5uOodVg,777
4
- utilities/asyncio.py,sha256=Hysj5gHlizHUhBo3D9Czo5wciJxNoO5HrhXZ4hbC-sk,21478
4
+ utilities/asyncio.py,sha256=d_z20q4pFhjMBruepHKjvbWVFF-89VpP6_o9ZFQIe9k,21508
5
5
  utilities/atomicwrites.py,sha256=geFjn9Pwn-tTrtoGjDDxWli9NqbYfy3gGL6ZBctiqSo,5393
6
6
  utilities/atools.py,sha256=IYMuFSFGSKyuQmqD6v5IUtDlz8PPw0Sr87Cub_gRU3M,1168
7
7
  utilities/cachetools.py,sha256=C1zqOg7BYz0IfQFK8e3qaDDgEZxDpo47F15RTfJM37Q,2910
@@ -64,7 +64,7 @@ utilities/rich.py,sha256=t50MwwVBsoOLxzmeVFSVpjno4OW6Ufum32skXbV8-Bs,1911
64
64
  utilities/scipy.py,sha256=X6ROnHwiUhAmPhM0jkfEh0-Fd9iRvwiqtCQMOLmOQF8,945
65
65
  utilities/sentinel.py,sha256=3jIwgpMekWgDAxPDA_hXMP2St43cPhciKN3LWiZ7kv0,1248
66
66
  utilities/shelve.py,sha256=HZsMwK4tcIfg3sh0gApx4-yjQnrY4o3V3ZRimvRhoW0,738
67
- utilities/slack_sdk.py,sha256=Gbla983KulSSXnNyzaXgYQLKoq84KvLH8SdhxU-jQ0Q,4126
67
+ utilities/slack_sdk.py,sha256=wPqn9F5AMXgmkp3zgIrBMllLt2SDCCnBNNyi-ag3yzw,5555
68
68
  utilities/socket.py,sha256=K77vfREvzoVTrpYKo6MZakol0EYu2q1sWJnnZqL0So0,118
69
69
  utilities/sqlalchemy.py,sha256=585hWuuXVTKTnyn0Pfd9JI6jp-hmKW6pLKGYMjXjytM,36959
70
70
  utilities/sqlalchemy_polars.py,sha256=wjJpoUo-yO9E2ujpG_06vV5r2OdvBiQ4yvV6wKCa2Tk,15605
@@ -87,7 +87,7 @@ utilities/warnings.py,sha256=un1LvHv70PU-LLv8RxPVmugTzDJkkGXRMZTE2-fTQHw,1771
87
87
  utilities/whenever.py,sha256=iLRP_-8CZtBpHKbGZGu-kjSMg1ZubJ-VSmgSy7Eudxw,17787
88
88
  utilities/zipfile.py,sha256=24lQc9ATcJxHXBPc_tBDiJk48pWyRrlxO2fIsFxU0A8,699
89
89
  utilities/zoneinfo.py,sha256=-Xm57PMMwDTYpxJdkiJG13wnbwK--I7XItBh5WVhD-o,1874
90
- dycw_utilities-0.114.3.dist-info/METADATA,sha256=vNqkObcQLSh6xKu-ehOh26STTT5syHO9ImD4L7O3dPc,12943
91
- dycw_utilities-0.114.3.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
92
- dycw_utilities-0.114.3.dist-info/licenses/LICENSE,sha256=gppZp16M6nSVpBbUBrNL6JuYfvKwZiKgV7XoKKsHzqo,1066
93
- dycw_utilities-0.114.3.dist-info/RECORD,,
90
+ dycw_utilities-0.114.4.dist-info/METADATA,sha256=9qRUMytURQugNiOj679IgyjcF69EMzLAGsd_y0cwi_E,12943
91
+ dycw_utilities-0.114.4.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
92
+ dycw_utilities-0.114.4.dist-info/licenses/LICENSE,sha256=gppZp16M6nSVpBbUBrNL6JuYfvKwZiKgV7XoKKsHzqo,1066
93
+ dycw_utilities-0.114.4.dist-info/RECORD,,
utilities/__init__.py CHANGED
@@ -1,3 +1,3 @@
1
1
  from __future__ import annotations
2
2
 
3
- __version__ = "0.114.3"
3
+ __version__ = "0.114.4"
utilities/asyncio.py CHANGED
@@ -326,7 +326,7 @@ class ExceptionProcessor(QueueProcessor[Exception | type[Exception]]):
326
326
  ##
327
327
 
328
328
 
329
- @dataclass(kw_only=True)
329
+ @dataclass(kw_only=True, unsafe_hash=True)
330
330
  class InfiniteLooper(ABC, Generic[THashable]):
331
331
  """An infinite loop which can throw exceptions by setting events."""
332
332
 
@@ -334,7 +334,7 @@ class InfiniteLooper(ABC, Generic[THashable]):
334
334
  sleep_restart: Duration = MINUTE
335
335
  logger: str | None = None
336
336
  _events: Mapping[THashable, Event] = field(
337
- default_factory=dict, init=False, repr=False
337
+ default_factory=dict, init=False, repr=False, hash=False
338
338
  )
339
339
 
340
340
  def __post_init__(self) -> None:
utilities/slack_sdk.py CHANGED
@@ -9,7 +9,12 @@ from typing import TYPE_CHECKING, override
9
9
 
10
10
  from slack_sdk.webhook.async_client import AsyncWebhookClient
11
11
 
12
- from utilities.asyncio import QueueProcessor, sleep_dur, timeout_dur
12
+ from utilities.asyncio import (
13
+ InfiniteQueueLooper,
14
+ QueueProcessor,
15
+ sleep_dur,
16
+ timeout_dur,
17
+ )
13
18
  from utilities.datetime import MINUTE, SECOND, datetime_duration_to_float
14
19
  from utilities.functools import cache
15
20
  from utilities.math import safe_round
@@ -95,6 +100,49 @@ class SlackHandler(Handler, QueueProcessor[str]):
95
100
  await sleep_dur(duration=self.sleep)
96
101
 
97
102
 
103
+ @dataclass(init=False, unsafe_hash=True)
104
+ class SlackHandlerIQL(Handler, InfiniteQueueLooper[None, str]):
105
+ """Handler for sending messages to Slack."""
106
+
107
+ @override
108
+ def __init__(
109
+ self,
110
+ url: str,
111
+ /,
112
+ *,
113
+ level: int = NOTSET,
114
+ sleep_core: Duration = _SLEEP,
115
+ sleep_restart: Duration = _SLEEP,
116
+ queue_type: type[Queue[str]] = Queue,
117
+ sender: Callable[[str, str], Coroutine1[None]] = _send_adapter,
118
+ timeout: Duration = _TIMEOUT,
119
+ ) -> None:
120
+ InfiniteQueueLooper.__init__( # InfiniteQueueLooper first
121
+ self, queue_type=queue_type
122
+ )
123
+ InfiniteQueueLooper.__post_init__(self)
124
+ Handler.__init__(self, level=level)
125
+ self.url = url
126
+ self.sender = sender
127
+ self.timeout = timeout
128
+ self.sleep_core = sleep_core
129
+ self.sleep_restart = sleep_restart
130
+
131
+ @override
132
+ def emit(self, record: LogRecord) -> None:
133
+ try:
134
+ self.put_items_nowait(self.format(record))
135
+ except Exception: # noqa: BLE001 # pragma: no cover
136
+ self.handleError(record)
137
+
138
+ @override
139
+ async def _process_items(self, *items: str) -> None:
140
+ """Process the first item."""
141
+ text = "\n".join(items)
142
+ async with timeout_dur(duration=self.timeout):
143
+ await self.sender(self.url, text)
144
+
145
+
98
146
  ##
99
147
 
100
148
 
@@ -128,4 +176,4 @@ def _get_client(url: str, /, *, timeout: Duration = _TIMEOUT) -> AsyncWebhookCli
128
176
  return AsyncWebhookClient(url, timeout=timeout_use)
129
177
 
130
178
 
131
- __all__ = ["SendToSlackError", "SlackHandler", "send_to_slack"]
179
+ __all__ = ["SendToSlackError", "SlackHandler", "SlackHandlerIQL", "send_to_slack"]