queutils 0.8.5__py3-none-any.whl → 0.9.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.
queutils/__init__.py CHANGED
@@ -2,10 +2,15 @@ from .countable import Countable as Countable
2
2
  from .asyncqueue import AsyncQueue as AsyncQueue
3
3
  from .iterablequeue import IterableQueue as IterableQueue, QueueDone as QueueDone
4
4
  from .filequeue import FileQueue as FileQueue
5
+ from .eventcounterqueue import (
6
+ QCounter as QCounter,
7
+ EventCounterQueue as EventCounterQueue,
8
+ )
5
9
 
6
10
  __all__ = [
7
11
  "asyncqueue",
8
12
  "countable",
13
+ "eventcounterqueue",
9
14
  "filequeue",
10
15
  "iterablequeue",
11
16
  ]
@@ -0,0 +1,116 @@
1
+ from asyncio import Queue
2
+ from typing import TypeVar
3
+ from deprecated import deprecated
4
+ from .countable import Countable
5
+ from .iterablequeue import IterableQueue, QueueDone
6
+ from collections import defaultdict
7
+ import logging
8
+
9
+ logger = logging.getLogger()
10
+ error = logger.error
11
+ message = logger.warning
12
+ verbose = logger.info
13
+ debug = logger.debug
14
+
15
+ ###########################################
16
+ #
17
+ # class CounterQueue
18
+ #
19
+ ###########################################
20
+ T = TypeVar("T")
21
+
22
+
23
+ @deprecated(version="0.9.1", reason="Use EventCounterQueue instead")
24
+ class CounterQueue(Queue[T], Countable):
25
+ """
26
+ CounterQueue is a asyncio.Queue for counting items
27
+ """
28
+
29
+ _counter: int
30
+ _count_items: bool
31
+ _batch: int
32
+
33
+ def __init__(
34
+ self, *args, count_items: bool = True, batch: int = 1, **kwargs
35
+ ) -> None:
36
+ super().__init__(*args, **kwargs)
37
+ self._counter = 0
38
+ self._count_items = count_items
39
+ self._batch = batch
40
+
41
+ def task_done(self) -> None:
42
+ super().task_done()
43
+ if self._count_items:
44
+ self._counter += 1
45
+ return None
46
+
47
+ @property
48
+ def count(self) -> int:
49
+ """Return number of completed tasks"""
50
+ return self._counter * self._batch
51
+
52
+ @property
53
+ def count_items(self) -> bool:
54
+ """Whether or not count items"""
55
+ return self._count_items
56
+
57
+
58
+ class EventCounterQueue(IterableQueue[tuple[str, int]]):
59
+ """
60
+ EventCounterQueue is a asyncio.Queue for counting events by name
61
+ """
62
+
63
+ _counter: defaultdict[str, int]
64
+ _batch: int
65
+
66
+ def __init__(self, *args, batch: int = 1, **kwargs) -> None:
67
+ super().__init__(*args, **kwargs)
68
+ self._batch = batch
69
+ self._counter = defaultdict(int)
70
+
71
+ async def receive(self) -> tuple[str, int]:
72
+ """Receive an event value from the queue and sum it"""
73
+ event: str
74
+ value: int
75
+ event, value = await super().get()
76
+ self._counter[event] += value
77
+ super().task_done()
78
+ return (event, value)
79
+
80
+ async def send(self, event: str = "count", value: int = 1) -> None:
81
+ """Send count of an event"""
82
+ await super().put((event, value))
83
+ return None
84
+
85
+ def get_count(self, event: str = "count") -> int:
86
+ """Return count for an event"""
87
+ return self._counter[event]
88
+
89
+ def get_counts(self) -> defaultdict[str, int]:
90
+ """Return counts of all events"""
91
+ return self._counter
92
+
93
+ async def listen(self) -> defaultdict[str, int]:
94
+ """Listen for event values"""
95
+ try:
96
+ while True:
97
+ await self.receive()
98
+ except QueueDone:
99
+ pass
100
+ return self.get_counts()
101
+
102
+
103
+ class QCounter:
104
+ def __init__(self, Q: Queue[int]):
105
+ self._count = 0
106
+ self._Q: Queue[int] = Q
107
+
108
+ @property
109
+ def count(self) -> int:
110
+ return self._count
111
+
112
+ async def start(self) -> None:
113
+ """Read and count items from Q"""
114
+ while True:
115
+ self._count += await self._Q.get()
116
+ self._Q.task_done()
@@ -1,10 +1,11 @@
1
- Metadata-Version: 2.3
1
+ Metadata-Version: 2.4
2
2
  Name: queutils
