planar 0.8.0__py3-none-any.whl → 0.9.1__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 (39) hide show
  1. planar/_version.py +1 -1
  2. planar/ai/agent.py +19 -3
  3. planar/ai/agent_base.py +1 -5
  4. planar/ai/agent_utils.py +0 -72
  5. planar/ai/models.py +30 -0
  6. planar/ai/pydantic_ai.py +12 -11
  7. planar/app.py +6 -11
  8. planar/config.py +6 -1
  9. planar/data/__init__.py +17 -0
  10. planar/data/config.py +49 -0
  11. planar/data/dataset.py +263 -0
  12. planar/data/exceptions.py +19 -0
  13. planar/data/test_dataset.py +354 -0
  14. planar/db/db.py +39 -21
  15. planar/dependencies.py +30 -0
  16. planar/files/test_files.py +6 -7
  17. planar/modeling/mixins/test_auditable.py +2 -2
  18. planar/modeling/orm/planar_base_entity.py +4 -1
  19. planar/routers/agents_router.py +52 -4
  20. planar/routers/test_agents_router.py +2 -2
  21. planar/routers/test_files_router.py +2 -2
  22. planar/routers/test_object_config_router.py +2 -2
  23. planar/routers/test_routes_security.py +3 -2
  24. planar/routers/test_rule_router.py +2 -2
  25. planar/routers/test_workflow_router.py +6 -8
  26. planar/rules/__init__.py +12 -18
  27. planar/scaffold_templates/app/flows/process_invoice.py.j2 +1 -2
  28. planar/scaffold_templates/planar.dev.yaml.j2 +9 -0
  29. planar/scaffold_templates/planar.prod.yaml.j2 +14 -0
  30. planar/scaffold_templates/pyproject.toml.j2 +2 -2
  31. planar/test_sqlalchemy.py +36 -1
  32. planar/testing/fixtures.py +3 -17
  33. planar/testing/workflow_observer.py +2 -2
  34. planar/workflows/notifications.py +39 -3
  35. planar/workflows/test_lock_timeout.py +4 -4
  36. {planar-0.8.0.dist-info → planar-0.9.1.dist-info}/METADATA +27 -13
  37. {planar-0.8.0.dist-info → planar-0.9.1.dist-info}/RECORD +39 -33
  38. {planar-0.8.0.dist-info → planar-0.9.1.dist-info}/WHEEL +0 -0
  39. {planar-0.8.0.dist-info → planar-0.9.1.dist-info}/entry_points.txt +0 -0
@@ -26,7 +26,7 @@ async def long_running_workflow():
26
26
  return "finished"
27
27
 
28
28
 
29
- async def test_lock_timer_extension(mem_db_engine):
29
+ async def test_lock_timer_extension(tmp_db_engine):
30
30
  tracer = SynchronizableTracer()
31
31
  tracer_var.set(tracer)
32
32
  lock_acquired = tracer.instrument(
@@ -36,7 +36,7 @@ async def test_lock_timer_extension(mem_db_engine):
36
36
  TraceSpec(function_name="lock_heartbeat", message="commit")
37
37
  )
38
38
 
39
- async with new_session(mem_db_engine) as session:
39
+ async with new_session(tmp_db_engine) as session:
40
40
  # This test verifies that when a workflow is executing, the heartbeat task
41
41
  # (lock_heartbeat) extends the workflow's lock_until field. We run a
42
42
  # long-running workflow (which sleeps for 1 second) with a short lock
@@ -95,7 +95,7 @@ async def crashed_worker_workflow():
95
95
  return "completed"
96
96
 
97
97
 
98
- async def test_orchestrator_resumes_crashed_worker(mem_db_engine):
98
+ async def test_orchestrator_resumes_crashed_worker(tmp_db_engine):
99
99
  # This test simulates the scenario where a worker has “crashed” after
100
100
  # locking a workflow. We start a workflow that suspends. Then we add a LockedResource
101
101
  # record with an expired lock_until time to simulate a crashed
@@ -105,7 +105,7 @@ async def test_orchestrator_resumes_crashed_worker(mem_db_engine):
105
105
  # the workflow to be resumed. Finally, we verify that the workflow
106
106
  # completes successfully. Start the workflow – its first execution will
107
107
  # suspend.
108
- async with new_session(mem_db_engine) as session:
108
+ async with new_session(tmp_db_engine) as session:
109
109
  session_var.set(session)
110
110
  wf = await crashed_worker_workflow.start()
111
111
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: planar
3
- Version: 0.8.0
3
+ Version: 0.9.1
4
4
  Summary: Add your description here
5
5
  License-Expression: LicenseRef-Proprietary
