edda-framework 0.9.1__py3-none-any.whl → 0.11.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.
edda/viewer_ui/app.py CHANGED
@@ -1296,6 +1296,8 @@ def start_viewer(edda_app: EddaApp, port: int = 8080, reload: bool = False) -> N
1296
1296
  "search_query": "",
1297
1297
  "started_after": None,
1298
1298
  "started_before": None,
1299
+ "input_filter_key": "",
1300
+ "input_filter_value": "",
1299
1301
  "instances": [],
1300
1302
  "next_page_token": None,
1301
1303
  "has_more": False,
@@ -1352,6 +1354,17 @@ def start_viewer(edda_app: EddaApp, port: int = 8080, reload: bool = False) -> N
1352
1354
  "click", lambda m=date_to_menu: m.open()
1353
1355
  )
1354
1356
 
1357
+ # Input data filter fields
1358
+ input_key = ui.input(
1359
+ label="Input Key",
1360
+ placeholder="e.g., input.order_id",
1361
+ ).classes("w-40")
1362
+
1363
+ input_value = ui.input(
1364
+ label="Input Value",
1365
+ placeholder="e.g., ORD-123",
1366
+ ).classes("w-36")
1367
+
1355
1368
  # Refresh button
1356
1369
  async def handle_refresh() -> None:
1357
1370
  """Handle refresh button click."""
@@ -1360,6 +1373,11 @@ def start_viewer(edda_app: EddaApp, port: int = 8080, reload: bool = False) -> N
1360
1373
  pagination_state["page_size"] = page_size_select.value
1361
1374
  pagination_state["started_after"] = date_from.value
1362
1375
  pagination_state["started_before"] = date_to.value
1376
+ pagination_state["input_filter_key"] = input_key.value
1377
+ pagination_state["input_filter_value"] = input_value.value
1378
+ # Debug output
1379
+ print(f"DEBUG: input_key.value = '{input_key.value}'")
1380
+ print(f"DEBUG: input_value.value = '{input_value.value}'")
1363
1381
  # Reset to first page
1364
1382
  pagination_state["current_token"] = None
1365
1383
  pagination_state["token_stack"] = []
@@ -1389,6 +1407,13 @@ def start_viewer(edda_app: EddaApp, port: int = 8080, reload: bool = False) -> N
1389
1407
  pagination_state["started_before"] + "T23:59:59"
1390
1408
  )
1391
1409
 
1410
+ # Build input_filters if key is provided
1411
+ input_filters = None
1412
+ if pagination_state["input_filter_key"]:
1413
+ input_filters = {
1414
+ pagination_state["input_filter_key"]: pagination_state["input_filter_value"]
1415
+ }
1416
+
1392
1417
  result = await service.get_instances_paginated(
1393
1418
  page_size=pagination_state["page_size"],
1394
1419
  page_token=pagination_state["current_token"],
@@ -1396,6 +1421,7 @@ def start_viewer(edda_app: EddaApp, port: int = 8080, reload: bool = False) -> N
1396
1421
  search_query=pagination_state["search_query"] or None,
1397
1422
  started_after=started_after,
1398
1423
  started_before=started_before,
1424
+ input_filters=input_filters,
1399
1425
  )
1400
1426
  pagination_state["instances"] = result["instances"]
1401
1427
  pagination_state["next_page_token"] = result["next_page_token"]
@@ -48,6 +48,7 @@ class WorkflowDataService:
48
48
  search_query: str | None = None,
49
49
  started_after: datetime | None = None,
50
50
  started_before: datetime | None = None,
51
+ input_filters: dict[str, Any] | None = None,
51
52
  ) -> dict[str, Any]:
