flo-python 0.1.0.dev3__tar.gz → 0.1.0.dev4__tar.gz
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.
- {flo_python-0.1.0.dev3 → flo_python-0.1.0.dev4}/PKG-INFO +1 -1
- {flo_python-0.1.0.dev3 → flo_python-0.1.0.dev4}/examples/worker.py +30 -47
- {flo_python-0.1.0.dev3 → flo_python-0.1.0.dev4}/pyproject.toml +1 -1
- {flo_python-0.1.0.dev3 → flo_python-0.1.0.dev4}/src/flo/client.py +4 -2
- {flo_python-0.1.0.dev3 → flo_python-0.1.0.dev4}/src/flo/worker.py +31 -3
- {flo_python-0.1.0.dev3 → flo_python-0.1.0.dev4}/.github/workflows/ci.yml +0 -0
- {flo_python-0.1.0.dev3 → flo_python-0.1.0.dev4}/.github/workflows/release.yml +0 -0
- {flo_python-0.1.0.dev3 → flo_python-0.1.0.dev4}/.gitignore +0 -0
- {flo_python-0.1.0.dev3 → flo_python-0.1.0.dev4}/LICENSE +0 -0
- {flo_python-0.1.0.dev3 → flo_python-0.1.0.dev4}/README.md +0 -0
- {flo_python-0.1.0.dev3 → flo_python-0.1.0.dev4}/examples/basic.py +0 -0
- {flo_python-0.1.0.dev3 → flo_python-0.1.0.dev4}/examples/stream_worker.py +0 -0
- {flo_python-0.1.0.dev3 → flo_python-0.1.0.dev4}/examples/test_decorator.py +0 -0
- {flo_python-0.1.0.dev3 → flo_python-0.1.0.dev4}/src/flo/__init__.py +0 -0
- {flo_python-0.1.0.dev3 → flo_python-0.1.0.dev4}/src/flo/actions.py +0 -0
- {flo_python-0.1.0.dev3 → flo_python-0.1.0.dev4}/src/flo/exceptions.py +0 -0
- {flo_python-0.1.0.dev3 → flo_python-0.1.0.dev4}/src/flo/kv.py +0 -0
- {flo_python-0.1.0.dev3 → flo_python-0.1.0.dev4}/src/flo/processing.py +0 -0
- {flo_python-0.1.0.dev3 → flo_python-0.1.0.dev4}/src/flo/queue.py +0 -0
- {flo_python-0.1.0.dev3 → flo_python-0.1.0.dev4}/src/flo/streams.py +0 -0
- {flo_python-0.1.0.dev3 → flo_python-0.1.0.dev4}/src/flo/types.py +0 -0
- {flo_python-0.1.0.dev3 → flo_python-0.1.0.dev4}/src/flo/wire.py +0 -0
- {flo_python-0.1.0.dev3 → flo_python-0.1.0.dev4}/src/flo/workflows.py +0 -0
- {flo_python-0.1.0.dev3 → flo_python-0.1.0.dev4}/tests/__init__.py +0 -0
- {flo_python-0.1.0.dev3 → flo_python-0.1.0.dev4}/tests/conftest.py +0 -0
- {flo_python-0.1.0.dev3 → flo_python-0.1.0.dev4}/tests/order-workflow.yaml +0 -0
- {flo_python-0.1.0.dev3 → flo_python-0.1.0.dev4}/tests/test_wire.py +0 -0
- {flo_python-0.1.0.dev3 → flo_python-0.1.0.dev4}/tests/test_workflows.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: flo-python
|
|
3
|
-
Version: 0.1.0.
|
|
3
|
+
Version: 0.1.0.dev4
|
|
4
4
|
Summary: Python SDK for the Flo distributed systems platform
|
|
5
5
|
Project-URL: Homepage, https://github.com/floruntime/flo-python
|
|
6
6
|
Project-URL: Documentation, https://github.com/floruntime/flo-python#readme
|
|
@@ -158,56 +158,39 @@ async def generate_report(ctx: ActionContext) -> bytes:
|
|
|
158
158
|
|
|
159
159
|
|
|
160
160
|
async def main():
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
os.getenv("FLO_ENDPOINT", "localhost:3000"),
|
|
161
|
+
async with FloClient(
|
|
162
|
+
os.getenv("FLO_ENDPOINT", "localhost:4455"),
|
|
164
163
|
namespace=os.getenv("FLO_NAMESPACE", "myapp"),
|
|
165
164
|
debug=os.getenv("FLO_DEBUG", "").lower() in ("1", "true"),
|
|
166
|
-
)
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
concurrency=5,
|
|
172
|
-
action_timeout=300, # 5 minutes
|
|
173
|
-
)
|
|
165
|
+
) as client:
|
|
166
|
+
worker = client.new_action_worker(
|
|
167
|
+
concurrency=5,
|
|
168
|
+
action_timeout=300, # 5 minutes
|
|
169
|
+
)
|
|
174
170
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
"
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
loop = asyncio.get_running_loop()
|
|
199
|
-
for sig in (signal.SIGINT, signal.SIGTERM):
|
|
200
|
-
loop.add_signal_handler(sig, signal_handler)
|
|
201
|
-
|
|
202
|
-
# Start worker (blocks until stopped)
|
|
203
|
-
logger.info("Starting worker...")
|
|
204
|
-
try:
|
|
205
|
-
await worker.start()
|
|
206
|
-
except KeyboardInterrupt:
|
|
207
|
-
logger.info("Interrupted")
|
|
208
|
-
finally:
|
|
209
|
-
await worker.close()
|
|
210
|
-
await client.close()
|
|
171
|
+
# Register action handlers
|
|
172
|
+
worker.register_action("process-order", process_order)
|
|
173
|
+
worker.register_action("send-notification", send_notification)
|
|
174
|
+
worker.register_action("generate-report", generate_report)
|
|
175
|
+
|
|
176
|
+
# Register using decorator syntax
|
|
177
|
+
@worker.action("health-check")
|
|
178
|
+
async def health_check(ctx: ActionContext) -> bytes:
|
|
179
|
+
return ctx.to_bytes({"status": "healthy", "worker_id": ctx.task_id})
|
|
180
|
+
|
|
181
|
+
# Handle shutdown signals
|
|
182
|
+
def signal_handler():
|
|
183
|
+
logger.info("Received shutdown signal")
|
|
184
|
+
worker.stop()
|
|
185
|
+
|
|
186
|
+
loop = asyncio.get_running_loop()
|
|
187
|
+
for sig in (signal.SIGINT, signal.SIGTERM):
|
|
188
|
+
loop.add_signal_handler(sig, signal_handler)
|
|
189
|
+
|
|
190
|
+
# Start worker (blocks until stopped)
|
|
191
|
+
logger.info("Starting worker...")
|
|
192
|
+
async with worker:
|
|
193
|
+
await worker.start()
|
|
211
194
|
logger.info("Worker shutdown complete")
|
|
212
195
|
|
|
213
196
|
|
|
@@ -372,11 +372,13 @@ class FloClient:
|
|
|
372
372
|
Returns:
|
|
373
373
|
A new ActionWorker instance ready to register actions and start.
|
|
374
374
|
|
|
375
|
-
Example
|
|
375
|
+
Example::
|
|
376
|
+
|
|
376
377
|
async with FloClient("localhost:3000", namespace="myapp") as client:
|
|
377
378
|
worker = client.new_action_worker(concurrency=5)
|
|
378
379
|
worker.register_action("process-order", process_order)
|
|
379
|
-
|
|
380
|
+
async with worker:
|
|
381
|
+
await worker.start()
|
|
380
382
|
"""
|
|
381
383
|
from .worker import ActionWorker
|
|
382
384
|
|
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
Provides ActionWorker for executing actions and StreamWorker for
|
|
4
4
|
processing stream records via consumer groups.
|
|
5
5
|
|
|
6
|
-
Example
|
|
6
|
+
Example::
|
|
7
|
+
|
|
7
8
|
from flo import FloClient, ActionContext
|
|
8
9
|
|
|
9
10
|
async def process_order(ctx: ActionContext) -> bytes:
|
|
@@ -14,8 +15,9 @@ Example:
|
|
|
14
15
|
async def main():
|
|
15
16
|
async with FloClient("localhost:3000", namespace="myapp") as client:
|
|
16
17
|
worker = client.new_action_worker(concurrency=5)
|
|
17
|
-
worker.
|
|
18
|
-
|
|
18
|
+
worker.register_action("process-order", process_order)
|
|
19
|
+
async with worker:
|
|
20
|
+
await worker.start()
|
|
19
21
|
"""
|
|
20
22
|
|
|
21
23
|
import asyncio
|
|
@@ -626,6 +628,19 @@ class ActionWorker:
|
|
|
626
628
|
if self._client:
|
|
627
629
|
await self._client.close()
|
|
628
630
|
|
|
631
|
+
async def __aenter__(self) -> "ActionWorker":
|
|
632
|
+
"""Async context manager entry."""
|
|
633
|
+
return self
|
|
634
|
+
|
|
635
|
+
async def __aexit__(
|
|
636
|
+
self,
|
|
637
|
+
exc_type: type[BaseException] | None,
|
|
638
|
+
exc_val: BaseException | None,
|
|
639
|
+
exc_tb: object,
|
|
640
|
+
) -> None:
|
|
641
|
+
"""Async context manager exit — closes the worker."""
|
|
642
|
+
await self.close()
|
|
643
|
+
|
|
629
644
|
|
|
630
645
|
# =============================================================================
|
|
631
646
|
# Stream Worker
|
|
@@ -977,3 +992,16 @@ class StreamWorker:
|
|
|
977
992
|
self.stop()
|
|
978
993
|
if self._client:
|
|
979
994
|
await self._client.close()
|
|
995
|
+
|
|
996
|
+
async def __aenter__(self) -> "StreamWorker":
|
|
997
|
+
"""Async context manager entry."""
|
|
998
|
+
return self
|
|
999
|
+
|
|
1000
|
+
async def __aexit__(
|
|
1001
|
+
self,
|
|
1002
|
+
exc_type: type[BaseException] | None,
|
|
1003
|
+
exc_val: BaseException | None,
|
|
1004
|
+
exc_tb: object,
|
|
1005
|
+
) -> None:
|
|
1006
|
+
"""Async context manager exit — closes the stream worker."""
|
|
1007
|
+
await self.close()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|