6
6
  Requires-Python: >=3.12
@@ -27,6 +27,10 @@ Provides-Extra: azure
27
27
  Requires-Dist: aiohttp>=3.8.0; extra == 'azure'
28
28
  Requires-Dist: azure-identity>=1.15.0; extra == 'azure'
29
29
  Requires-Dist: azure-storage-blob>=12.19.0; extra == 'azure'
30
+ Provides-Extra: data
31
+ Requires-Dist: ducklake>=0.1.1; extra == 'data'
32
+ Requires-Dist: ibis-framework[duckdb]>=10.8.0; extra == 'data'
33
+ Requires-Dist: polars>=1.31.0; extra == 'data'
30
34
  Provides-Extra: otel
31
35
  Requires-Dist: opentelemetry-api>=1.34.1; extra == 'otel'
32
36
  Requires-Dist: opentelemetry-exporter-otlp>=1.34.1; extra == 'otel'
@@ -57,8 +61,8 @@ The workflow system in Planar is a sophisticated orchestration framework that en
57
61
  - Concurrency Control: Uses a locking mechanism to prevent multiple executions
58
62
  - Recovery: Can recover from crashes by detecting stalled workflows
59
63
  3. Main Components:
60
- - @workflow decorator: Marks a function as a workflow with persistence
61
- - @step decorator: Wraps function calls inside a workflow to make them resumable
64
+ - `@workflow` decorator: Marks a function as a workflow with persistence
65
+ - `@step` decorator: Wraps function calls inside a workflow to make them resumable
62
66
  - Suspend class: Allows pausing workflow execution
63
67
  - workflow_orchestrator: Background task that finds and resumes suspended workflows
64
68
  4. REST API Integration:
@@ -74,18 +78,20 @@ The workflow system in Planar is a sophisticated orchestration framework that en
74
78
 
75
79
  Planar builds on Python's async/await system but adds durability. When you create a workflow:
76
80
 
81
+ ```python
77
82
  @workflow
78
83
  async def process_order(order_id: str):
79
84
  # workflow steps
85
+ ```
80
86
 
81
87
  The system:
82
88
 
83
- 1. Enforces that all workflows and steps must be coroutines (async def)
84
- 2. Accesses the underlying generator of the coroutine via coro.__await__()
85
- 3. Manually drives this generator by calling next(gen) and gen.send(result)
89
+ 1. Enforces that all workflows and steps must be coroutines (`async def`)
90
+ 2. Accesses the underlying generator of the coroutine via `coro.__await__()`
91
+ 3. Manually drives this generator by calling `next(gen)` and `gen.send(result)`
86
92
  4. Intercepts any values yielded from the coroutine to implement suspension
87
93
 
88
- The execute() function (lines 278-335) is the core that drives coroutine execution. It:
94
+ The `execute()` function (lines 278-335) is the core that drives coroutine execution. It:
89
95
  - Takes control of the coroutine's generator
90
96
  - Processes each yielded value
91
97
  - Handles regular awaits vs. suspensions differently
@@ -95,6 +101,7 @@ The workflow system in Planar is a sophisticated orchestration framework that en
95
101
 
96
102
  The Suspend class (lines 55-72) enables pausing workflows:
97
103
 
104
+ ```python
98
105
  class Suspend:
99
106
  def __init__(self, *, wakeup_at=None, interval=None):
100
107
  # Set when to wake up
@@ -102,36 +109,42 @@ The workflow system in Planar is a sophisticated orchestration framework that en
102
109
  def __await__(self):
103
110
  result = yield self
104
111
  return result
112
+ ```
105
113
 
106
114
  When you call:
115
+ ```python
107
116
  await suspend(interval=timedelta(minutes=5))
117
+ ```
108
118
 
109
119
  What happens:
110
- 1. The suspend() function uses the @step() decorator to mark it as resumable
120
+ 1. The `suspend()` function uses the `@step()` decorator to mark it as resumable
111
121
  2. Inside it creates and awaits a Suspend object
112
- 3. The __await__ method yields self (the Suspend instance) to the executor
113
- 4. The execute() function detects this is a Suspend object (lines 303-307)
122
+ 3. The `__await__` method yields self (the Suspend instance) to the executor
123
+ 4. The `execute()` function detects this is a Suspend object (lines 303-307)
114
124
  5. It sets the workflow status to SUSPENDED and persists the wake-up time
115
- 6. Later, the orchestrator finds workflows ready to resume based on wakeup_at
125
+ 6. Later, the orchestrator finds workflows ready to resume based on `wakeup_at`
116
126
  7. When resumed, execution continues right after the suspension point
