dycw-utilities 0.127.0__py3-none-any.whl → 0.129.13__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.
utilities/redis.py CHANGED
@@ -23,9 +23,8 @@ from typing import (
23
23
  )
24
24
 
25
25
  from redis.asyncio import Redis
26
- from redis.typing import EncodableT
27
26
 
28
- from utilities.asyncio import EnhancedQueue, InfiniteQueueLooper, Looper, timeout_dur
27
+ from utilities.asyncio import EnhancedQueue, Looper, timeout_dur
29
28
  from utilities.contextlib import suppress_super_object_attribute_error
30
29
  from utilities.datetime import (
31
30
  MILLISECOND,
@@ -34,7 +33,7 @@ from utilities.datetime import (
34
33
  datetime_duration_to_timedelta,
35
34
  )
36
35
  from utilities.errors import ImpossibleCaseError
37
- from utilities.functions import ensure_int, get_class_name, identity
36
+ from utilities.functions import ensure_int, identity
38
37
  from utilities.iterables import always_iterable, one
39
38
  from utilities.orjson import deserialize, serialize
40
39
 
@@ -51,10 +50,10 @@ if TYPE_CHECKING:
51
50
 
52
51
  from redis.asyncio import ConnectionPool
53
52
  from redis.asyncio.client import PubSub
54
- from redis.typing import ResponseT
53
+ from redis.typing import EncodableT, ResponseT
55
54
 
56
55
  from utilities.iterables import MaybeIterable
57
- from utilities.types import Duration, MaybeType, TypeLike
56
+ from utilities.types import Duration, TypeLike
58
57
 
59
58
 
60
59
  _K = TypeVar("_K")
@@ -620,42 +619,6 @@ class PublishError(Exception):
620
619
  ##
621
620
 
622
621
 
623
- @dataclass(kw_only=True)
624
- class Publisher(InfiniteQueueLooper[None, tuple[str, EncodableT]]):
625
- """Publish a set of messages to Redis."""
626
-
627
- redis: Redis
628
- serializer: Callable[[Any], EncodableT] | None = None
629
- timeout: Duration = _PUBLISH_TIMEOUT
630
-
631
- @override
632
- async def _process_queue(self) -> None:
633
- for item in self._queue.get_all_nowait(): # skipif-ci-and-not-linux
634
- channel, data = item
635
- _ = await publish(
636
- self.redis,
637
- channel,
638
- data,
639
- serializer=self.serializer,
640
- timeout=self.timeout,
641
- )
642
-
643
- @override
644
- def _yield_events_and_exceptions(
645
- self,
646
- ) -> Iterator[tuple[None, MaybeType[Exception]]]:
647
- yield (None, PublisherError) # skipif-ci-and-not-linux
648
-
649
-
650
- @dataclass(kw_only=True)
651
- class PublisherError(Exception):
652
- publisher: Publisher
653
-
654
- @override
655
- def __str__(self) -> str:
656
- return f"Error running {get_class_name(self.publisher)!r}" # skipif-ci-and-not-linux
657
-
658
-
659
622
  @dataclass(kw_only=True)
660
623
  class PublishService(Looper[tuple[str, _T]]):
661
624
  """Service to publish items to Redis."""
@@ -1095,8 +1058,6 @@ def _deserialize(
1095
1058
  __all__ = [
1096
1059
  "PublishService",
1097
1060
  "PublishServiceMixin",
1098
- "Publisher",
1099
- "PublisherError",
1100
1061
  "RedisHashMapKey",
1101
1062
  "RedisKey",
1102
1063
  "SubscribeService",
utilities/scipy.py CHANGED
@@ -19,7 +19,7 @@ def _ppf_1d(array: NDArrayF, cutoff: float, /) -> NDArrayF:
19
19
  out = full_like(array, nan, dtype=float)
20
20
  out[j] = _ppf_1d(array[j], cutoff)
21
21
  return out
22
- low, high = min(array), max(array)
22
+ low, high = array.min(), array.max()
23
23
  if is_zero(span := high - low):
24
24
  return zeros_like(array, dtype=float)
25
25
  centred = (array - low) / span
utilities/slack_sdk.py CHANGED
@@ -7,7 +7,7 @@ from typing import TYPE_CHECKING, Any, Self, override
7
7
 
8
8
  from slack_sdk.webhook.async_client import AsyncWebhookClient
9
9
 
10
- from utilities.asyncio import InfiniteQueueLooper, Looper, timeout_dur
10
+ from utilities.asyncio import Looper, timeout_dur
11
11
  from utilities.datetime import MINUTE, SECOND, datetime_duration_to_float
12
12
  from utilities.functools import cache
13
13
  from utilities.math import safe_round
@@ -27,53 +27,10 @@ _TIMEOUT: Duration = MINUTE
27
27
  ##
28
28
 
29
29
 
30
- _SLEEP: Duration = SECOND
31
-
32
-
33
30
  async def _send_adapter(url: str, text: str, /) -> None:
34
31
  await send_to_slack(url, text) # pragma: no cover
35
32
 
36
33
 
37
- @dataclass(init=False, unsafe_hash=True)
38
- class SlackHandler(Handler, InfiniteQueueLooper[None, str]):
39
- """Handler for sending messages to Slack."""
40
-
41
- @override
42
- def __init__(
43
- self,
44
- url: str,
45
- /,
46
- *,
47
- level: int = NOTSET,
48
- sleep_core: Duration = _SLEEP,
49
- sleep_restart: Duration = _SLEEP,
50
- sender: Callable[[str, str], Coroutine1[None]] = _send_adapter,
51
- timeout: Duration = _TIMEOUT,
52
- ) -> None:
53
- InfiniteQueueLooper.__init__(self) # InfiniteQueueLooper first
54
- InfiniteQueueLooper.__post_init__(self)
55
- Handler.__init__(self, level=level) # Handler next
56
- self.url = url
57
- self.sender = sender
58
- self.timeout = timeout
59
- self.sleep_core = sleep_core
60
- self.sleep_restart = sleep_restart
61
-
62
- @override
63
- def emit(self, record: LogRecord) -> None:
64
- try:
65
- self.put_right_nowait(self.format(record))
66
- except Exception: # noqa: BLE001 # pragma: no cover
67
- self.handleError(record)
68
-
69
- @override
70
- async def _process_queue(self) -> None:
71
- messages = self._queue.get_all_nowait()
72
- text = "\n".join(messages)
73
- async with timeout_dur(duration=self.timeout):
74
- await self.sender(self.url, text)
75
-
76
-
77
34
  @dataclass(init=False, unsafe_hash=True)
78
35
  class SlackHandlerService(Handler, Looper[str]):
79
36
  """Service to send messages to Slack."""
@@ -187,4 +144,4 @@ def _get_client(url: str, /, *, timeout: Duration = _TIMEOUT) -> AsyncWebhookCli
187
144
  return AsyncWebhookClient(url, timeout=timeout_use)
188
145
 
189
146
 
190
- __all__ = ["SendToSlackError", "SlackHandler", "SlackHandlerService", "send_to_slack"]
147
+ __all__ = ["SendToSlackError", "SlackHandlerService", "send_to_slack"]
utilities/sqlalchemy.py CHANGED
@@ -57,7 +57,7 @@ from sqlalchemy.orm import (
57
57
  from sqlalchemy.orm.exc import UnmappedClassError
58
58
  from sqlalchemy.pool import NullPool, Pool
59
59
 
60
- from utilities.asyncio import InfiniteQueueLooper, Looper, timeout_dur
60
+ from utilities.asyncio import Looper, timeout_dur
61
61
  from utilities.contextlib import suppress_super_object_attribute_error
62
62
  from utilities.datetime import SECOND
63
63
  from utilities.functions import (
@@ -82,13 +82,7 @@ from utilities.iterables import (
82
82
  )
83
83
  from utilities.reprlib import get_repr
84
84
  from utilities.text import snake_case
85
- from utilities.types import (
86
- Duration,
87
- MaybeIterable,
88
- MaybeType,
89
- StrMapping,
90
- TupleOrStrMapping,
91
- )
85
+ from utilities.types import Duration, MaybeIterable, StrMapping, TupleOrStrMapping
92
86
 
93
87
  _T = TypeVar("_T")
94
88
  type _EngineOrConnectionOrAsync = Engine | Connection | AsyncEngine | AsyncConnection
@@ -610,52 +604,6 @@ class TablenameMixin:
610
604
  ##
611
605
 
612
606
 
613
- @dataclass(kw_only=True)
614
- class Upserter(InfiniteQueueLooper[None, _InsertItem]):
615
- """Upsert a set of items to a database."""
616
-
617
- engine: AsyncEngine
618
- snake: bool = False
619
- selected_or_all: _SelectedOrAll = "selected"
620
- chunk_size_frac: float = CHUNK_SIZE_FRAC
621
- assume_tables_exist: bool = False
622
- timeout_create: Duration | None = None
623
- error_create: type[Exception] = TimeoutError
624
- timeout_insert: Duration | None = None
625
- error_insert: type[Exception] = TimeoutError
626
-
627
- @override
628
- async def _process_queue(self) -> None:
629
- items = self._queue.get_all_nowait()
630
- await upsert_items(
631
- self.engine,
632
- *items,
633
- snake=self.snake,
634
- selected_or_all=self.selected_or_all,
635
- chunk_size_frac=self.chunk_size_frac,
636
- assume_tables_exist=self.assume_tables_exist,
637
- timeout_create=self.timeout_create,
638
- error_create=self.error_create,
639
- timeout_insert=self.timeout_insert,
640
- error_insert=self.error_insert,
641
- )
642
-
643
- @override
644
- def _yield_events_and_exceptions(
645
- self,
646
- ) -> Iterator[tuple[None, MaybeType[Exception]]]:
647
- yield (None, UpserterError)
648
-
649
-
650
- @dataclass(kw_only=True)
651
- class UpserterError(Exception):
652
- upserter: Upserter
653
-
654
- @override
655
- def __str__(self) -> str:
656
- return f"Error running {get_class_name(self.upserter)!r}"
657
-
658
-
659
607
  @dataclass(kw_only=True)
660
608
  class UpsertService(Looper[_InsertItem]):
661
609
  """Service to upsert items to a database."""
@@ -1202,8 +1150,6 @@ __all__ = [
1202
1150
  "UpsertItemsError",
1203
1151
  "UpsertService",
1204
1152
  "UpsertServiceMixin",
1205
- "Upserter",
1206
- "UpserterError",
1207
1153
  "check_engine",
1208
1154
  "columnwise_max",
1209
1155
  "columnwise_min",