DefStream 0.1.18__74-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.
Files changed (75) hide show
  1. DefStream/Broker/Configuration.py +18 -0
  2. DefStream/Broker/Connection.py +141 -0
  3. DefStream/Broker/Consumer.py +59 -0
  4. DefStream/Broker/Errors.py +14 -0
  5. DefStream/Broker/Event.py +35 -0
  6. DefStream/Broker/Implements/RabbitMQ/Configuration.py +49 -0
  7. DefStream/Broker/Implements/RabbitMQ/Connection.py +547 -0
  8. DefStream/Broker/Implements/RabbitMQ/Consumer.py +358 -0
  9. DefStream/Broker/Implements/RabbitMQ/Event.py +127 -0
  10. DefStream/Broker/Implements/RabbitMQ/Exchange.py +278 -0
  11. DefStream/Broker/Implements/RabbitMQ/Policies.py +9 -0
  12. DefStream/Broker/Implements/RabbitMQ/Queue.py +321 -0
  13. DefStream/Broker/Implements/RabbitMQ/Serializer.py +75 -0
  14. DefStream/Broker/Implements/RabbitMQ/Stream.py +181 -0
  15. DefStream/Broker/Implements/RabbitMQ/Subscription.py +74 -0
  16. DefStream/Broker/Implements/RabbitMQ/__init__.py +47 -0
  17. DefStream/Broker/Implements/Redis/Configuration.py +59 -0
  18. DefStream/Broker/Implements/Redis/Connection.py +265 -0
  19. DefStream/Broker/Implements/Redis/Consumer.py +364 -0
  20. DefStream/Broker/Implements/Redis/Event.py +191 -0
  21. DefStream/Broker/Implements/Redis/Queue.py +284 -0
  22. DefStream/Broker/Implements/Redis/Serializer.py +48 -0
  23. DefStream/Broker/Implements/Redis/Subscription.py +46 -0
  24. DefStream/Broker/Implements/Redis/__init__.py +29 -0
  25. DefStream/Broker/Implements/__init__.py +1 -0
  26. DefStream/Broker/Policies.py +25 -0
  27. DefStream/Broker/Priority.py +26 -0
  28. DefStream/Broker/Protocol.py +45 -0
  29. DefStream/Broker/__init__.py +59 -0
  30. DefStream/Descriptor/DataObject.py +409 -0
  31. DefStream/Descriptor/Types.py +248 -0
  32. DefStream/Descriptor/Value.py +188 -0
  33. DefStream/Descriptor/__init__.py +172 -0
  34. DefStream/Inspector/Extension.py +69 -0
  35. DefStream/Inspector/Extensions/Console.html +373 -0
  36. DefStream/Inspector/Extensions/Console.py +415 -0
  37. DefStream/Inspector/Extensions/Metrics.py +316 -0
  38. DefStream/Inspector/Extensions/Ping.py +107 -0
  39. DefStream/Inspector/Extensions/Specifications.py +176 -0
  40. DefStream/Inspector/Extensions/Status.html +206 -0
  41. DefStream/Inspector/Extensions/Status.py +124 -0
  42. DefStream/Inspector/Extensions/__init__.py +13 -0
  43. DefStream/Inspector/Inspector.py +347 -0
  44. DefStream/Inspector/Response.py +14 -0
  45. DefStream/Inspector/__init__.py +9 -0
  46. DefStream/Validator/Pattern.py +36 -0
  47. DefStream/Validator/Patterns/Array.py +30 -0
  48. DefStream/Validator/Patterns/Common.py +92 -0
  49. DefStream/Validator/Patterns/Compare.py +180 -0
  50. DefStream/Validator/Patterns/Condition.py +60 -0
  51. DefStream/Validator/Patterns/DataObject.py +85 -0
  52. DefStream/Validator/Patterns/DateTime.py +111 -0
  53. DefStream/Validator/Patterns/Number.py +43 -0
  54. DefStream/Validator/Patterns/Object.py +150 -0
  55. DefStream/Validator/Patterns/Size.py +110 -0
  56. DefStream/Validator/Patterns/String.py +85 -0
  57. DefStream/Validator/Patterns/Type.py +350 -0
  58. DefStream/Validator/Patterns/__init__.py +137 -0
  59. DefStream/Validator/Validate.py +29 -0
  60. DefStream/Validator/Validator.py +30 -0
  61. DefStream/Validator/__init__.py +11 -0
  62. DefStream/Worker/Executor.py +371 -0
  63. DefStream/Worker/Message.py +180 -0
  64. DefStream/Worker/Pool.py +245 -0
  65. DefStream/Worker/Run.py +357 -0
  66. DefStream/Worker/Specification.py +87 -0
  67. DefStream/Worker/Startup.py +174 -0
  68. DefStream/Worker/Worker.py +421 -0
  69. DefStream/Worker/__init__.py +47 -0
  70. DefStream/__init__.py +0 -0
  71. defstream-0.1.18.dist-info/METADATA +92 -0
  72. defstream-0.1.18.dist-info/RECORD +75 -0
  73. defstream-0.1.18.dist-info/WHEEL +6 -0
  74. defstream-0.1.18.dist-info/licenses/LICENSE +674 -0
  75. defstream-0.1.18.dist-info/top_level.txt +1 -0