117
127
 
118
128
  YieldWrapper
119
129
 
120
130
  The YieldWrapper class (lines 48-53) is crucial for handling regular async operations:
121
131
 
132
+ ```python
122
133
  class YieldWrapper:
123
134
  def __init__(self, value):
124
135
  self.value = value
125
136
  def __await__(self):
126
137
  return (yield self.value)
138
+ ```
127
139
 
128
140
  For non-Suspend yields (regular awaits), the system:
129
- 1. Wraps the yielded value in YieldWrapper
130
- 2. Awaits it to get the result from asyncio
141
+ 1. Wraps the yielded value in `YieldWrapper`
142
+ 2. Awaits it to get the result from `asyncio`
131
143
  3. Sends the result back to the workflow's generator
132
144
 
133
145
  This allows you to use normal async functions inside workflows:
134
146
 
147
+ ```python
135
148
  @workflow
136
149
  async def my_workflow():
137
150
  # This works because YieldWrapper passes through regular awaits
@@ -140,6 +153,7 @@ The workflow system in Planar is a sophisticated orchestration framework that en
140
153
  await suspend(interval=timedelta(hours=1))
141
154
  # When resumed days later, continues here
142
155
  return process_result(data)
156
+ ```
143
157
 
144
158
  The magic is that the workflow appears to be a normal async function, but the state is persisted across suspensions, allowing workflows to survive
145
159
  process restarts or even server reboots.
@@ -1,8 +1,9 @@
1
1
  planar/__init__.py,sha256=FAYRGjuJOH2Y_XYFA0-BrRFjuKdPzIShNbaYwJbtu6A,499
2
- planar/_version.py,sha256=dZWiMFvyJ9WmUBmP_1Yn0Ze7otmWd3MrPYqf8mefKr4,18
3
- planar/app.py,sha256=SKIpNY1K6NFF4_20kDxT40BIfJotiyhjNPwjU7P8_Ek,18695
2
+ planar/_version.py,sha256=MDn0Ro0DvGxuAuRTGL8IBqcm5nbo1P640CIS7xBBu2k,18
3
+ planar/app.py,sha256=VEs4jDlcisyOy9I9zEGMG_-Qm8ULKT36CSHjqrYit3o,18491
4
4
  planar/cli.py,sha256=2ObR5XkLGbdbnDqp5mrBzDVhSacHCNsVNSHnXkrMQzQ,9593
5
- planar/config.py,sha256=NHNrvJl8h1QkUHUxZ96Th_v1TSxoxf8u0C4CA1VBr2k,17557
5
+ planar/config.py,sha256=6J42G9rEVUiOyCAY3EwUTU3PPmWthGTnrHMzST9TMcc,17809
6
+ planar/dependencies.py,sha256=PH78fGk3bQfGnz-AphxH49307Y0XVgl3EY0LdGJnoik,1008
6
7
  planar/object_registry.py,sha256=RMleX5XE8OKDxlnMeyLpJ1Y280duub-tx1smR1zTlDg,3219
7
8
  planar/registry_items.py,sha256=UhZRIpbSoa_CV9OTl17pJfRLxItYp4Pxd9f5ZbJkGaM,2055
8
9
  planar/session.py,sha256=xLS9WPvaiy9nr2Olju1-C-7_sU5VXK8RuNdjuKndul4,1020
@@ -12,26 +13,31 @@ planar/test_cli.py,sha256=faR6CSuooHHyyB5Yt-p8CIr7mGtKrrU2TLQbc4Oe9bA,13834
12
13
  planar/test_config.py,sha256=HcmDu1nwKZZhzHQLGVyP9oxje-_g_XubEsvzRj28QPg,14328
13
14
  planar/test_object_config.py,sha256=izn4s2HmSDWpGtgpOTDmKeUYN2-63WDR1QtVQrT-x00,20135
14
15
  planar/test_object_registry.py,sha256=R7IwbB2GACm2HUuVZTeVY4V12XB9_JgSSeppPxiCdfs,480
15
- planar/test_sqlalchemy.py,sha256=F0aKqm5tStQj_Mqjh50kiLX4r7kphBFDOUDu_Iw7S3s,5573
16
+ planar/test_sqlalchemy.py,sha256=QTloaipWiFmlLTBGH6YCRkwi1R27gmQZnwprO7lPLfU,7058
16
17
  planar/test_utils.py,sha256=gKenXotj36SN_bb3bQpYPfD8t06IjnGBQqEgWpujHcA,3086
17
18
  planar/utils.py,sha256=v7q9AJyWgQWl9VPSN_0qxw3rBvYe-_Pb_KcwqSsjOFU,3103