52
53
  """
53
54
  Get workflow instances with cursor-based pagination and filtering.
@@ -59,6 +60,8 @@ class WorkflowDataService:
59
60
  search_query: Search by workflow name or instance ID (partial match)
60
61
  started_after: Filter instances started after this datetime
61
62
  started_before: Filter instances started before this datetime
63
+ input_filters: Filter by input data values. Keys are JSON paths
64
+ (e.g., "order_id"), values are expected values (exact match).
62
65
 
63
66
  Returns:
64
67
  Dictionary containing:
@@ -75,6 +78,7 @@ class WorkflowDataService:
75
78
  instance_id_filter=search_query,
76
79
  started_after=started_after,
77
80
  started_before=started_before,
81
+ input_filters=input_filters,
78
82
  )
79
83
  return result
80
84
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: edda-framework
3
- Version: 0.9.1
3
+ Version: 0.11.0
4
4
  Summary: Lightweight Durable Execution Framework
5
5
  Project-URL: Homepage, https://github.com/i2y/edda
6
6
  Project-URL: Documentation, https://github.com/i2y/edda#readme
@@ -28,6 +28,8 @@ Requires-Dist: httpx>=0.28.1
28
28
  Requires-Dist: pydantic>=2.0.0
29
29
  Requires-Dist: sqlalchemy[asyncio]>=2.0.0
30
30
  Requires-Dist: uvloop>=0.22.1
31
+ Provides-Extra: cpu-monitor
32
+ Requires-Dist: psutil>=5.9.0; extra == 'cpu-monitor'
31
33
  Provides-Extra: dev
32
34
  Requires-Dist: black>=25.9.0; extra == 'dev'
33
35
  Requires-Dist: mcp>=1.22.0; extra == 'dev'
@@ -42,12 +44,17 @@ Requires-Dist: testcontainers[postgres]>=4.0.0; extra == 'dev'
42
44
  Requires-Dist: tsuno>=0.1.3; extra == 'dev'
43
45
  Provides-Extra: mcp
44
46
  Requires-Dist: mcp>=1.22.0; extra == 'mcp'
47
+ Provides-Extra: mirascope
48
+ Requires-Dist: mirascope[anthropic,google,openai]>=2.0.0a0; extra == 'mirascope'
49
+ Requires-Dist: pydantic-settings>=2.0.0; extra == 'mirascope'
45
50
  Provides-Extra: mysql
46
51
  Requires-Dist: aiomysql>=0.2.0; extra == 'mysql'
47
52
  Provides-Extra: opentelemetry
48
53
  Requires-Dist: opentelemetry-api>=1.20.0; extra == 'opentelemetry'
49
54
  Requires-Dist: opentelemetry-exporter-otlp>=1.20.0; extra == 'opentelemetry'
50
55
  Requires-Dist: opentelemetry-sdk>=1.20.0; extra == 'opentelemetry'
56
+ Provides-Extra: postgres-notify
57
+ Requires-Dist: asyncpg>=0.30.0; extra == 'postgres-notify'
51
58
  Provides-Extra: postgresql
52
59
  Requires-Dist: asyncpg>=0.30.0; extra == 'postgresql'
53
60
  Provides-Extra: server
@@ -87,7 +94,9 @@ For detailed documentation, visit [https://i2y.github.io/edda/](https://i2y.gith
87
94
  - ☁️ **CloudEvents Support**: Native support for CloudEvents protocol
88
95
  - ⏱️ **Event & Timer Waiting**: Free up worker resources while waiting for events or timers, resume on any available worker
89
96
  - 📬 **Channel-based Messaging**: Actor-model style communication with competing (job queue) and broadcast (fan-out) modes
97
+ - ⚡ **Instant Notifications**: PostgreSQL LISTEN/NOTIFY for near-instant event delivery (optional)
90
98
  - 🤖 **MCP Integration**: Expose durable workflows as AI tools via Model Context Protocol
99
+ - 🧠 **Mirascope Integration**: Durable LLM calls
91
100
  - 🌍 **ASGI/WSGI Support**: Deploy with your preferred server (uvicorn, gunicorn, uWSGI)
92
101
 
93
102
  ## Use Cases
@@ -221,6 +230,9 @@ uv add edda-framework --extra mysql
221
230
  # With Viewer UI
222
231
  uv add edda-framework --extra viewer
223
232
 
233
+ # With PostgreSQL instant notifications (LISTEN/NOTIFY)
234
+ uv add edda-framework --extra postgres-notify
235
+
224
236
  # All extras (PostgreSQL, MySQL, Viewer UI)
225
237
  uv add edda-framework --extra postgresql --extra mysql --extra viewer
226
238
  ```
@@ -272,6 +284,8 @@ pip install "git+https://github.com/i2y/edda.git[postgresql,viewer]"
272
284
 
273
285
  **Important**: For multi-process or multi-pod deployments (K8s, Docker Compose with multiple replicas, etc.), you **must** use PostgreSQL or MySQL. SQLite supports multiple async workers within a single process, but its table-level locking makes it unsuitable for multi-process/multi-pod scenarios.
274
286
 
287
+ > **Tip**: For PostgreSQL, install the `postgres-notify` extra for near-instant event delivery using LISTEN/NOTIFY instead of polling.
288
+
275
289
  ### Development Installation
276
290
 
277
291
  If you want to contribute to Edda or modify the framework itself:
@@ -492,6 +506,8 @@ app = EddaApp(
492
506
  # Connection pool settings (optional)
493
507
  pool_size=5, # Concurrent connections
494
508
  max_overflow=10, # Additional burst capacity
509
+ # Batch processing (optional)
510
+ max_workflows_per_batch=10, # Or "auto" / "auto:cpu" for dynamic scaling
495
511
  )
496
512
  ```
497
513
 
@@ -1,6 +1,6 @@
1
1
  edda/__init__.py,sha256=hGC6WR2R36M8LWC97F-0Rw4Ln0QUUT_1xC-7acOy_Fk,2237
2
2
  edda/activity.py,sha256=nRm9eBrr0lFe4ZRQ2whyZ6mo5xd171ITIVhqytUhOpw,21025
3
- edda/app.py,sha256=11-IczlJpCR_G-jWUvV1DIr_Zwm6bDJnFiNBQsZ79Zo,44306
3
+ edda/app.py,sha256=hoxDKp6q5qHl_dNLMkLxKhuibUC6D8FtuiWsIZkzwhA,61546
4
4
  edda/channels.py,sha256=Budi0FyxalmcAMwj50mX3WzRce5OuLKXGws0Hp_snfw,34745
5
5
  edda/compensation.py,sha256=iKLlnTxiF1YSatmYQW84EkPB1yMKUEZBtgjuGnghLtY,11824
6
6
  edda/context.py,sha256=pPn98-G5HgaOGDRzEhma58TzBulwsiTvmNEMLIu0XwI,21330
@@ -16,28 +16,35 @@ edda/integrations/__init__.py,sha256=F_CaTvlDEbldfOpPKq_U9ve1E573tS6XzqXnOtyHcXI
16
16
  edda/integrations/mcp/__init__.py,sha256=YK-8m0DIdP-RSqewlIX7xnWU7TD3NioCiW2_aZSgnn8,1232
17
17
  edda/integrations/mcp/decorators.py,sha256=31SmbDwmHEGvUNa3aaatW91hBkpnS5iN9uy47dID3J4,10037
18
18
  edda/integrations/mcp/server.py,sha256=Q5r4AbMn-9gBcy2CZocbgW7O0fn7Qb4e9CBJa1FEmzU,14507
19
+ edda/integrations/mirascope/__init__.py,sha256=TKKIs1W2ef88qT1oNoNm0-DQZObOc7tiuw3ul38nc6U,2509
20
+ edda/integrations/mirascope/agent.py,sha256=9y2HmyEDs5zREJgRuXI9EINjj09rWy991Khs7eDXfyY,16235
21
+ edda/integrations/mirascope/call.py,sha256=2pSDrja8Zix6d3TM4VejLmp1DHxbUnSAdSBSg7CFC7k,5754
22
+ edda/integrations/mirascope/decorator.py,sha256=TIK9qoR5ydaz-r33HAMuLrY4rsKJ5tsPlJJp5T_06B8,5488
23
+ edda/integrations/mirascope/types.py,sha256=vgEAu8EFTLSd92XSAxtZpMoe5gv93fe4Rm0DaXaDlV8,9088
19
24
  edda/integrations/opentelemetry/__init__.py,sha256=x1_PyyygGDW-rxQTwoIrGzyjKErXHOOKdquFAMlCOAo,906
20
25
  edda/integrations/opentelemetry/hooks.py,sha256=rCb6K_gJJMxjQ-UoJnbIOWsafapipzu7w-YPROZKxDA,21330
21
26
  edda/outbox/__init__.py,sha256=azXG1rtheJEjOyoWmMsBeR2jp8Bz02R3wDEd5tQnaWA,424
22
- edda/outbox/relayer.py,sha256=2tnN1aOQ8pKWfwEGIlYwYLLwyOKXBjZ4XZsIr1HjgK4,9454
27
+ edda/outbox/relayer.py,sha256=_yOZVpjj862lzMtEK47RMdVdbxXmL8v-FXppZWdy4Ag,10444
23
28
  edda/outbox/transactional.py,sha256=LFfUjunqRlGibaINi-efGXFFivWGO7v3mhqrqyGW6Nw,3808
24
29
  edda/serialization/__init__.py,sha256=hnOVJN-mJNIsSa_XH9jwhIydOsWvIfCaFaSd37HUplg,216
25
30
  edda/serialization/base.py,sha256=xJy2CY9gdJDCF0tmCor8NomL2Lr_w7cveVvxccuc-tA,1998
26
31
  edda/serialization/json.py,sha256=Dq96V4n1yozexjCPd_CL6Iuvh1u3jJhef6sTcNxXZeA,2842
27
- edda/storage/__init__.py,sha256=Q-kNJsjF8hMc2Q5MYFlLBENKExlNlKkbmUkwBOosj9I,216
32
+ edda/storage/__init__.py,sha256=NjvAzYV3SknACrC16ZQOA-xCKOj1-s3rBIWOS1ZGCaM,407
28
33
  edda/storage/models.py,sha256=vUwjiAOvp9uFNQgLK57kEGo7uzXplDZikOfnlOyed2M,12146
29
- edda/storage/protocol.py,sha256=NTUuLZ5_OlBiASaJIRuz5x7NykpCOjQgDWWNrRQzong,39021
30
- edda/storage/sqlalchemy_storage.py,sha256=KvSGapeKJ3hhClXNxFKHByD3Key5aidxBMUjs6-EJvE,136811
34
+ edda/storage/notify_base.py,sha256=gUb-ypG1Bo0c-KrleYmC7eKtdwQNUeqGS5k7UILlSsQ,5055
35
+ edda/storage/pg_notify.py,sha256=to5rDIQbiqqkNNVMODye_KvY4EDqRSUQblTeoeDZv8w,11850
36
+ edda/storage/protocol.py,sha256=vdB5GvBen8lgUA0qEfBXfQTLbVfGKeBTQuEwSUqLZtI,39463
37
+ edda/storage/sqlalchemy_storage.py,sha256=IAc8SYHM2xoJEIVDG05_mkguWQGB3wIAALsc0QI8EcE,144484
31
38
  edda/viewer_ui/__init__.py,sha256=N1-T33SXadOXcBsDSgJJ9Iqz4y4verJngWryQu70c5c,517
32
- edda/viewer_ui/app.py,sha256=CqHKsUj5pcysHCk0aRfkEqV4DIV4l3GzOPKBJ5DTYOQ,95624
39
+ edda/viewer_ui/app.py,sha256=K3c5sMeJz_AE9gh5QftxwvfDthLeJi1i2CDkP9gb4Ig,96695
33
40
  edda/viewer_ui/components.py,sha256=A0IxLwgj_Lu51O57OfzOwME8jzoJtKegEVvSnWc7uPo,45174
34
- edda/viewer_ui/data_service.py,sha256=yzmPz67rBoECY7eNK5nl6YS3jIZAi-haaqrP0GIgJYE,36373
41
+ edda/viewer_ui/data_service.py,sha256=KOqnWr-Y8seH_dkJH_ejHRfxQqn7aY8Ni5C54tx2Z-E,36621
35
42
  edda/viewer_ui/theme.py,sha256=mrXoXLRzgSnvE2a58LuMcPJkhlvHEDMWVa8Smqtk4l0,8118
36
43
  edda/visualizer/__init__.py,sha256=DOpDstNhR0VcXAs_eMKxaL30p_0u4PKZ4o2ndnYhiRo,343
37
44
  edda/visualizer/ast_analyzer.py,sha256=plmx7C9X_X35xLY80jxOL3ljg3afXxBePRZubqUIkxY,13663
38
45
  edda/visualizer/mermaid_generator.py,sha256=XWa2egoOTNDfJEjPcwoxwQmblUqXf7YInWFjFRI1QGo,12457
39
- edda_framework-0.9.1.dist-info/METADATA,sha256=8m1LKjz9cWbmwsa7V-FAEIQdgM3_63wan3Yml58KToE,35741
40
- edda_framework-0.9.1.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
41
- edda_framework-0.9.1.dist-info/entry_points.txt,sha256=dPH47s6UoJgUZxHoeSMqZsQkLaSE-SGLi-gh88k2WrU,48
42
- edda_framework-0.9.1.dist-info/licenses/LICENSE,sha256=udxb-V7_cYKTHqW7lNm48rxJ-Zpf0WAY_PyGDK9BPCo,1069
43
- edda_framework-0.9.1.dist-info/RECORD,,
46
+ edda_framework-0.11.0.dist-info/METADATA,sha256=AkgFtGUJNfhOoHXzti_R7fLli1q45Bg5xO6TfpjvsO8,36587
47
+ edda_framework-0.11.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
48
+ edda_framework-0.11.0.dist-info/entry_points.txt,sha256=dPH47s6UoJgUZxHoeSMqZsQkLaSE-SGLi-gh88k2WrU,48
49
+ edda_framework-0.11.0.dist-info/licenses/LICENSE,sha256=udxb-V7_cYKTHqW7lNm48rxJ-Zpf0WAY_PyGDK9BPCo,1069
50
+ edda_framework-0.11.0.dist-info/RECORD,,