@@ -0,0 +1,421 @@
1
+ from abc import (
2
+ ABC,
3
+ abstractmethod,
4
+ )
5
+ from collections.abc import Mapping
6
+ from logging import getLogger
7
+ from threading import Event as PyEvent
8
+ from typing import (
9
+ Any,
10
+ List,
11
+ Callable,
12
+ Optional,
13
+ Sequence,
14
+ Type,
15
+ Tuple,
16
+ Union,
17
+ )
18
+
19
+ from ..Broker import (
20
+ Connection,
21
+ GetConsumer,
22
+ Consumer,
23
+ EventHandler,
24
+ )
25
+ from ..Broker.Event import Event
26
+ from .Message import task_parameters
27
+ from ..Inspector import Inspector
28
+ from .Pool import (
29
+ Pool,
30
+ PoolFull,
31
+ )
32
+ from .Run import Run
33
+ from .Executor import run_cleanups
34
+ from .Startup import startup
35
+
36
+ __all__ = (
37
+ 'Worker',
38
+ 'WorkerSetup',
39
+ 'WorkerCleanup',
40
+ )
41
+
42
+ class WorkerSetup(ABC):
43
+ @abstractmethod
44
+ def __call__(
45
+ self,
46
+ worker: 'Worker',
47
+ ) -> None:
48
+ raise NotImplementedError
49
+
50
+
51
+ class WorkerCleanup(ABC):
52
+ @abstractmethod
53
+ def __call__(
54
+ self,
55
+ worker: 'Worker',
56
+ ) -> None:
57
+ raise NotImplementedError
58
+
59
+
60
+ def worker_hooks(
61
+ hooks: Optional[Union[Callable[['Worker'], None], Sequence[Callable[['Worker'], None]]]],
62
+ ) -> Tuple[Callable[['Worker'], None], ...]:
63
+ result = () if hooks is None else tuple(hooks) if isinstance(
64
+ hooks,
65
+ Sequence,
66
+ ) else (hooks,)
67
+ if not all(callable(hook) for hook in result):
68
+ raise TypeError('Worker hooks must be callable')
69
+ return result
70
+
71
+
72
+ class Worker:
73
+ logger = getLogger('DefStream.Worker')
74
+
75
+ def __init__(
76
+ self,
77
+ broker: Connection,
78
+ pool: Pool,
79
+ setups: Optional[Union[WorkerSetup, Sequence[WorkerSetup]]] = None,
80
+ cleanups: Optional[Union[WorkerCleanup, Sequence[WorkerCleanup]]] = None,
81
+ inspector: Optional[Inspector] = None,
82
+ ):
83
+ self.broker = broker
84
+ self.pool = pool
85
+ self.tasks: List[Type[Run]] = []
86
+ self.consumer: Optional[Consumer] = None
87
+ self.started = False
88
+ self.running = PyEvent()
89
+ self.stopping = PyEvent()
90
+ self.finished = PyEvent()
91
+ self.pending = 0
92
+ self.setups = worker_hooks(setups)
93
+ self.cleanups = worker_hooks(cleanups)
94
+ self.inspector = inspector
95
+
96
+ def add(
97
+ self,
98
+ run: Type[Run],
99
+ ) -> None:
100
+ if self.started:
101
+ raise RuntimeError('Cannot register runs after starting the worker')
102
+ task_parameters(run)
103
+ if run in self.tasks:
104
+ raise ValueError('Run is already registered')
105
+ if any(
106
+ registered.name == run.name
107
+ for registered in self.tasks
108
+ ):
109
+ raise ValueError('Duplicate Run name: ' + run.name)
110
+ self.tasks.append(run)
111
+ self.logger.debug(
112
+ 'Task registered: task=%s.%s',
113
+ run.__module__,
114
+ run.__qualname__,
115
+ )
116
+
117
+ def run(self) -> None:
118
+ if self.started:
119
+ raise RuntimeError('Worker can only be started once')
120
+ if not self.tasks:
121
+ raise RuntimeError('Register at least one Run before starting')
122
+ self.started = True
123
+ self.logger.info(
124
+ 'Starting Worker: tasks=%s',
125
+ len(self.tasks),
126
+ )
127
+ try:
128
+ startup(self)
129
+ if self.inspector is not None:
130
+ self.inspector.start(self)
131
+ self.logger.debug('Connecting to broker')
132
+ self.broker.connect()
133
+ self.logger.debug('Broker connected')
134
+ for setup in self.setups:
135
+ self.logger.debug(
136
+ 'Starting Worker setup: hook=%s',
137
+ type(setup).__qualname__,
138
+ )
139
+ setup(self)
140
+ self.logger.debug(
141
+ 'Worker setup completed: hook=%s',
142
+ type(setup).__qualname__,
143
+ )
144
+ if not isinstance(self.broker, GetConsumer):
145
+ raise TypeError('Worker broker must support consumer creation')
146
+ self.consumer = self.broker.consumer()
147
+ self.logger.debug('Consumer created')
148
+ for run in self.tasks:
149
+ self.logger.debug(
150
+ 'Subscribing task: task=%s.%s',
151
+ run.__module__,
152
+ run.__qualname__,
153
+ )
154
+ self.consumer.subs(
155
+ run.parameters,
156
+ Handler(
157
+ self,
158
+ run,
159
+ ),
160
+ )
161
+ self.logger.debug(
162
+ 'Task subscribed: task=%s.%s',
163
+ run.__module__,
164
+ run.__qualname__,
165
+ )
166
+ if not self.stopping.is_set():
167
+ self.running.set()
168
+ self.logger.info('Worker ready to consume')
169
+ self.consumer.run()
170
+ finally:
171
+ self.running.clear()
172
+ self.finished.set()
173
+ if self.pending:
174
+ self.logger.error(
175
+ 'Consumer exited with unconfirmed deliveries: pending=%s',
176
+ self.pending,
177
+ )
178
+ try:
179
+ self.logger.info(
180
+ 'Draining Worker tasks: pending=%s',
181
+ self.pending,
182
+ )
183
+ self.pool.stop()
184
+ finally:
185
+ try:
186
+ self.cleanup()
187
+ finally:
188
+ try:
189
+ if self.consumer is not None:
190
+ self.consumer.close()
191
+ finally:
192
+ try:
193
+ self.broker.close()
194
+ finally:
195
+ if self.inspector is not None and self.inspector.worker is self:
196
+ self.inspector.stop()
197
+ self.logger.info('Worker shutdown completed')
198
+
199
+ def cleanup(self) -> None:
200
+ self.logger.debug(
201
+ 'Starting Worker cleanup: hooks=%s',
202
+ len(self.cleanups),
203
+ )
204
+ run_cleanups(
205
+ self.cleanups,
206
+ self,
207
+ )
208
+ self.logger.debug('Worker cleanup completed')
209
+
210
+ def stop(self) -> None:
211
+ if not self.stopping.is_set():
212
+ self.logger.info(
213
+ 'Worker shutdown requested: pending=%s',
214
+ self.pending,
215
+ )
216
+ self.stopping.set()
217
+ if self.consumer is not None and not self.finished.is_set():
218
+ self.consumer.call(self.try_stop)
219
+
220
+ def try_stop(self) -> None:
221
+ if self.stopping.is_set() and self.pending == 0 and self.consumer is not None:
222
+ self.logger.debug('No pending tasks; requesting Consumer stop')
223
+ self.consumer.stop()
224
+
225
+ def receive(
226
+ self,
227
+ run: Type[Run],
228
+ event: Event,
229
+ ) -> None:
230
+ if self.stopping.is_set():
231
+ self.logger.debug(
232
+ 'Requeuing message received during shutdown: task=%s.%s',
233
+ run.__module__,
234
+ run.__qualname__,
235
+ )
236
+ event.nack()
237
+ return
238
+ if not isinstance(
239
+ event.body,
240
+ Mapping,
241
+ ):
242
+ self.failed(
243
+ run,
244
+ event,
245
+ TypeError('Run message body must be a mapping'),
246
+ )
247
+ return
248
+ self.pending += 1
249
+ consumer = self.consumer
250
+ if consumer is None:
251
+ self.pending -= 1
252
+ raise RuntimeError('Worker consumer is not initialized')
253
+ inspector = self.inspector
254
+ task = run.name
255
+ self.logger.debug(
256
+ 'Task message received: task=%s pending=%s',
257
+ task,
258
+ self.pending,
259
+ )
260
+ contexts = inspector.begin(task) if inspector is not None else ()
261
+
262
+ def schedule(
263
+ error: Optional[BaseException] = None,
264
+ result: Any = None,
265
+ ) -> None:
266
+ if inspector is not None:
267
+ inspector.end(
268
+ task,
269
+ contexts,
270
+ error is None,
271
+ )
272
+ if self.finished.is_set():
273
+ self.logger.error(
274
+ 'Cannot confirm delivery after Consumer exit: task=%s',
275
+ task,
276
+ )
277
+ return
278
+ self.logger.debug(
279
+ 'Scheduling task result callback: task=%s success=%s',
280
+ task,
281
+ error is None,
282
+ )
283
+ consumer.call(lambda: self.complete(
284
+ run,
285
+ event,
286
+ error,
287
+ result,
288
+ ))
289
+
290
+ try:
291
+ self.logger.debug(
292
+ 'Submitting task to Pool: task=%s',
293
+ task,
294
+ )
295
+ self.pool.submit(
296
+ run,
297
+ dict(event.body),
298
+ callback=lambda result: schedule(result=result),
299
+ error_callback=schedule,
300
+ )
301
+ self.logger.debug(
302
+ 'Pool task submission accepted: task=%s',
303
+ task,
304
+ )
305
+ except PoolFull:
306
+ self.logger.debug(
307
+ 'Requeuing message because Pool is full: task=%s',
308
+ task,
309
+ )
310
+ if inspector is not None:
311
+ inspector.end(
312
+ task,
313
+ contexts,
314
+ None,
315
+ )
316
+ self.pending -= 1
317
+ event.nack()
318
+ return
319
+ except Exception:
320
+ if inspector is not None:
321
+ inspector.end(
322
+ task,
323
+ contexts,
324
+ None,
325
+ )
326
+ self.pending -= 1
327
+ raise
328
+
329
+ def complete(
330
+ self,
331
+ run: Type[Run],
332
+ event: Event,
333
+ error: Optional[BaseException] = None,
334
+ result: Any = None,
335
+ ) -> None:
336
+ try:
337
+ if error is not None:
338
+ self.failed(
339
+ run,
340
+ event,
341
+ error,
342
+ )
343
+ else:
344
+ if self.consumer is None:
345
+ raise RuntimeError('Worker consumer is not initialized')
346
+ self.consumer.complete(
347
+ event,
348
+ result,
349
+ )
350
+ self.logger.debug(
351
+ 'Consumer completion returned: task=%s.%s',
352
+ run.__module__,
353
+ run.__qualname__,
354
+ )
355
+ finally:
356
+ self.pending -= 1
357
+ self.logger.debug(
358
+ 'Task completion handling finished: pending=%s',
359
+ self.pending,
360
+ )
361
+ self.try_stop()
362
+
363
+ def failed(
364
+ self,
365
+ run: Type[Run],
366
+ event: Event,
367
+ error: BaseException,
368
+ ) -> None:
369
+ if isinstance(
370
+ error,
371
+ TypeError,
372
+ ) and not isinstance(
373
+ event.body,
374
+ Mapping,
375
+ ):
376
+ self.logger.warning(
377
+ 'Rejected a non-mapping task message: task=%s.%s',
378
+ run.__module__,
379
+ run.__qualname__,
380
+ )
381
+ else:
382
+ self.logger.error(
383
+ 'Task failed: task=%s.%s',
384
+ run.__module__,
385
+ run.__qualname__,
386
+ exc_info=(
387
+ type(error),
388
+ error,
389
+ error.__traceback__,
390
+ ),
391
+ )
392
+ if self.consumer is None:
393
+ raise RuntimeError('Worker consumer is not initialized')
394
+ self.consumer.fail(
395
+ event,
396
+ run.on_error,
397
+ )
398
+ self.logger.debug(
399
+ 'Consumer failure policy returned: task=%s.%s',
400
+ run.__module__,
401
+ run.__qualname__,
402
+ )
403
+
404
+
405
+ class Handler(EventHandler):
406
+ def __init__(
407
+ self,
408
+ worker: Worker,
409
+ run: Type[Run],
410
+ ):
411
+ self.worker = worker
412
+ self.run = run
413
+
414
+ def __call__(
415
+ self,
416
+ event: Event,
417
+ ) -> None:
418
+ self.worker.receive(
419
+ self.run,
420
+ event,
421
+ )
@@ -0,0 +1,47 @@
1
+ from .Worker import (
2
+ Worker,
3
+ WorkerSetup,
4
+ WorkerCleanup,
5
+ )
6
+ from .Message import (
7
+ declare,
8
+ emit,
9
+ request,
10
+ )
11
+ from .Run import (
12
+ Run,
13
+ Context,
14
+ RunSetup,
15
+ RunComplete,
16
+ RunError,
17
+ )
18
+ from .Specification import Specification
19
+ from .Pool import (
20
+ Pool,
21
+ PoolFull,
22
+ PoolSetup,
23
+ PoolCleanup,
24
+ ThreadPool,
25
+ ProcessPool,
26
+ )
27
+
28
+ __all__ = (
29
+ 'Worker',
30
+ 'declare',
31
+ 'emit',
32
+ 'request',
33
+ 'WorkerSetup',
34
+ 'WorkerCleanup',
35
+ 'Run',
36
+ 'Specification',
37
+ 'Pool',
38
+ 'PoolFull',
39
+ 'PoolSetup',
40
+ 'PoolCleanup',
41
+ 'ThreadPool',
42
+ 'ProcessPool',
43
+ 'Context',
44
+ 'RunSetup',
45
+ 'RunComplete',
46
+ 'RunError',
47
+ )
DefStream/__init__.py ADDED
File without changes
@@ -0,0 +1,92 @@
1
+ Metadata-Version: 2.4
2
+ Name: DefStream
3
+ Version: 0.1.18
4
+ Summary: Synchronous message processing with pluggable broker adapters
5
+ Home-page: https://github.com/yong5eon/DefStream
6
+ Author: Heo Yongseon
7
+ Project-URL: Source, https://github.com/yong5eon/DefStream
8
+ Project-URL: Issues, https://github.com/yong5eon/DefStream/issues
9
+ Project-URL: Releases, https://github.com/yong5eon/DefStream/releases
10
+ Classifier: Programming Language :: Python :: 3.9
11
+ Classifier: Programming Language :: Python :: 3.10
12
+ Classifier: Programming Language :: Python :: 3.11
13
+ Classifier: Programming Language :: Python :: 3.12
14
+ Classifier: Programming Language :: Python :: 3.13
15
+ Classifier: Programming Language :: Python :: 3.14
16
+ Requires-Python: >=3.9
17
+ Description-Content-Type: text/markdown
18
+ License-File: LICENSE
19
+ Provides-Extra: rabbitmq
20
+ Requires-Dist: pika>=1.3.2; extra == "rabbitmq"
21
+ Provides-Extra: redis
22
+ Requires-Dist: redis>=5.1.1; extra == "redis"
23
+ Dynamic: author
24
+ Dynamic: classifier
25
+ Dynamic: description
26
+ Dynamic: description-content-type
27
+ Dynamic: home-page
28
+ Dynamic: license-file
29
+ Dynamic: project-url
30
+ Dynamic: provides-extra
31
+ Dynamic: requires-python
32
+ Dynamic: summary
33
+
34
+ # DefStream
35
+
36
+ Synchronous event/message processing with pluggable broker adapters
37
+
38
+ DefStream processes broker messages with ordinary Python task methods and can run them in thread or process pools. It requires Python 3.9 or later.
39
+
40
+ ## Installation
41
+
42
+ Install the client extra for the broker you use. A broker server must be available separately.
43
+
44
+ ```shell
45
+ python -m pip install "DefStream[RabbitMQ]"
46
+ ```
47
+
48
+ For Redis Streams, install `DefStream[Redis]`. To install both clients, use `DefStream[RabbitMQ,Redis]`. The plain `DefStream` installation includes neither broker client.
49
+
50
+ ## Quick start
51
+
52
+ The following worker listens to a local RabbitMQ server at `127.0.0.1:5672`. The example credentials are for local development only.
53
+
54
+ ```python
55
+ from signal import SIGINT, signal
56
+
57
+ from DefStream.Broker.Implements.RabbitMQ import Configuration, Connection, Reject, Subscription
58
+ from DefStream.Worker import Run, ThreadPool, Worker, WorkerSetup, declare
59
+
60
+
61
+ class Add(
62
+ Run,
63
+ parameters=Subscription(queue='example.add', error='example.add.error'),
64
+ on_error=Reject(),
65
+ ):
66
+ def run(self, a: int, b: int):
67
+ print(a + b)
68
+ return a + b
69
+
70
+
71
+ class Prepare(WorkerSetup):
72
+ def __call__(self, worker: Worker) -> None:
73
+ for task in worker.tasks:
74
+ declare(task=task, broker=worker.broker)
75
+
76
+
77
+ if __name__ == '__main__':
78
+ worker = Worker(
79
+ Connection(Configuration(host='127.0.0.1', port=5672, username='guest', password='guest')),
80
+ ThreadPool(4),
81
+ setups=Prepare(),
82
+ )
83
+ worker.add(Add)
84
+ signal(SIGINT, lambda *_: worker.stop())
85
+ worker.run()
86
+ ```
87
+
88
+ Run the script after starting RabbitMQ. The worker declares its task queue and waits for messages. Store production credentials outside source code.
89
+
90
+ ## License
91
+
92
+ See the `LICENSE` file included with the source distribution for the license terms.
@@ -0,0 +1,75 @@
1
+ DefStream/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ DefStream/Broker/Configuration.py,sha256=cf-sjY9knNCGUWd6dKZClyTzB-mvPYfSuvSTTFALhjo,345
3
+ DefStream/Broker/Connection.py,sha256=KWJDcLq3zYYaytgrTdDZcCoZWGd7KU6B2trAPsen0GU,2125
4
+ DefStream/Broker/Consumer.py,sha256=6zfOSO1gLDkF53TbDRzSp9GCDbL_zOIwz9B2WpMR748,1258
5
+ DefStream/Broker/Errors.py,sha256=_l1ieD1vBbX8MLXEzTK8m_21-8o0Szix3Pg-DNY0aNQ,206
6
+ DefStream/Broker/Event.py,sha256=dIfqIjjlnxlO7UTZEhovUKErJSKd4XmjENlmphLwtnU,470
7
+ DefStream/Broker/Policies.py,sha256=pTur9yqDalStCpMMD0I7yYtJSv0BDt9DIgPMtIgRkpA,273
8
+ DefStream/Broker/Priority.py,sha256=PKxjpMkQEOIOT_cZjG8J6IA7tdQBk3xqQVNG0a7xU7c,621
9
+ DefStream/Broker/Protocol.py,sha256=oYvZaFCIXDroY1Z-iJ6yUelOyrLDDEJMV1ML8_ugEZw,559
10
+ DefStream/Broker/__init__.py,sha256=z_FLeH6QNeoHASnn940fUOnLaMbIE5SDypxDcjZy-JU,866
11
+ DefStream/Broker/Implements/__init__.py,sha256=iwhKnzeBJLKxpRVjvzwiRE63_zNpIBfaKLITauVph-0,24
12
+ DefStream/Broker/Implements/RabbitMQ/Configuration.py,sha256=sHysXc1nlJHbSjWD3BZxlXjKBAbz2AKDtr7ACVVVj0c,1094
13
+ DefStream/Broker/Implements/RabbitMQ/Connection.py,sha256=CSL-0wyiCm1O2AGaN3Pwso_DUrj3VonH8Z3Vco8Ft9A,14198
14
+ DefStream/Broker/Implements/RabbitMQ/Consumer.py,sha256=G3LbXvntZnCTGM-8TfTOed5NF7_qMgk7ZFslSmlIqQo,9686
15
+ DefStream/Broker/Implements/RabbitMQ/Event.py,sha256=j7GjKsVA64-x8ScjAMBrobVF75RE_BXEh6tWXXdS-FI,3086
16
+ DefStream/Broker/Implements/RabbitMQ/Exchange.py,sha256=hn-P-PXCa8v7CzB4yxO1hM04-hDaU7_rACnKvZJHoU4,8476
17
+ DefStream/Broker/Implements/RabbitMQ/Policies.py,sha256=E0NA3zvO1h6BPr7CyMo9WPy6ztobuTd6fGUFgB8604o,90
18
+ DefStream/Broker/Implements/RabbitMQ/Queue.py,sha256=iEdDj8ji35p4ak8JwqsnhUZPvdhtFfQW3RN_YKacFow,9429
19
+ DefStream/Broker/Implements/RabbitMQ/Serializer.py,sha256=PbL_V89GHPjqh1zvOM-apExhD7Bgau2jinpVCsVUg00,1718
20
+ DefStream/Broker/Implements/RabbitMQ/Stream.py,sha256=sgX0otKZMqDKK2eX1S1zkhCo6OhGEr1qyLEpvvwTijY,5694
21
+ DefStream/Broker/Implements/RabbitMQ/Subscription.py,sha256=A1sCwWgytNYOIJ-D9PKps_1blxJNp1lGK0a1CDHh7Jw,1849
22
+ DefStream/Broker/Implements/RabbitMQ/__init__.py,sha256=Ndt5yNXcgecN1mj0Qv7M32LUFK96WKmSi88wKMB1ZdU,673
23
+ DefStream/Broker/Implements/Redis/Configuration.py,sha256=A86E44Jo2z_d45xBHH92atR-PPyySlT7QWgxc3UX1Yc,1551
24
+ DefStream/Broker/Implements/Redis/Connection.py,sha256=CMyVSp4uiyVDIe4y5JQtNNqycksAvGw5Ed8uXyK2RCY,5258
25
+ DefStream/Broker/Implements/Redis/Consumer.py,sha256=-b-2tfa2BCIGqVsf9AkKDnedDkHZ56g7eRRlUHEz6QY,8608
26
+ DefStream/Broker/Implements/Redis/Event.py,sha256=L4kugJefdlEKfCpgbxdBoj9818y9nuL7PECsoXDDfH8,4397
27
+ DefStream/Broker/Implements/Redis/Queue.py,sha256=ndRkp6vh4C7Pp_E0alAjsqHqPm9ban4Kxd4Xi_NeJZw,6097
28
+ DefStream/Broker/Implements/Redis/Serializer.py,sha256=NWGxpnf5kegR9i_kr8cxQk5JiXO1lMdvTo2sPmghHe0,635
29
+ DefStream/Broker/Implements/Redis/Subscription.py,sha256=I6MZdT8-VSBeiGBHuOmld11xwiQv048YQLfRGS9FzSE,811
30
+ DefStream/Broker/Implements/Redis/__init__.py,sha256=mYLkr6H040-cphMjTFv6j-_75q9qusEYPMY97erfjAQ,449
31
+ DefStream/Descriptor/DataObject.py,sha256=hq7YufF6_NCs41TFUozpwFv6qI5iv3Cx5SHHq2IPeLc,12018
32
+ DefStream/Descriptor/Types.py,sha256=tnC9ZjsCx8e_zK5pXjJymx-UxRJNQPBPMxrfMyG2fIE,5112
33
+ DefStream/Descriptor/Value.py,sha256=dSEVedEc9glv3sWC4idUdW0EXtstCW7It2WeZfTGYF0,3525
34
+ DefStream/Descriptor/__init__.py,sha256=xu_dDulMEItY6d7OjMZptsBb9_zdH--rqPTTnkz8ZGg,2544
35
+ DefStream/Inspector/Extension.py,sha256=4VqIVtsMpeLzsnlG1fWVif1mBv3BakC7L1fFVso4gvc,954
36
+ DefStream/Inspector/Inspector.py,sha256=Oq5-YBLLORCw2GtnyGVHcY-3yUYXksQPgc7P-hbfPoU,7323
37
+ DefStream/Inspector/Response.py,sha256=QtXyorMAize6iM08so3k-WY1PdArjE6VK3Lixjz6WvA,204
38
+ DefStream/Inspector/__init__.py,sha256=O1rJuT-n92AY3Z3im6XJ13mqaI67wpMQmbPwLDBbOQU,153
39
+ DefStream/Inspector/Extensions/Console.html,sha256=5xyI-JWbTKje9tdcIAXnfIyuBqLT72EWmWAto387RfQ,21024
40
+ DefStream/Inspector/Extensions/Console.py,sha256=EXCnwxmVPy1N4y6w15m36ZysTf0brltlMvstszclmmM,10052
41
+ DefStream/Inspector/Extensions/Metrics.py,sha256=WKusp_ZvZi5vV3zhncdURjTzmNRpaAnixFQtthpjx-8,8351
42
+ DefStream/Inspector/Extensions/Ping.py,sha256=EZ2nyzTbbYjbRoFjdidgNCW-3BWIPoWpOzBGDreA5JQ,2391
43
+ DefStream/Inspector/Extensions/Specifications.py,sha256=l1F-LguRPBvE1EaSq_4nQKpjctpV6OdNZs0BVR3I0KM,3841
44
+ DefStream/Inspector/Extensions/Status.html,sha256=PBYBVzV1pgwST89_CIX_jhXHGwKQrpoL-KEyrzuKkJE,12060
45
+ DefStream/Inspector/Extensions/Status.py,sha256=2qidtJiK6xMC56deLzfXdr6xJdOPdc51oSsjKiGXNYs,2795
46
+ DefStream/Inspector/Extensions/__init__.py,sha256=f6ktG84sWLNFVfDLrBtkWl4hjhIrwblRZ990raGATFo,229
47
+ DefStream/Validator/Pattern.py,sha256=gRRlEzS908b9OCXRpFnEG4gujNKCSTlhPUGwWGi-Dqg,674
48
+ DefStream/Validator/Validate.py,sha256=2Edk1sWh5_4QdYTc1xakDLPXMAWNrrjso1TLi7ZQ4Gg,700
49
+ DefStream/Validator/Validator.py,sha256=lvJGzDKecKIBAQrfFuSHBRUh6PCxiHRsabul6cYxcdA,556
50
+ DefStream/Validator/__init__.py,sha256=juhR_lm3XpqU-BUnTjbaYbFNXa_zs9Xi9-x_9EyvJgE,172
51
+ DefStream/Validator/Patterns/Array.py,sha256=XPc88iPhU2k30TIyMsB6pdDqUO_wjv-5YP96mTHbApc,514
52
+ DefStream/Validator/Patterns/Common.py,sha256=JJIOAcPO6epnIINaVu5SuwmnQoK3rLQn6vYyZ3JBuX8,1817
53
+ DefStream/Validator/Patterns/Compare.py,sha256=5xYVvaiQydvIi8WYgIADltSk0tz_ki76k-c89vZsFcw,3726
54
+ DefStream/Validator/Patterns/Condition.py,sha256=V8iEG9onH6bxlUnqFY8jDdmm6BIx2SBeEJAluVHeEUM,1135
55
+ DefStream/Validator/Patterns/DataObject.py,sha256=BTdbKGSYs1ebXNXmKP2m3T0iJeTBxIwgwl45gacpuUA,2258
56
+ DefStream/Validator/Patterns/DateTime.py,sha256=2ejPyRxFbvWf_0FmUrtXTBTvMnp8nakfW_TyCsRY_h4,2515
57
+ DefStream/Validator/Patterns/Number.py,sha256=k59Ue1Sw-D1iWz8OywjQljPVXdZlTawSl9jBpPjJKKY,919
58
+ DefStream/Validator/Patterns/Object.py,sha256=94aa5eC35dZyrgBlbAEH5eB7v9YB8k_haru_EBeU1vw,3563
59
+ DefStream/Validator/Patterns/Size.py,sha256=n-PdMTYNCw0-KN2wqWqK7nN6smVvrGLO4YfwBLlGA9Y,2016
60
+ DefStream/Validator/Patterns/String.py,sha256=sR4s0GM1J8r1kiOyu4HkDUgIrz-9PvLthHM1IFTgSqw,1805
61
+ DefStream/Validator/Patterns/Type.py,sha256=-z75Q3vYw6Br7T-gACIZNLV2PLLkFdHn67VcLxTDqEs,8758
62
+ DefStream/Validator/Patterns/__init__.py,sha256=2Kkk6BrvcLl0C22I0WhGphp2dF55Ig2b3LY0DMDNWm8,1603
63
+ DefStream/Worker/Executor.py,sha256=1-WSJOVC7LYeXq34OQNr7TFo98LbjvRvkyX8GheqXLk,8024
64
+ DefStream/Worker/Message.py,sha256=JG2I-398YpfAlcCqzds0sFQ35UrqAPZbmdaQTmQ7RyE,3242
65
+ DefStream/Worker/Pool.py,sha256=_LD38ZHq5-T1U8u8Trus_T3bR_IuP0hP8vV2YNz3gDA,4830
66
+ DefStream/Worker/Run.py,sha256=Ik1Ej_NBuMl9sUA1Bw1gTYo3r2QNcKiZl6jRQMucf-A,7392
67
+ DefStream/Worker/Specification.py,sha256=MRPpHtSKYaDAa6t0vitCJCiCwQRL9QmG1Y2zibv_UWU,1807
68
+ DefStream/Worker/Startup.py,sha256=vuGfGHzJcx3vCBZAEs3UxDyzHKKW7U9lWUEkeFTAyN4,3955
69
+ DefStream/Worker/Worker.py,sha256=6RHkKCe-zcVKNCO7y69OGjOGdUUtXF3MRtP1WLEeWXo,8785
70
+ DefStream/Worker/__init__.py,sha256=TG_Ma2HFLi5DKTPbqKZ5VWR28g-_WhsKcrf3iYLJxcw,578
71
+ defstream-0.1.18.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
72
+ defstream-0.1.18.dist-info/METADATA,sha256=hneB1u-ydeKj38S1kLPXXVYLFFOpBKii2-W4TxovNj0,2938
73
+ defstream-0.1.18.dist-info/WHEEL,sha256=gRtyB-Pg_pXsUWjiW8ODP1rRp2RMPXkI9uiRVCZyu0A,101
74
+ defstream-0.1.18.dist-info/top_level.txt,sha256=zsnisIu5wHL4b7VM8e9AggG9KTSdUU4morFqpb8YWFs,10
75
+ defstream-0.1.18.dist-info/RECORD,,
@@ -0,0 +1,6 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (84.2.1)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+ Build: 74
6
+