18
19
  planar/ai/__init__.py,sha256=ABOKvqQOLlVJkptcvXcuLjVZZWEsK8h-1RyFGK7kib8,231
19
- planar/ai/agent.py,sha256=kcrFLQzIU7QPGNjgl_7irP1jJOReHs8EYz8-_H_TV0A,11929
20
- planar/ai/agent_base.py,sha256=X4Gl4PmxyxD_HLnVyxK7fnhKgmudznrGwcv5nMzAXWs,5349
21
- planar/ai/agent_utils.py,sha256=r7WGGMs5fCo5MlLX5vPlA9ry0mMzpSuf4Ro6Gnvp2TQ,5966
22
- planar/ai/models.py,sha256=Rxvt00kCaQzbU59LcYDegK7kV8qYTRVH3YhU3ufuJCY,3532
23
- planar/ai/pydantic_ai.py,sha256=IAVavvbqp7KIUpwFQwWf5hXtsxn2yMxIjl2NjeL3EsE,23423
20
+ planar/ai/agent.py,sha256=flgHU00LRT-UcP0TjMqDigi2jwWq6UoMpmCZSOTyyB0,12428
21
+ planar/ai/agent_base.py,sha256=iOOiUwbTiqckrZ-ZtlpkPCjSNE117gMwxrdgegO-P-0,5303
22
+ planar/ai/agent_utils.py,sha256=Yug1lt3uT7zLJ0X9uUBpKEomxucKaZiEUBIcf-RZILo,4052
23
+ planar/ai/models.py,sha256=aH61vkHJEhmupvGJHS87Nv7bpCpcfBJDO-N8k3k2ixc,4292
24
+ planar/ai/pydantic_ai.py,sha256=lYWtnIclOLRiEpBJi5r6Ey8gDBVlQIHTFa3iEzUNqWY,23525
24
25
  planar/ai/test_agent_serialization.py,sha256=zYLIxhYdFhOZzBrEBoQNyYLyNcNxWwaMTkjt_ARTkZk,8073
25
26
  planar/ai/utils.py,sha256=WVBW0TGaoKytC4bNd_a9lXrBf5QsDRut4GBcA53U2Ww,3116
27
+ planar/data/__init__.py,sha256=LwrWl925w1CN0aW645Wpj_kDp0B8j5SsPzjr9iyrcmI,285
28
+ planar/data/config.py,sha256=zp6ChI_2MUMbupEVQNY-BxzcdLvejXG33DCp0BujGVU,1209
29
+ planar/data/dataset.py,sha256=P0NVE2OvJcXMKqVylYczY2lSGR0pSWlPAHM_upKoBWQ,9507
30
+ planar/data/exceptions.py,sha256=AlhGQ_TReyEzfPSlqoXCjoZ1206Ut7dS4lrukVfGHaw,358
31
+ planar/data/test_dataset.py,sha256=w2kay2PE-BhkryM3cOKX0nzSr2G0nCJxDuW1QCeFbyk,9985
26
32
  planar/db/__init__.py,sha256=SNgB6unQ1f1E9dB9O-KrsPsYM17KLsgOW1u0ajqs57I,318
27
33
  planar/db/alembic.ini,sha256=8G9IWbmF61Vwp1BXbkNOXTTgCEUMBQhOK_e-nnpnSYY,4309
28
- planar/db/db.py,sha256=dELx4CHZkOAxFgHsW8qPlx2kUZ8J7cTlU6rHljMV_vg,12102
34
+ planar/db/db.py,sha256=VNpHH1R62tdWVLIV1I2ULmw3B8M6-RsM2ALG3VAVjSg,12790
29
35
  planar/db/alembic/env.py,sha256=cowI6O_4BMJPqDAukkbg69lzdsE44soi3ysxKGXbS_w,5207
30
36
  planar/db/alembic/script.py.mako,sha256=Cl7ixgLNtLk1gF5xFNXOnC9YYLX4cpFd8yHtEyY0_dY,699
31
37
  planar/db/alembic/versions/3476068c153c_initial_system_tables_migration.py,sha256=1FbzJyfapjegM-Mxd3HMMVA-8zVU6AnrnzEgIoc6eoQ,13204
32
38
  planar/files/__init__.py,sha256=fms64l32M8hPK0SINXxNCykr2EpjBTcdgnezVgaCwkc,120
33
39
  planar/files/models.py,sha256=zbZvMkoqoSnn7yOo26SRtEgtlHJbFIvwSht75APHQXk,6145
