datacurrent 1.0.0__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 (43) hide show
  1. datacurrent/__init__.py +157 -0
  2. datacurrent/_version.py +6 -0
  3. datacurrent/buffering/__init__.py +8 -0
  4. datacurrent/buffering/backpressure.py +47 -0
  5. datacurrent/buffering/queue.py +304 -0
  6. datacurrent/concurrency/__init__.py +8 -0
  7. datacurrent/concurrency/limits.py +106 -0
  8. datacurrent/concurrency/tasks.py +86 -0
  9. datacurrent/config.py +86 -0
  10. datacurrent/core/__init__.py +17 -0
  11. datacurrent/core/_util.py +42 -0
  12. datacurrent/core/lifecycle.py +81 -0
  13. datacurrent/core/operators.py +844 -0
  14. datacurrent/core/pipeline.py +64 -0
  15. datacurrent/core/sink.py +70 -0
  16. datacurrent/core/stream.py +566 -0
  17. datacurrent/events/__init__.py +9 -0
  18. datacurrent/events/bus.py +380 -0
  19. datacurrent/events/routing.py +59 -0
  20. datacurrent/events/subscriptions.py +75 -0
  21. datacurrent/exceptions.py +191 -0
  22. datacurrent/integrations/__init__.py +18 -0
  23. datacurrent/integrations/fastapi.py +76 -0
  24. datacurrent/integrations/starlette.py +75 -0
  25. datacurrent/observability/__init__.py +17 -0
  26. datacurrent/observability/logging.py +128 -0
  27. datacurrent/observability/metrics.py +127 -0
  28. datacurrent/py.typed +1 -0
  29. datacurrent/reliability/__init__.py +14 -0
  30. datacurrent/reliability/retry.py +134 -0
  31. datacurrent/reliability/timeout.py +39 -0
  32. datacurrent/transports/__init__.py +31 -0
  33. datacurrent/transports/_deps.py +23 -0
  34. datacurrent/transports/base.py +80 -0
  35. datacurrent/transports/http.py +211 -0
  36. datacurrent/transports/memory.py +171 -0
  37. datacurrent/transports/sse.py +374 -0
  38. datacurrent/transports/websocket.py +277 -0
  39. datacurrent-1.0.0.dist-info/METADATA +250 -0
  40. datacurrent-1.0.0.dist-info/RECORD +43 -0
  41. datacurrent-1.0.0.dist-info/WHEEL +5 -0
  42. datacurrent-1.0.0.dist-info/licenses/LICENSE +20 -0
  43. datacurrent-1.0.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,250 @@