3
- Version: 0.8.5
3
+ Version: 0.9.3
4
4
  Summary: Handy Python Queue utilies
5
5
  Project-URL: Homepage, https://github.com/Jylpah/queutils
6
6
  Project-URL: Bug Tracker, https://github.com/Jylpah/queutils/issues
7
7
  Author-email: Jylpah <jylpah@gmail.com>
8
+ License-File: LICENSE
8
9
  Classifier: Development Status :: 4 - Beta
9
10
  Classifier: Framework :: AsyncIO
10
11
  Classifier: License :: OSI Approved :: MIT License
@@ -13,6 +14,7 @@ Classifier: Programming Language :: Python :: 3
13
14
  Classifier: Topic :: Software Development :: Libraries
14
15
  Requires-Python: >=3.11
15
16
  Requires-Dist: aioconsole>=0.6
17
+ Requires-Dist: deprecated>=1.2.18
16
18
  Provides-Extra: dev
17
19
  Requires-Dist: build>=0.10; extra == 'dev'
18
20
  Requires-Dist: hatchling>=1.22.4; extra == 'dev'
@@ -24,6 +26,7 @@ Requires-Dist: pytest-datafiles>=3.0; extra == 'dev'
24
26
  Requires-Dist: pytest-timeout>=2.2; extra == 'dev'
25
27
  Requires-Dist: pytest>=8.0; extra == 'dev'
26
28
  Requires-Dist: ruff>=0.1.9; extra == 'dev'
29
+ Requires-Dist: types-deprecated>=1.2.15; extra == 'dev'
27
30
  Description-Content-Type: text/markdown
28
31
 