34
- planar/files/test_files.py,sha256=2GFAz39dIf6-bhmJaDFeOpS2sZN7VnLI60ky-e170Mc,8921
40
+ planar/files/test_files.py,sha256=nclsbLnbijCWQ-Aj8Yvo06hs72PygL1Wps7uk7716sc,8957
35
41
  planar/files/storage/azure_blob.py,sha256=PzCm8ZpyAMH9-N6VscTlLpud-CBLcQX9qC6YjbOSfZg,12316
36
42
  planar/files/storage/base.py,sha256=KO7jyKwjKg5fNSLvhxJWE-lsypv6LXXf7bgA34aflwY,2495
37
43
  planar/files/storage/config.py,sha256=jE9Dn6cG_a4x9pdaZkasOxjyWkK6hmplLrPjEsRXGLM,3473
@@ -57,20 +63,20 @@ planar/modeling/field_helpers.py,sha256=9SOHTWPzjlaiq7RF88wjug3NvAywFurcHn651YL_
57
63
  planar/modeling/json_schema_generator.py,sha256=NDqPkWQA_I7ywQXCEQfj5ub9u5KAFEcSQpXVkrCluV4,2864
58
64
  planar/modeling/mixins/__init__.py,sha256=Lwg5eL4VFfv61FRBvH5OZqIyfrSogxQlYLUDnWnSorg,320
59
65
  planar/modeling/mixins/auditable.py,sha256=WP7aDWVn1j22ZffKzYRpu23JQJ4vvHCU1qxcbgChwhc,1619
60
- planar/modeling/mixins/test_auditable.py,sha256=zIa63_0Y19wMF7oIvMcOj7RoIVH7ztQzis9kHFEKKR8,2912
66
+ planar/modeling/mixins/test_auditable.py,sha256=RSYesWWBysFEWTD39-yDhww3wCe1OPN9Yt3ywGmx4d8,2912
61
67
  planar/modeling/mixins/test_timestamp.py,sha256=oLKPvr8oUdjJPJRif81nn4YV_uwbxql_ojjXdKI7j7E,4366
62
68
  planar/modeling/mixins/test_uuid_primary_key.py,sha256=t9ZoB0dS4jjJVrHic7EeEh_g3eZeYV3mr0ylv3Kr1Io,1575
63
69
  planar/modeling/mixins/timestamp.py,sha256=-eHndCWztDiOxfCI2UknmphGeoHMJVDJG1Lz4KtkQUA,1641
64
70
  planar/modeling/mixins/uuid_primary_key.py,sha256=O1BtuXk5GdsfpwTS6nGZm1GNi0pdXKQ6Kt2f5ZjiuMc,453
65
71
  planar/modeling/orm/__init__.py,sha256=QwPgToKEf_gCdjAjKKmgh0xLTHGsboK1kH1a1a0tSy0,339
66
- planar/modeling/orm/planar_base_entity.py,sha256=nL1kT2k__F9Lmo1SW2XEfB6vJi_Fg72u-wW1F79eFTs,959
72
+ planar/modeling/orm/planar_base_entity.py,sha256=7X0d86mWABleTWpulnA91P80ZjlUdGd6bv-L_TIhR2Q,1151
67
73
  planar/modeling/orm/query_filter_builder.py,sha256=Q2qWojo1Pzkt3HY1DdkBINlsP7uTOg1OOSUmwlzjTs8,5335
68
74
  planar/modeling/orm/reexports.py,sha256=sP7nw8e1yp1cahpfsefO84P5n4TNnBRk1jVHuCuH4U4,290
69
75
  planar/object_config/__init__.py,sha256=8LbI3teg3jCKoUznZ7cal22C1URnHtJMpBokCHZQUWo,352
70
76
  planar/object_config/models.py,sha256=nCyK82JitZwzGwbaBa-dZVxHPnL51ZJ6h87a-KEwHAw,3078
71
77
  planar/object_config/object_config.py,sha256=MgaL-jBFJJtP6ipZ2eJs-KMhj94V_sT3QCSoVTpYP3Y,13609
72
78
  planar/routers/__init__.py,sha256=B_ZEbBuosX4ahPfvWZsyMIPmQm0rt6ail4nJA6NLfOk,379
73
- planar/routers/agents_router.py,sha256=plshAbCDuk1eNQB9H0wVZbcZ6dGqgL9ffEcwHcklTm8,6821
79
+ planar/routers/agents_router.py,sha256=trb1JPYVlaV7O2uoYvKIrLuTNGP_PmQSLZmXYFWrHkg,8251
74
80
  planar/routers/entity_router.py,sha256=7Y1LDSqI_ovoOGr9DGylGM8BmRxF-WSPQSwITJHc6NE,4841