1
+ Metadata-Version: 2.4
2
+ Name: datacurrent
3
+ Version: 1.0.0
4
+ Summary: Python streaming, made simple: async streams, operators, backpressure and real-time transports.
5
+ Author: DataCurrent contributors
6
+ License: MIT
7
+ Keywords: streaming,async,asyncio,real-time,data pipeline,stream processing,backpressure,reactive,event bus,pubsub,websocket,server-sent events,http streaming,concurrency,observability,http,https
8
+ Classifier: Development Status :: 5 - Production/Stable
9
+ Classifier: Framework :: AsyncIO
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: License :: OSI Approved :: MIT License
12
+ Classifier: Operating System :: OS Independent
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3.11
15
+ Classifier: Programming Language :: Python :: 3.12
16
+ Classifier: Programming Language :: Python :: 3.13
17
+ Classifier: Programming Language :: Python :: 3.14
18
+ Classifier: Programming Language :: Python :: 3 :: Only
19
+ Classifier: Topic :: Internet
20
+ Classifier: Topic :: Software Development :: Libraries
21
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
22
+ Classifier: Typing :: Typed
23
+ Requires-Python: >=3.11
24
+ Description-Content-Type: text/markdown
25
+ License-File: LICENSE
26
+ Requires-Dist: httpx>=0.27
27
+ Requires-Dist: websockets>=12
28
+ Provides-Extra: starlette
29
+ Requires-Dist: starlette>=0.36; extra == "starlette"
30
+ Provides-Extra: fastapi
31
+ Requires-Dist: fastapi>=0.110; extra == "fastapi"
32
+ Provides-Extra: all
33
+ Requires-Dist: starlette>=0.36; extra == "all"
34
+ Requires-Dist: fastapi>=0.110; extra == "all"
35
+ Provides-Extra: dev
36
+ Requires-Dist: pytest>=8; extra == "dev"
37
+ Requires-Dist: pytest-asyncio>=0.23; extra == "dev"
38
+ Requires-Dist: pytest-cov>=5; extra == "dev"
39
+ Requires-Dist: hypothesis>=6; extra == "dev"
40
+ Requires-Dist: build>=1.2; extra == "dev"
41
+ Requires-Dist: twine>=5; extra == "dev"
42
+ Requires-Dist: ruff>=0.6; extra == "dev"
43
+ Requires-Dist: mypy>=1.11; extra == "dev"
44
+ Requires-Dist: fastapi>=0.110; extra == "dev"
45
+ Dynamic: license-file
46
+
47
+ # DataCurrent
48
+
49
+ ### Python streaming, made simple.
50
+
51
+ DataCurrent is a production-ready asynchronous streaming library. It gives you
52
+ one consistent API for lists, async generators, queues, WebSockets, Server-Sent
53
+ Events and streaming HTTP responses.
54
+
55
+ **Version 1.0.0 · Stable / Production**
56
+
57
+ - 279 tests passing, with 100% line and branch coverage.
58
+ - Required networking dependencies install automatically.
59
+ - No broker, database, API key or hosted service.
60
+
61
+ ## Install
62
+
63
+ ```bash
64
+ pip install datacurrent
65
+ ```
66
+
67
+ Python 3.11 or newer is required. `httpx` and `websockets` are installed with the
68
+ package, so HTTP streaming, SSE and WebSocket clients work immediately.
69
+
70
+ Framework helpers are optional:
71
+
72
+ ```bash
73
+ pip install "datacurrent[fastapi]"
74
+ pip install "datacurrent[starlette]"
75
+ pip install "datacurrent[all]"
76
+ ```
77
+
78
+ ## Quick start
79
+
80
+ ```python
81
+ import asyncio
82
+ from datacurrent import Stream
83
+
84
+
85
+ async def main() -> None:
86
+ result = await (
87
+ Stream.from_iterable(range(10))
88
+ .filter(lambda number: number % 2 == 0)
89
+ .map(lambda number: number * number)
90
+ .take(4)
91
+ .collect()
92
+ )
93
+ print(result) # [0, 4, 16, 36]
94
+
95
+
96
+ asyncio.run(main())
97
+ ```
98
+
99
+ Streams are lazy and single-consumer:
100
+
101
+ ```python
102
+ stream = Stream.from_iterable([1, 2, 3])
103
+
104
+ async for item in stream:
105
+ print(item)
106
+
107
+ # A second iteration raises StreamConsumedError.
108
+ ```
109
+
110
+ Common terminals:
111
+
112
+ ```python
113
+ await Stream.from_iterable([1, 2, 3]).collect() # [1, 2, 3]
114
+ await Stream.from_iterable([1, 2, 3]).count() # 3
115
+ await Stream.from_iterable([3, 1, 2]).reduce(max) # 3
116
+ await Stream.empty().first("fallback") # "fallback"
117
+ ```
118
+
119
+ Async callbacks work everywhere a callback is accepted:
120
+
121
+ ```python
122
+ users = await Stream.from_iterable(user_ids).map(fetch_user, concurrency=8).collect()
123
+ ```
124
+
125
+ ## Operators
126
+
127
+ `map`, `filter`, `flat_map`, `take`, `skip`, `batch`, `buffer`, `distinct`,
128
+ `enumerate`, `window`, `debounce`, `throttle`, `timeout`, `retry`, `recover`,
129
+ `tap`, `zip`, `merge` and `concat`.
130
+
131
+ ```python
132
+ batches = Stream.from_iterable(range(1_000)).filter(lambda number: number % 3 == 0).batch(100)
133
+
134
+ async for batch in batches:
135
+ print(len(batch))
136
+ ```
137
+
138
+ ## Backpressure
139
+
140
+ Buffers are bounded and block the producer by default. Data is not silently
141
+ dropped.
142
+
143
+ ```python
144
+ stream = Stream.from_iterable(range(100_000)).buffer(size=64)
145
+ ```
146
+
147
+ Lossy behaviour must be explicit and is counted:
148
+
149
+ ```python
150
+ stream = Stream.from_iterable(range(10_000)).buffer(
151
+ size=16,
152
+ overflow="drop_oldest",
153
+ )
154
+ items = await stream.collect()
155
+ print(len(items), stream.stats["dropped"])
156
+ ```
157
+
158
+ Policies: `block`, `drop_newest`, `drop_oldest`, `error`.
159
+
160
+ ## Real-time data
161
+
162
+ ### WebSocket
163
+
164
+ ```python
165
+ from datacurrent import WebSocketStream
166
+
167
+ async with WebSocketStream.connect("wss://example.com/events") as stream:
168
+ await stream.send_json({"subscribe": "trades"})
169
+ async for message in stream:
170
+ print(message)
171
+ ```
172
+
173
+ ### Server-Sent Events
174
+
175
+ ```python
176
+ from datacurrent import SSEStream
177
+
178
+ async with SSEStream.connect("https://example.com/events") as stream:
179
+ async for event in stream:
180
+ print(event.event, event.json())
181
+ ```
182
+
183
+ ### Streaming HTTP
184
+
185
+ ```python
186
+ from datacurrent import HTTPStream
187
+
188
+ async with HTTPStream("https://example.com/feed.ndjson") as response:
189
+ async for line in response.iter_lines():
190
+ handle(line)
191
+ ```
192
+
193
+ ### Fan-out and events
194
+
195
+ ```python
196
+ from datacurrent import Channel, EventBus
197
+
198
+ channel = Channel(buffer_size=64)
199
+ first = channel.subscribe()
200
+ second = channel.subscribe()
201
+ await channel.publish("deploy finished")
202
+
203
+ bus = EventBus()
204
+
205
+
206
+ @bus.subscribe("user.*")
207
+ async def on_user(event):
208
+ print(event.topic, event.data)
209
+
210
+
211
+ await bus.publish("user.created", {"user_id": 123})
212
+ ```
213
+
214
+ ## Retries
215
+
216
+ ```python
217
+ from datacurrent import RetryPolicy
218
+
219
+ stream = Stream.from_factory(connect_and_read).retry(
220
+ RetryPolicy(max_attempts=3, base_delay=0.2, jitter=0.1)
221
+ )
222
+ ```
223
+
224
+ Retries require a replayable source, such as a factory or a list. A consumed
225
+ generator raises `NonReplayableStreamError` instead of silently restarting.
226
+
227
+ ## Why DataCurrent
228
+
229
+ - One model for iterables, queues, HTTP, SSE and WebSockets.
230
+ - Backpressure by default, with explicit and counted drop policies.
231
+ - Bounded concurrency and cancellation-safe cleanup.
232
+ - No infrastructure: no broker, database or external account.
233
+ - Explicit delivery semantics; no false durability claims.
234
+ - Typed API and sync or async callbacks throughout.
235
+
236
+ HTTP clients such as `httpx` and `aiohttp` handle requests; DataCurrent adds the
237
+ stream engine around them. Reactive libraries provide operator algebra, while
238
+ broker frameworks require Kafka, Redis or RabbitMQ. DataCurrent is the
239
+ in-process streaming layer that works without any of them.
240
+
241
+ ## Compatibility and limits
242
+
243
+ - Python 3.11+ on asyncio; no Trio or AnyIO backend.
244
+ - In-memory `Channel` and `EventBus` delivery is at most once.
245
+ - No durable broker adapters or OpenTelemetry exporter in 1.0.0.
246
+ - Not published to PyPI; the project name is provisional.
247
+
248
+ ## License
249
+
250
+ MIT.
@@ -0,0 +1,43 @@
1
+ datacurrent/__init__.py,sha256=-LVJm3Qd2yjbLOYt2NO9mdViiwPnWuzLoEtValxiDKg,3387
2
+ datacurrent/_version.py,sha256=FZ-fDfPIlmCOb96GbhTHdze7YhOilXVqbGvUOdNv1SM,179
3
+ datacurrent/config.py,sha256=AQvYeNdQvkePSY-EbE0Q0JhEswVKExXzLnJ9Lg_1ESM,2963
4
+ datacurrent/exceptions.py,sha256=Nra8RGSm-bwx7iKt6CK_VeRhvINwjVHgEXdRToHZ5jI,6124
5
+ datacurrent/py.typed,sha256=MEVxnsuDFCH3jsQWkwO_BItWvy5RNDh3BRxEDX8yV4M,70
6
+ datacurrent/buffering/__init__.py,sha256=RUIxcxAHF8LumK1ijgvnbWuW6mDE3GJVXRYcJwavfN4,249
7
+ datacurrent/buffering/backpressure.py,sha256=DwxQg7CVQ8tZyYcyYrgeEW9e5EDokeLRHXV0Ew5wti8,1732
8
+ datacurrent/buffering/queue.py,sha256=YSv_wA-kvMEllSTgmCnZqWQiqXGoDfDqYf1DRPYk470,9786
9
+ datacurrent/concurrency/__init__.py,sha256=9b91jurrbN9ImZpzJ9TEBXmOXYFGISdGKid7JzF4m30,257
10
+ datacurrent/concurrency/limits.py,sha256=FNCbe6tKbL2IbfhoZ8-l0ycH9sYXk_d2_jxLGXFBdAk,2933
11
+ datacurrent/concurrency/tasks.py,sha256=8ptFva17eu42rfKeiCLmbjlNY-yjae1OrG1tPZOzIMw,2743
12
+ datacurrent/core/__init__.py,sha256=eHvFAkOuodDQav1C2BcLIXQeXxP7ek_rtNIREg-Ieek,394
13
+ datacurrent/core/_util.py,sha256=kXtOe--SgQ5tigGBeG0_TiakmM5dSYywD3s5TdpD43E,1272
14
+ datacurrent/core/lifecycle.py,sha256=TgYtrMbvByR3401jSigEItLXi_M_x841JCW0mf-tTkI,2432
15
+ datacurrent/core/operators.py,sha256=jDqYoWOAMUNGiaBrY4fgisehPuL4K8j7Ag8EoH62xDs,25430
16
+ datacurrent/core/pipeline.py,sha256=CIbcP3_l3t7SKajgplg9zycoyIpv9nb24ssvfKkZcWQ,1848
17
+ datacurrent/core/sink.py,sha256=NOy6fpc4y_vWDEU3m9AXyCj_2EDcUTxxjAqsgif_nYk,2078
18
+ datacurrent/core/stream.py,sha256=vN3pjR39RHMI2wVMmDpZQydcboTI3mCJZO-k7qOUBXM,20270
19
+ datacurrent/events/__init__.py,sha256=2QGcVd5f7XX7m1tuVokL4ioICgs_IsFu_w1rS_ypqNA,279
20
+ datacurrent/events/bus.py,sha256=1c_-q4SU4dGl9THdTGJ7umoTc2iNyVBudukgcio3pRw,13722
21
+ datacurrent/events/routing.py,sha256=am9L59dcnmeBVEmuuyfT6H0amiGuAWoSA8W42OxlSH0,1890
22
+ datacurrent/events/subscriptions.py,sha256=Ye4Y0lNkZuL8xbrRrvUQuLdblKoolb7VZ0DiMSo5b8w,2271
23
+ datacurrent/integrations/__init__.py,sha256=E44jhwY2DQDO3yYjw5IF61IyO4l5E6z-sIun7Cr_m_s,479
24
+ datacurrent/integrations/fastapi.py,sha256=236CnlNOdXUFA-OZnSGxfZaUhc2NHw7y2hSHXKAgyQo,2419
25
+ datacurrent/integrations/starlette.py,sha256=VMMOWt8WKmoRWulY_q622Jfib16C2o6Co9oVs3SJiuQ,2156
26
+ datacurrent/observability/__init__.py,sha256=98V3UcsXK9v1CM81kTiT6JbSr2Kc0v43ypuHSeYs9so,403
27
+ datacurrent/observability/logging.py,sha256=yGsZfrTK0qBArsbdVc-ouZVor49XucIDGCbITCXmqv0,3464
28
+ datacurrent/observability/metrics.py,sha256=A5YWDo8lkSfCIygkzJwtceFJXLsteEFb6FDaTpayOgo,3646
29
+ datacurrent/reliability/__init__.py,sha256=jyfZU6cT_i-Fhn4O6y3RKZfn4D4EcJXiOoLPLM24oak,314
30
+ datacurrent/reliability/retry.py,sha256=VVlnvKdZ9RQJo4Ptb98V-644A9_sNqXbORhHirhuOFg,4965
31
+ datacurrent/reliability/timeout.py,sha256=XTYHTlen4IO72452M8KvjJT3w1QJdrhIkQRM9a_kb1w,1135
32
+ datacurrent/transports/__init__.py,sha256=mU6RnvlCtYHyfJ_vCF7hZCFAj9bG306tr2MVZYs4yBM,610
33
+ datacurrent/transports/_deps.py,sha256=vbUjFWdFLG3SxGMyGF8Ncu7uMcRloERHOZlA87ueRbw,623
34
+ datacurrent/transports/base.py,sha256=GQx-eiAkP9sSUaMsY-oG_3qOS1EGHS6SpZ-1_PMAr5s,2397
35
+ datacurrent/transports/http.py,sha256=HXz1H4D-6JhejcQsZp9H0tcDqu2dxd-abxWOcuD-mL4,7497
36
+ datacurrent/transports/memory.py,sha256=BGAZyUbu_-7l8KDFATxBctHb8rQz9_Dkyn-c0ChbZn4,5495
37
+ datacurrent/transports/sse.py,sha256=bUeH2N7DA0aJGlDN7irJ_yVo5eLtS104Ek9o6mBV4iY,13147
38
+ datacurrent/transports/websocket.py,sha256=RNBqzQv6rXZarXJywgfoIO0VBN6c1rX94Y5Zzpr9dGg,10589
39
+ datacurrent-1.0.0.dist-info/licenses/LICENSE,sha256=8uPxhvCmrJv91ttoxbEdtoh7xoifHgKLacwpMmjLYKU,1073
40
+ datacurrent-1.0.0.dist-info/METADATA,sha256=-G30SZO8MCyA67E6-OD5wx1rymB6cny20vXc9aoWtLc,7186
41
+ datacurrent-1.0.0.dist-info/WHEEL,sha256=mOdXR9C3wMVov7cSY8PY-XCzo3SmmWCHvGQr5csJoao,91
42
+ datacurrent-1.0.0.dist-info/top_level.txt,sha256=CUBOKcU2k3gV2eRDU5JYl49MClij1kYAjK8TN19Ws9s,12
43
+ datacurrent-1.0.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (84.2.1)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,20 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 CoderProandTester
4
+ Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ of this software and associated documentation files (the "Software"), to deal
6
+ in the Software without restriction, including without limitation the rights
7
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ copies of the Software, and to permit persons to whom the Software is
9
+ furnished to do so, subject to the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be included in all
12
+ copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
+ SOFTWARE.
@@ -0,0 +1 @@
1
+ datacurrent