29
32
  [![Python package](https://github.com/Jylpah/queutils/actions/workflows/python-package.yml/badge.svg)](https://github.com/Jylpah/queutils/actions/workflows/python-package.yml) [![codecov](https://codecov.io/gh/Jylpah/queutils/graph/badge.svg?token=rMKdbfHOFs)](https://codecov.io/gh/Jylpah/queutils)
@@ -32,14 +35,15 @@ Description-Content-Type: text/markdown
32
35
 
33
36
  Queutils *[Queue Utils]* is a package of handy Python queue classes:
34
37
 
35
- - **[AsyncQueue](docs/asyncqueue.md)** - An `async` wrapper for non-async `queue.Queue`
36
- - **[IterableQueue](docs/iterablequeue.md)** - An `AsyncIterable` queue that terminates when finished
37
- - **[FileQueue](docs/filequeue.md)** - Builds an iterable queue of filenames from files/dirs given as input
38
+ - **AsyncQueue** - An `async` wrapper for non-async `queue.Queue`
39
+ - **IterableQueue** - An `AsyncIterable` queue that terminates when finished
40
+ - **EventCounterQueue** - An `IterableQueue` for counting events in `async` threads
41
+ - **FileQueue** - Builds an iterable queue of filenames from files/dirs given as input
38
42
 
39
43
 
40
44
  # AsyncQueue
41
45
 
42
- [`AsyncQueue`](docs/asyncqueue.md) is a async wrapper for non-async `queue.Queue`. It can be used to create
46
+ `AsyncQueue` is a async wrapper for non-async `queue.Queue`. It can be used to create
43
47
  an `asyncio.Queue` compatible interface to a (non-async) managed `multiprocessing.Queue` and thus enable `async` code in parent/child processes to communicate over `multiprocessing.Queue` as it were an `asyncio.Queue`.
44
48
 
45
49
  ## Features
@@ -51,7 +55,7 @@ an `asyncio.Queue` compatible interface to a (non-async) managed `multiprocessin
51
55
 
52
56
  # IterableQueue
53
57
 
54
- [`IterableQueue`](docs/iterablequeue.md) is an `asyncio.Queue` subclass that is `AsyncIterable[T]` i.e. it can be
58
+ `IterableQueue` is an `asyncio.Queue` subclass that is `AsyncIterable[T]` i.e. it can be
55
59
  iterated in `async for` loop. `IterableQueue` terminates automatically when the queue has been filled and emptied.
56
60
 
57
61
  The `IterableQueue` requires "producers" (functions adding items to the queue) to register themselves and it
@@ -71,9 +75,19 @@ producers are "finished", the queue enters into "filled" state and no new items
71
75
  - Countable property can be disabled with count_items=False. This is useful when you
72
76
  want to sum the count of multiple IterableQueues
73
77
 
78
+ # EventCounterQueue
79
+
80
+ `EventCounterQueue` can be used to count named events (default event is `count`) between `async` threads. `async` worker threads call `queue.send(event="event_name", N=amount)`. The receving end can either `receive()` a single event or `listen()` all events and return `collections.defaultdict[str, int]` as a result.
81
+
82
+ ## Features
83
+
84
+ - Supports multiple producers and a single listener
85
+ - Default event is `count`
86
+
87
+
74
88
  # FileQueue
75
89
 
76
- [`FileQueue`](docs/filequeue.md) builds a queue (`IterableQueue[pathlib.Path]`) of the matching
90
+ `FileQueue` builds a queue (`IterableQueue[pathlib.Path]`) of the matching
77
91
  files found based on search parameters given. It can search both list of files or directories or
78
92
  mixed. Async method `FileQueue.mk_queue()` searches subdirectories of given directories.
79
93
 
@@ -0,0 +1,11 @@
1
+ queutils/__init__.py,sha256=rbDSh9513Dday-MfWzPOUfN7Aj2x4IqrvCmKbBj7has,441
2
+ queutils/asyncqueue.py,sha256=GZRmlWTBQoKzTf7xr4MI-qhNqvIiaNWswAxFokP91Lg,2789
3
+ queutils/countable.py,sha256=YSi7ILf9CuB5Tm3T4UUMEFlveqzqcmomfqJAlLGHEz8,172
4
+ queutils/eventcounterqueue.py,sha256=NjT8FqEskZhjmus7L333DZU9kXoZCNsn7ydCI5HSe1U,3047
5
+ queutils/filequeue.py,sha256=q2ly9H-lSCq6xuOqT1IlWgyCVyLoZiKbc0NuzmkF4aw,5360
6
+ queutils/iterablequeue.py,sha256=ZXwa9040yTawL1DMMNBXgQKiYr32nmzuSbgi-raAtZc,8664
7
+ queutils/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
+ queutils-0.9.3.dist-info/METADATA,sha256=VGe0K6t0aepLD6DlXlwjFiifK8IUZfcmQlOUXVCKFbA,4664
9
+ queutils-0.9.3.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
10
+ queutils-0.9.3.dist-info/licenses/LICENSE,sha256=J1zeIKU2JVQmhwO2hHQDK8WR6zjVZ-wX8r7ZlL45AbI,1063
11
+ queutils-0.9.3.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: hatchling 1.26.3
2
+ Generator: hatchling 1.27.0
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
@@ -1,10 +0,0 @@
1
- queutils/__init__.py,sha256=MboAom80iQTQURz0liGv_f2ae2Np8YA5ORX1LwsNa50,311
2
- queutils/asyncqueue.py,sha256=GZRmlWTBQoKzTf7xr4MI-qhNqvIiaNWswAxFokP91Lg,2789
3
- queutils/countable.py,sha256=YSi7ILf9CuB5Tm3T4UUMEFlveqzqcmomfqJAlLGHEz8,172
4
- queutils/filequeue.py,sha256=q2ly9H-lSCq6xuOqT1IlWgyCVyLoZiKbc0NuzmkF4aw,5360
5
- queutils/iterablequeue.py,sha256=ZXwa9040yTawL1DMMNBXgQKiYr32nmzuSbgi-raAtZc,8664
6
- queutils/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
- queutils-0.8.5.dist-info/METADATA,sha256=6sJ7O4naraaat7-8ZFeTD9c_r1RFM9uDtkotLuX6aq0,4169
8
- queutils-0.8.5.dist-info/WHEEL,sha256=C2FUgwZgiLbznR-k0b_5k3Ai_1aASOXDss3lzCUsUug,87
9
- queutils-0.8.5.dist-info/licenses/LICENSE,sha256=J1zeIKU2JVQmhwO2hHQDK8WR6zjVZ-wX8r7ZlL45AbI,1063
10
- queutils-0.8.5.dist-info/RECORD,,