75
81
  planar/routers/event.py,sha256=yvzzMQaKRoS2A0KSjQTyWcfmBzpt8xPNDfVW50XUSCw,2961
76
82
  planar/routers/files.py,sha256=udu6PeZ9AuOpNyJete21rWAVQyE0qnC7tnSyJ97AH4Y,5644
@@ -79,14 +85,14 @@ planar/routers/info.py,sha256=HQa-mumw4zitG61V9isJlZ3cMr8pEwlB54Ct_LrpJDo,4473
79
85
  planar/routers/models.py,sha256=RwXjXpJw2uyluM4Fjc34UA0Jm7J95cUjbmTTarD_P9k,4669
80
86
  planar/routers/object_config_router.py,sha256=zA8-gGBQp1-Gm3uCC4WJ6nLicFwt4CsCqCYLFp1lRN8,4802
81
87
  planar/routers/rule.py,sha256=d6giUwYRKzxQFPeoWbe8Ylp2Cxd71_uK8yoS9NrOOBg,3563
82
- planar/routers/test_agents_router.py,sha256=d_d_lZT5zuSxNY2MEu51SmgLRGNZ3yCpGUooAXLpEaY,6082
83
- planar/routers/test_files_router.py,sha256=_uYpRJkxSxyjFJAG7aj3letx25iDSkaOgZDTRHfU8TU,1559
84
- planar/routers/test_object_config_router.py,sha256=HBOsQZXccPuWOLCPxEsduSd93loswUsbSk3eTM6KHRc,11389
85
- planar/routers/test_routes_security.py,sha256=DsyEbpaNsLGTE_aWhs_KyePJxw2qTBviP2Tn-GZj3T8,5508
86
- planar/routers/test_rule_router.py,sha256=gCJO7-NVjkio-0ZHY2hNgPvubN-0NAPA3Hg5Jcrwe70,17203
87
- planar/routers/test_workflow_router.py,sha256=rjK1Eau-YWs3vZbuJ50Ae_8I8_8TfxQA0F8I2HeDl9o,16572
88
+ planar/routers/test_agents_router.py,sha256=jzRCLB21YcEfhaFUos_gfRp9WDdP38_cozTQkHbi9b4,6099
89
+ planar/routers/test_files_router.py,sha256=HfZF1zeJ9BD2jhE6s698Jo7sDpO55RJF5g1Ksup4jtM,1576
90
+ planar/routers/test_object_config_router.py,sha256=JpzoNlNONgljmGJYtrXnhtGhKjUT3YQMhP89fnt7dn4,11406
91
+ planar/routers/test_routes_security.py,sha256=lXHeYg_th4UaDWeANM-dzONF8p2bEtwXJYYUlftE9R8,5556
92
+ planar/routers/test_rule_router.py,sha256=08fa4sc7RaXvQzPCQQ4LaftfXuQwoPEDzcS4lesPG2Q,17220
93
+ planar/routers/test_workflow_router.py,sha256=w3Gl1Okr2FgKMIqcum3gD6XzVrYm82oSIj_znbtd-aQ,16592
88
94
  planar/routers/workflow.py,sha256=8R35ENZeB5Mdt7WfH2zZ75BPg2oQ9d8kL47P1qvP-7Q,18045
89
- planar/rules/__init__.py,sha256=gl5FSqLJMVPa04jqKtNNNH3alWeUsxq5CR71gmK-Xyk,662
95
+ planar/rules/__init__.py,sha256=lF3F8Rdf2ottjiJu0IeBdqhg1bckLhOqZFI2t-8KItM,474
90
96
  planar/rules/decorator.py,sha256=nxT17n9uwfXMOlk5lliw_cRS7Y83gMI6CQdrf_pB5yk,6666
91
97
  planar/rules/models.py,sha256=vC38JLeGzmU87L8BX4AyVJLJHmRYjWRmoHQ6S6ZlhPg,10186
92
98
  planar/rules/rule_configuration.py,sha256=B2G6mPnfxA277nF-Gr-B_Uely-ZOhz2jAhiwQMZuY-k,6508
@@ -107,12 +113,12 @@ planar/rules/test_data/portfolio_risk_monitor.json,sha256=tTvQOJJLhakGxG4CnA9fdB
107
113
  planar/rules/test_data/supply_chain_risk.json,sha256=fO0wV5ZnsZQpOP19Zp2troTMADaX0-KMpCxG_uHG198,7263
108
114
  planar/rules/test_data/warehouse_cross_docking.json,sha256=IPfcgNkY2sds301BeW6CjgFtK_zRyr27gI3UcqCB2Uo,5549
109
115
  planar/scaffold_templates/main.py.j2,sha256=HcV0PVzcyRDaJvNdDQIFiDR1MJlLquNQzNO9oNkCKDQ,322
110
- planar/scaffold_templates/planar.dev.yaml.j2,sha256=bUvPZKJDzSEjK1hffgs4RYWSMfOzViVP0_nOG0iw4T8,797
111
- planar/scaffold_templates/planar.prod.yaml.j2,sha256=DCWYIam7pdTMgWlWOcPNgDma5MHmH_QqjUO722SKE_4,555
112
- planar/scaffold_templates/pyproject.toml.j2,sha256=zD8UaEwK3uUYoGQuFuPZZCNdvqNS0faGrNHbD081DAU,182
116
+ planar/scaffold_templates/planar.dev.yaml.j2,sha256=I5-IqX7GJm6qA91WtUMw43L4hKACqgnER_H2racim4c,998
117
+ planar/scaffold_templates/planar.prod.yaml.j2,sha256=FahJ2atDtvVH7IUCatGq6h9hmyF8meeiWC8RLfWphOQ,867
118
+ planar/scaffold_templates/pyproject.toml.j2,sha256=nFfHWLp0sFK8cqjkdwBm6Hi6xsPzTNkaBeSgdTWTS-Q,183
113
119
  planar/scaffold_templates/app/__init__.py.j2,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
114
120
  planar/scaffold_templates/app/db/entities.py.j2,sha256=wg9O3JtRaRMKlDtoWHHodyNRL0s1UILvsr9fCQ_O2-4,279
115
- planar/scaffold_templates/app/flows/process_invoice.py.j2,sha256=nVJ5BlhOkHFEGkBuQNEF5G2P5HA1FGx25NSS5RXBUsw,1728
121
+ planar/scaffold_templates/app/flows/process_invoice.py.j2,sha256=R3EII_O2DHV1kvffW_AApZyaS6rR9eikcpxI08XH9dI,1691
116
122
  planar/security/auth_context.py,sha256=i63JkHQ3oXNlTis7GIKRkZJbkcvZhD2jVDuO7blgbSc,5068
117
123
  planar/security/auth_middleware.py,sha256=Grrm0i2bstWZ83ukrNZsHvFbNzffN0rvbbCcb2OxRY0,5746
118
124
  planar/security/authorization.py,sha256=zoej88_VINVNSDXm7u2LJbwOpMqmXBKj_pmCaPTar7M,11721
@@ -129,12 +135,12 @@ planar/sse/hub.py,sha256=5jhfk7zdCivau3TT1MxU2qtvETSskhqEiXzt-t0sRpE,6859
129
135
  planar/sse/model.py,sha256=fU_Fx9LS2ouS6-Dj1TIF-PLGul9YratKWafoWfZR1gc,123
130
136
  planar/sse/proxy.py,sha256=aJGo_-JIeQ0xSmE4HJdulZxIgCVRsBMMXqqSqtPvTvo,9177
131
137
  planar/testing/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
132
- planar/testing/fixtures.py,sha256=UEg12Ohj2Oip94CrC_wQ9rch71wctUZ1fYNryJLsPUY,9149
138
+ planar/testing/fixtures.py,sha256=spK7iL1NSv-d8fd139ep-SDogZR2ZycGkD_voSAPPF4,8662
133
139
  planar/testing/memory_storage.py,sha256=apcuFisC3hW9KiU3kO8zwHQ6oK9Lu20NSX5fJ0LSZUY,2824
134
140
  planar/testing/planar_test_client.py,sha256=qPkI_ZHZho_38PpdSmEjcRBO1iHcIx3dOwo7c02Am10,1979
135
141
  planar/testing/synchronizable_tracer.py,sha256=SWeta1CgwGsN5duC0FR8NyXOQ1b1L8nDpvGdjZVJ9Bg,4938
136
142
  planar/testing/test_memory_storage.py,sha256=So32XL0gbLDFMTl-WJN445x9jL6O8Qsqw8IRaiZnsPs,4797
137
- planar/testing/workflow_observer.py,sha256=mEHlPy1KGbUw-1tJPbju_O349LBx0zOzeUznvrBWkSo,2977
143
+ planar/testing/workflow_observer.py,sha256=0Q2xsYuZzNGXHZVwvXBqL9KXPsdIXuSZGBJAxHopzJw,2976
138
144
  planar/workflows/__init__.py,sha256=yFrrtKYUCx4jBPpHdEWDfKQgZXzGyr9voj5lFe9C-_w,826
139
145
  planar/workflows/context.py,sha256=93kPSmYniqjX_lv6--eUUPnzZEKZJi6IPaAjrT-hFRY,1271
140
146
  planar/workflows/contrib.py,sha256=b7WhCancxNCKO63mJCez9MahwMQc5_3zQxr_soJoXCY,6478
@@ -145,7 +151,7 @@ planar/workflows/execution.py,sha256=8c4a2L1qRMPQrCEJ8-sEk-gJi_xKq5gYKDSWSbSspVI
145
151
  planar/workflows/lock.py,sha256=QU5_y_n8RHOC7ppLicH7yWX-Ni7N93hlB14D2zXOQ8A,8773
146
152
  planar/workflows/misc.py,sha256=g3XVRMeU9mgDRi_6RgFdydLEqvTAg49wbIGlmC7kOu8,140
147
153
  planar/workflows/models.py,sha256=54z19XaMp-OP9qE_HT2yhK12u8NC4ZD7SgwY8sGjyw4,5567
148
- planar/workflows/notifications.py,sha256=FnGTEFu8_uQ1jIbSnJfhTs6wmPqW8U2-l-SclYrLHlI,2834
154
+ planar/workflows/notifications.py,sha256=JrObfWD-uRZJlZLMSDJDqjDuXfYAoRSLfgEeyoy98Vs,3795
149
155
  planar/workflows/orchestrator.py,sha256=rneB1yOPDZiJcHFbD6UDZ4juU77iSBK1eu1gOFm58vM,15480
150
156
  planar/workflows/query.py,sha256=38B5SLwXf3AlA_1ChR5DicFWdcUqzpQzMkuAUCNHafI,8838
151
157
  planar/workflows/serialization.py,sha256=v3eqUS0odUFS7PnIrKyKUrK-feIv0ssxEp2VxjkddyI,13733
@@ -154,13 +160,13 @@ planar/workflows/step_metadata.py,sha256=7hwcIm6ot8m-iUXSYCbPmkg6bWegF6_RJ1stInv
154
160
  planar/workflows/step_testing_utils.py,sha256=WiTwxB4mM2y6dW7CJ3PlIR1BkBodSxQV7-S25pQ3Ycs,2361
155
161
  planar/workflows/sub_workflow_runner.py,sha256=EpS7DhhXRbC6ABm-Sho6Uyxh2TqCjcTPDYvcTQN4FjY,8313
156
162
  planar/workflows/test_concurrency_detection.py,sha256=yfgvLOMkPaK7EiW4ihm1KQx82Y-s9pB6uJhBfDi7PwQ,4528
157
- planar/workflows/test_lock_timeout.py,sha256=WAQttTjmetTLiDHb9j0o_ydvF6j4TV1SaY_iNH8Y5vk,5746
163
+ planar/workflows/test_lock_timeout.py,sha256=H78N090wJtiEg6SaJosfRWijpX6HwnyWyNNb7WaGPe0,5746
158
164
  planar/workflows/test_serialization.py,sha256=JfaveBRQTNMkucqkTorIMGcvi8S0j6uRtboFaWpCmes,39586
159
165
  planar/workflows/test_suspend_deserialization.py,sha256=ddw2jToSJ-ebQ0RfT7KWTRMCOs1nis1lprQiGIGuaJ0,7751
160
166
  planar/workflows/test_workflow.py,sha256=KArm9m44IBXKY9j4v_O74MAweFN6jEb7tVRomziaeFU,64011
161
167
  planar/workflows/tracing.py,sha256=E7E_kj2VBQisDqrllviIshbvOmB9QcEeRwMapunqio4,2732
162
168
  planar/workflows/wrappers.py,sha256=KON6RGg1D6yStboNbuMEeTXRpPTEa8S6Elh1tOnMAlM,1149
163
- planar-0.8.0.dist-info/METADATA,sha256=D4RMLkoOUDNlZgbuEjMrnTjV4ga6FHJ3ZtxeC2uUe6A,12020
164
- planar-0.8.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
165
- planar-0.8.0.dist-info/entry_points.txt,sha256=ZtFgrZ0eeoVmhLA51ESipK0nHg2t_prjW0Cm8WhpP54,95
166
- planar-0.8.0.dist-info/RECORD,,
169
+ planar-0.9.1.dist-info/METADATA,sha256=dXMHhfpYKGO-5bwwHaSSJLH2LyKxODUOwj0zTtT6gnY,12303
170
+ planar-0.9.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
171
+ planar-0.9.1.dist-info/entry_points.txt,sha256=ZtFgrZ0eeoVmhLA51ESipK0nHg2t_prjW0Cm8WhpP54,95
172
+ planar-0.9.1.dist-info/RECORD,,
File without changes