planar 0.9.2__py3-none-any.whl → 0.10.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.
planar/utils.py CHANGED
@@ -108,3 +108,20 @@ def partition[T](
108
108
  false_items.append(item)
109
109
 
110
110
  return false_items, true_items
111
+
112
+
113
+ def one_or_raise[T](iterable: Iterable[T]) -> T:
114
+ """Extract the single element from an iterable or raise an exception."""
115
+ iterator = iter(iterable)
116
+ try:
117
+ value = next(iterator)
118
+ except StopIteration:
119
+ raise ValueError("Expected exactly one element, but iterable is empty")
120
+
121
+ try:
122
+ next(iterator)
123
+ raise ValueError(
124
+ "Expected exactly one element, but iterable contains multiple elements"
125
+ )
126
+ except StopIteration:
127
+ return value
@@ -2,12 +2,15 @@ from datetime import datetime, timedelta
2
2
  from functools import wraps
3
3
  from typing import Any, Callable, Coroutine, Dict
4
4
 
5
+ from pydantic.main import BaseModel
6
+
5
7
  from planar.logging import get_logger
6
8
  from planar.session import get_session
7
9
  from planar.utils import P, T, U, utc_now
8
10
  from planar.workflows import step
9
11
  from planar.workflows.context import get_context
10
12
  from planar.workflows.events import check_event_exists, get_latest_event
13
+ from planar.workflows.models import StepType
11
14
  from planar.workflows.step_core import Suspend, suspend_workflow
12
15
  from planar.workflows.tracing import trace
13
16
 
@@ -19,6 +22,11 @@ async def get_deadline(max_wait_time: float) -> datetime:
19
22
  return utc_now() + timedelta(seconds=max_wait_time)
20
23
 
21
24
 
25
+ @step(step_type=StepType.MESSAGE)
26
+ async def message(message: str | BaseModel):
27
+ pass
28
+
29
+
22
30
  @step(display_name="Wait for event")
23
31
  async def wait_for_event(
24
32
  event_key: str,
@@ -78,7 +78,7 @@ def step(
78
78
  return decorator
79
79
 
80
80
 
81
- def workflow(*, name: str | None = None):
81
+ def workflow(*, name: str | None = None, is_interactive: bool = False):
82
82
  """
83
83
  Decorator to define a workflow.
84
84
 
@@ -177,6 +177,7 @@ def workflow(*, name: str | None = None):
177
177
  start_step=start_workflow_step,
178
178
  wait_for_completion=wait_for_completion,
179
179
  wrapped_fn=run_workflow,
180
+ is_interactive=is_interactive,
180
181
  )
181
182
 
182
183
  return wf_wrapper
@@ -30,6 +30,7 @@ class StepType(str, Enum):
30
30
  RULE = "rule"
31
31
  HUMAN_IN_THE_LOOP = "human_in_the_loop"
32
32
  TOOL_CALL = "tool_call"
33
+ MESSAGE = "message"
33
34
 
34
35
 
35
36
  class WorkflowStatus(str, Enum):
@@ -14,7 +14,8 @@ from sqlmodel.ext.asyncio.session import AsyncSession
14
14
 
15
15
  from planar.session import get_session
16
16
  from planar.testing.workflow_observer import WorkflowObserver
17
- from planar.utils import utc_now
17
+ from planar.utils import one_or_raise, utc_now
18
+ from planar.workflows.contrib import message
18
19
  from planar.workflows.decorators import (
19
20
  __AS_STEP_CACHE,
20
21
  __is_workflow_step,
@@ -1965,3 +1966,40 @@ async def test_child_workflow_called_as_start_step(session: AsyncSession):
1965
1966
  assert child_wf.parent_id is None
1966
1967
  assert child_wf.status == WorkflowStatus.SUCCEEDED
1967
1968
  assert child_wf.result == "child_result"
1969
+
1970
+
1971
+ # =============================================================================
1972
+ # Test for message steps
1973
+ # =============================================================================
1974
+ class Example(BaseModel):
1975
+ id: int
1976
+ msg: str
1977
+
1978
+
1979
+ @pytest.mark.parametrize("input", ["hello", Example(id=1, msg="hello")])
1980
+ async def test_message(session: AsyncSession, input: str | BaseModel):
1981
+ @workflow()
1982
+ async def msg_workflow(msg: str | BaseModel):
1983
+ await message(msg)
1984
+
1985
+ async with WorkflowOrchestrator.ensure_started() as orchestrator:
1986
+ wf = await msg_workflow.start(input)
1987
+ await orchestrator.wait_for_completion(wf.id)
1988
+
1989
+ await session.refresh(wf)
1990
+ steps = (
1991
+ await session.exec(
1992
+ select(WorkflowStep).where(WorkflowStep.workflow_id == wf.id)
1993
+ )
1994
+ ).all()
1995
+
1996
+ step = one_or_raise(steps)
1997
+ # We recorded a single `WorkflowStep` of type `MESSAGE` to the DB.
1998
+ assert step.status is StepStatus.SUCCEEDED
1999
+ assert step.step_type is StepType.MESSAGE
2000
+ if isinstance(input, str):
2001
+ assert step.args == [input]
2002
+ else:
2003
+ assert step.args == [input.model_dump()]
2004
+ assert not step.kwargs
2005
+ assert step.result is None
@@ -33,6 +33,7 @@ class WorkflowWrapper(Wrapper[P, T, U, R]):
33
33
  start: Callable[P, Coroutine[T, U, Workflow]]
34
34
  start_step: Callable[P, Coroutine[T, U, UUID]]
35
35
  wait_for_completion: Callable[[UUID], Coroutine[T, U, R]]
36
+ is_interactive: bool
36
37
 
37
38
 
38
39
  @dataclass(kw_only=True)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: planar
3
- Version: 0.9.2
3
+ Version: 0.10.0
4
4
  Summary: Add your description here
5
5
  License-Expression: LicenseRef-Proprietary
6
6
  Requires-Dist: aiofiles>=24.1.0
@@ -55,21 +55,22 @@ The workflow system in Planar is a sophisticated orchestration framework that en
55
55
  1. Core Concept: Implements a durable workflow system that can survive process restarts by storing workflow state in a database. It allows workflows to
56
56
  be suspended and resumed.
57
57
  2. Key Features:
58
- - Persistent Steps: Each step in a workflow is tracked in the database
59
- - Automatic Retries: Failed steps can be retried automatically
60
- - Suspendable Workflows: Workflows can be suspended and resumed later
61
- - Concurrency Control: Uses a locking mechanism to prevent multiple executions
62
- - Recovery: Can recover from crashes by detecting stalled workflows
58
+ - Persistent Steps: Each step in a workflow is tracked in the database
59
+ - Automatic Retries: Failed steps can be retried automatically
60
+ - Suspendable Workflows: Workflows can be suspended and resumed later
61
+ - Concurrency Control: Uses a locking mechanism to prevent multiple executions
62
+ - Recovery: Can recover from crashes by detecting stalled workflows
63
63
  3. Main Components:
64
- - `@workflow` decorator: Marks a function as a workflow with persistence
65
- - `@step` decorator: Wraps function calls inside a workflow to make them resumable
66
- - Suspend class: Allows pausing workflow execution
67
- - workflow_orchestrator: Background task that finds and resumes suspended workflows
64
+ - `@workflow` decorator: Marks a function as a workflow with persistence
65
+ - `@step` decorator: Wraps function calls inside a workflow to make them resumable
66
+ - Suspend class: Allows pausing workflow execution
67
+ - workflow_orchestrator: Background task that finds and resumes suspended workflows
68
68
  4. REST API Integration:
69
- - Automatically creates API endpoints for starting workflows
70
- - Provides status endpoints to check workflow progress
71
- This is essentially a state machine for managing long-running business processes that need to be resilient to failures and can span multiple
72
- requests/processes.
69
+ - Automatically creates API endpoints for starting workflows
70
+ - Provides status endpoints to check workflow progress
71
+
72
+ This is essentially a state machine for managing long-running business processes that need to be resilient to failures and can span multiple
73
+ requests/processes.
73
74
 
74
75
  ### Coroutines and the suspension mechanism
75
76
  Coroutines are the heart of Planar's workflow system. Here's how they work:
@@ -278,7 +279,7 @@ We use pytest for testing Planar:
278
279
  To test with PostgreSQL locally, you'll need a PostgreSQL container running:
279
280
 
280
281
  ```bash
281
- docker run --restart=always --name planar-postgres -e POSTGRES_PASSWORD=123 -p 127.0.0.1:5432:5432 -d docker.io/library/postgres
282
+ docker run --restart=always --name planar-postgres -e POSTGRES_PASSWORD=postgres -p 127.0.0.1:5432:5432 -d docker.io/library/postgres
282
283
  ```
283
284
 
284
285
  Ensure the container name is `planar-postgres`.
@@ -320,5 +321,3 @@ To install cairo, run the following command:
320
321
  brew install cairo libffi pkg-config
321
322
  export DYLD_FALLBACK_LIBRARY_PATH="/opt/homebrew/lib:${DYLD_FALLBACK_LIBRARY_PATH}"
322
323
  ```
323
-
324
-
@@ -1,30 +1,35 @@
1
1
  planar/__init__.py,sha256=FAYRGjuJOH2Y_XYFA0-BrRFjuKdPzIShNbaYwJbtu6A,499
2
2
  planar/ai/__init__.py,sha256=ABOKvqQOLlVJkptcvXcuLjVZZWEsK8h-1RyFGK7kib8,231
3
- planar/ai/agent.py,sha256=flgHU00LRT-UcP0TjMqDigi2jwWq6UoMpmCZSOTyyB0,12428
4
- planar/ai/agent_base.py,sha256=rdK5ExCpkPf5sdVy-Wo5MKAx2O_GULFCwA24s0XO6Ek,5462
3
+ planar/ai/agent.py,sha256=HAyQvdA-NOEYMtze3Gh_BtOzk-rD1DXnv1jNGWd-9dA,12499
4
+ planar/ai/agent_base.py,sha256=5UURilfMldIYoTNzwlSY9eVaub5LDovCGFeAszyuGWE,6198
5
5
  planar/ai/agent_utils.py,sha256=MYNerdAm2TPVbDSKAmBCUlGmR56NAc8seZmDAFOWvUA,4199
6
6
  planar/ai/models.py,sha256=bZd4MoBBJMqzXJqsmsbMdZtOaRrNeX438CHAqOvmpfw,4598
7
7
  planar/ai/pydantic_ai.py,sha256=FpD0pE7wWNYwmEUZ90D7_J8gbAoqKmWtrLr2fhAd7rg,23503
8
+ planar/ai/state.py,sha256=6vQ8VMLxJYB75QXkm8AVPkdXHUMwwjKxBWH-hGIK9p0,278
8
9
  planar/ai/test_agent_serialization.py,sha256=zYLIxhYdFhOZzBrEBoQNyYLyNcNxWwaMTkjt_ARTkZk,8073
10
+ planar/ai/test_agent_tool_step_display.py,sha256=7OeKLnimItAkAFcArufDfiL3rXnQ1GwEtrE58_557hM,2588
9
11
  planar/ai/utils.py,sha256=WVBW0TGaoKytC4bNd_a9lXrBf5QsDRut4GBcA53U2Ww,3116
10
- planar/app.py,sha256=VEs4jDlcisyOy9I9zEGMG_-Qm8ULKT36CSHjqrYit3o,18491
11
- planar/cli.py,sha256=2ObR5XkLGbdbnDqp5mrBzDVhSacHCNsVNSHnXkrMQzQ,9593
12
+ planar/app.py,sha256=G5MtKJ4QPrUbiN9ykWCavVo2Kq4cMawZAxiS3uDyFaI,18673
13
+ planar/cli.py,sha256=SIyQOY3MbNDuohNcXFRIrHJuGxFNNC8C_ihfCXIUvbE,9900
12
14
  planar/config.py,sha256=6J42G9rEVUiOyCAY3EwUTU3PPmWthGTnrHMzST9TMcc,17809
13
15
  planar/data/__init__.py,sha256=LwrWl925w1CN0aW645Wpj_kDp0B8j5SsPzjr9iyrcmI,285
14
16
  planar/data/config.py,sha256=zp6ChI_2MUMbupEVQNY-BxzcdLvejXG33DCp0BujGVU,1209
15
- planar/data/dataset.py,sha256=P0NVE2OvJcXMKqVylYczY2lSGR0pSWlPAHM_upKoBWQ,9507
17
+ planar/data/connection.py,sha256=OGBVVapxDu1-vxAHjlEmSQiapBXBegetb4Nu0wg4n2Q,3846
18
+ planar/data/dataset.py,sha256=FKvuM2-xI101mEf1eeOYfNjSpHk8XjFXnAktTNR8Nig,5800
16
19
  planar/data/exceptions.py,sha256=AlhGQ_TReyEzfPSlqoXCjoZ1206Ut7dS4lrukVfGHaw,358
17
- planar/data/test_dataset.py,sha256=w2kay2PE-BhkryM3cOKX0nzSr2G0nCJxDuW1QCeFbyk,9985
20
+ planar/data/test_dataset.py,sha256=_tYvzw4y2-8rlRELdJxItcG_0OCFlOv7tBC7QI1j21o,10196
21
+ planar/data/utils.py,sha256=hhHKpYBvzLdzjNy_OElpAqIU-3XuHqUkFCiF5YWsShs,2556
18
22
  planar/db/__init__.py,sha256=SNgB6unQ1f1E9dB9O-KrsPsYM17KLsgOW1u0ajqs57I,318
19
- planar/db/alembic/env.py,sha256=UlOrLBfFJ-WbNK0R1cgS2MC3yrqeE4-6rIirB3rGLYo,5344
23
+ planar/db/alembic/env.py,sha256=4yX_aCqrXScVN3q7ISiMEDz40-5Dmociqh6d7VCUPwc,6051
20
24
  planar/db/alembic/script.py.mako,sha256=BgXfi4ClINnJU-PaaWqh1-Sjqu4brkWpbVd-0rEPzLU,665
21
25
  planar/db/alembic/versions/3476068c153c_initial_system_tables_migration.py,sha256=1FbzJyfapjegM-Mxd3HMMVA-8zVU6AnrnzEgIoc6eoQ,13204
22
- planar/db/alembic.ini,sha256=8G9IWbmF61Vwp1BXbkNOXTTgCEUMBQhOK_e-nnpnSYY,4309
26
+ planar/db/alembic/versions/8855a78a408f_message_step_type.py,sha256=iH13r8swy79lw8icGNKW1lqN09TX93MvR1zi-qvWNlU,869
27
+ planar/db/alembic.ini,sha256=FI1S0DlTn7IVp3-eT17PNxbVBbqhn84k2VzwRHpNz_Q,4304
23
28
  planar/db/db.py,sha256=VNpHH1R62tdWVLIV1I2ULmw3B8M6-RsM2ALG3VAVjSg,12790
24
29
  planar/dependencies.py,sha256=PH78fGk3bQfGnz-AphxH49307Y0XVgl3EY0LdGJnoik,1008
25
- planar/files/__init__.py,sha256=fms64l32M8hPK0SINXxNCykr2EpjBTcdgnezVgaCwkc,120
30
+ planar/files/__init__.py,sha256=uXqwnoIaJAuDYXFA-9gqcSq1R4mZLNyfem1zZyGI5Ek,206
26
31
  planar/files/models.py,sha256=zbZvMkoqoSnn7yOo26SRtEgtlHJbFIvwSht75APHQXk,6145
27
- planar/files/storage/azure_blob.py,sha256=PzCm8ZpyAMH9-N6VscTlLpud-CBLcQX9qC6YjbOSfZg,12316
32
+ planar/files/storage/azure_blob.py,sha256=QM-j9NHZmbwGv7H04yNpakJ54BJMseWEjehSekL3yr8,12316
28
33
  planar/files/storage/base.py,sha256=KO7jyKwjKg5fNSLvhxJWE-lsypv6LXXf7bgA34aflwY,2495
29
34
  planar/files/storage/config.py,sha256=jE9Dn6cG_a4x9pdaZkasOxjyWkK6hmplLrPjEsRXGLM,3473
30
35
  planar/files/storage/context.py,sha256=Qadlz4T-FQ1A0TdGsOfuNmM679ohayU7oaexUpT8AY0,361
@@ -64,24 +69,26 @@ planar/object_config/models.py,sha256=nCyK82JitZwzGwbaBa-dZVxHPnL51ZJ6h87a-KEwHA
64
69
  planar/object_config/object_config.py,sha256=MgaL-jBFJJtP6ipZ2eJs-KMhj94V_sT3QCSoVTpYP3Y,13609
65
70
  planar/object_registry.py,sha256=RMleX5XE8OKDxlnMeyLpJ1Y280duub-tx1smR1zTlDg,3219
66
71
  planar/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
67
- planar/registry_items.py,sha256=UhZRIpbSoa_CV9OTl17pJfRLxItYp4Pxd9f5ZbJkGaM,2055
72
+ planar/registry_items.py,sha256=slRQWmrK39wn5BQ3ohHmbiwvkEq1yr1nB8jSc7QG2CE,2132
68
73
  planar/routers/__init__.py,sha256=B_ZEbBuosX4ahPfvWZsyMIPmQm0rt6ail4nJA6NLfOk,379
69
74
  planar/routers/agents_router.py,sha256=trb1JPYVlaV7O2uoYvKIrLuTNGP_PmQSLZmXYFWrHkg,8251
75
+ planar/routers/dataset_router.py,sha256=wTFI-NCNsFLWZEmcq0g1Sj9wxrhrh6vGglpriuHoHrk,7424
70
76
  planar/routers/entity_router.py,sha256=7Y1LDSqI_ovoOGr9DGylGM8BmRxF-WSPQSwITJHc6NE,4841
71
77
  planar/routers/event.py,sha256=yvzzMQaKRoS2A0KSjQTyWcfmBzpt8xPNDfVW50XUSCw,2961
72
78
  planar/routers/files.py,sha256=udu6PeZ9AuOpNyJete21rWAVQyE0qnC7tnSyJ97AH4Y,5644
73
79
  planar/routers/human.py,sha256=m_CbH97_QGmzriui_xopLOq-2D1kR0WgvO92fMaFeBQ,5010
74
80
  planar/routers/info.py,sha256=HQa-mumw4zitG61V9isJlZ3cMr8pEwlB54Ct_LrpJDo,4473
75
- planar/routers/models.py,sha256=RwXjXpJw2uyluM4Fjc34UA0Jm7J95cUjbmTTarD_P9k,4669
81
+ planar/routers/models.py,sha256=zknkVs9-B4UJlMe9fl2EpXx7sdzfjQfwAbNoL1a0wmI,4694
76
82
  planar/routers/object_config_router.py,sha256=zA8-gGBQp1-Gm3uCC4WJ6nLicFwt4CsCqCYLFp1lRN8,4802
77
83
  planar/routers/rule.py,sha256=d6giUwYRKzxQFPeoWbe8Ylp2Cxd71_uK8yoS9NrOOBg,3563
78
84
  planar/routers/test_agents_router.py,sha256=jzRCLB21YcEfhaFUos_gfRp9WDdP38_cozTQkHbi9b4,6099
85
+ planar/routers/test_dataset_router.py,sha256=8Dm6ZFlIXQgwWLG3y00mz5cMsZvmIw7yM2-w-Qe_sCQ,13058
79
86
  planar/routers/test_files_router.py,sha256=HfZF1zeJ9BD2jhE6s698Jo7sDpO55RJF5g1Ksup4jtM,1576
80
87
  planar/routers/test_object_config_router.py,sha256=JpzoNlNONgljmGJYtrXnhtGhKjUT3YQMhP89fnt7dn4,11406
81
88
  planar/routers/test_routes_security.py,sha256=lXHeYg_th4UaDWeANM-dzONF8p2bEtwXJYYUlftE9R8,5556
82
89
  planar/routers/test_rule_router.py,sha256=08fa4sc7RaXvQzPCQQ4LaftfXuQwoPEDzcS4lesPG2Q,17220
83
- planar/routers/test_workflow_router.py,sha256=w3Gl1Okr2FgKMIqcum3gD6XzVrYm82oSIj_znbtd-aQ,16592
84
- planar/routers/workflow.py,sha256=8R35ENZeB5Mdt7WfH2zZ75BPg2oQ9d8kL47P1qvP-7Q,18045
90
+ planar/routers/test_workflow_router.py,sha256=h2XTJrlO3vAshd45abtMaE0kigWTNxXjfJiuGcjcA7s,17463
91
+ planar/routers/workflow.py,sha256=I9wJLqcFf52eEREhwqMsYICBEVD7I07g7ILWzxR5x9Y,18151
85
92
  planar/rules/__init__.py,sha256=lF3F8Rdf2ottjiJu0IeBdqhg1bckLhOqZFI2t-8KItM,474
86
93
  planar/rules/decorator.py,sha256=nxT17n9uwfXMOlk5lliw_cRS7Y83gMI6CQdrf_pB5yk,6666
87
94
  planar/rules/models.py,sha256=vC38JLeGzmU87L8BX4AyVJLJHmRYjWRmoHQ6S6ZlhPg,10186
@@ -105,14 +112,14 @@ planar/rules/test_rules.py,sha256=6M7CSg1bwn7O7DOoNi38vyVG4UmPQfRFxEO9qGE6rz0,52
105
112
  planar/scaffold_templates/app/__init__.py.j2,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
106
113
  planar/scaffold_templates/app/db/entities.py.j2,sha256=wg9O3JtRaRMKlDtoWHHodyNRL0s1UILvsr9fCQ_O2-4,279
107
114
  planar/scaffold_templates/app/flows/process_invoice.py.j2,sha256=R3EII_O2DHV1kvffW_AApZyaS6rR9eikcpxI08XH9dI,1691
108
- planar/scaffold_templates/main.py.j2,sha256=HcV0PVzcyRDaJvNdDQIFiDR1MJlLquNQzNO9oNkCKDQ,322
115
+ planar/scaffold_templates/main.py.j2,sha256=zrqsuv3Fp4lcknvB37RrRHy11msdFB1yDguYmTLLPhw,398
109
116
  planar/scaffold_templates/planar.dev.yaml.j2,sha256=I5-IqX7GJm6qA91WtUMw43L4hKACqgnER_H2racim4c,998
110
117
  planar/scaffold_templates/planar.prod.yaml.j2,sha256=FahJ2atDtvVH7IUCatGq6h9hmyF8meeiWC8RLfWphOQ,867
111
118
  planar/scaffold_templates/pyproject.toml.j2,sha256=nFfHWLp0sFK8cqjkdwBm6Hi6xsPzTNkaBeSgdTWTS-Q,183
112
119
  planar/security/auth_context.py,sha256=i63JkHQ3oXNlTis7GIKRkZJbkcvZhD2jVDuO7blgbSc,5068
113
120
  planar/security/auth_middleware.py,sha256=Grrm0i2bstWZ83ukrNZsHvFbNzffN0rvbbCcb2OxRY0,5746
114
- planar/security/authorization.py,sha256=zoej88_VINVNSDXm7u2LJbwOpMqmXBKj_pmCaPTar7M,11721
115
- planar/security/default_policies.cedar,sha256=ACZqs-74iTQHypuKwfyyvIhXaRRn0MuRc98zTFGnFYU,1070
121
+ planar/security/authorization.py,sha256=zTh5rLmVJZnGDq540_1WYljJ7Hws-BY_P6VqUCONqLE,12760
122
+ planar/security/default_policies.cedar,sha256=j7stjEfmgzthsDCjw1NwlE3_SxXQmLOGNRONM_2htoE,1492
116
123
  planar/security/security_context.py,sha256=vzfwiDJRzq8snaENrJddG5Ei-UUq_a5hkInMEOZf0mM,496
117
124
  planar/security/tests/test_auth_middleware.py,sha256=GjAyJYAR6jF_zGG85ZKY-E_e_aoqjK8qiHSalv2T2rk,6206
118
125
  planar/security/tests/test_authorization_context.py,sha256=cnsC3V13NBJwzyIwZaM9wu_vergcnmVhwB3khVH7G-o,2364
@@ -134,23 +141,23 @@ planar/test_object_registry.py,sha256=R7IwbB2GACm2HUuVZTeVY4V12XB9_JgSSeppPxiCdf
134
141
  planar/test_sqlalchemy.py,sha256=QTloaipWiFmlLTBGH6YCRkwi1R27gmQZnwprO7lPLfU,7058
135
142
  planar/test_utils.py,sha256=gKenXotj36SN_bb3bQpYPfD8t06IjnGBQqEgWpujHcA,3086
136
143
  planar/testing/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
137
- planar/testing/fixtures.py,sha256=spK7iL1NSv-d8fd139ep-SDogZR2ZycGkD_voSAPPF4,8662
144
+ planar/testing/fixtures.py,sha256=2Pa5pdqrpcLNAxEsaZiDiLaivD4KWAL8pin22H-XuuM,9694
138
145
  planar/testing/memory_storage.py,sha256=apcuFisC3hW9KiU3kO8zwHQ6oK9Lu20NSX5fJ0LSZUY,2824
139
- planar/testing/planar_test_client.py,sha256=qPkI_ZHZho_38PpdSmEjcRBO1iHcIx3dOwo7c02Am10,1979
146
+ planar/testing/planar_test_client.py,sha256=2atx5zER5bGrCVoa-lcag8xP2ZcbnOLKoGRKpfOJCg8,1992
140
147
  planar/testing/synchronizable_tracer.py,sha256=SWeta1CgwGsN5duC0FR8NyXOQ1b1L8nDpvGdjZVJ9Bg,4938
141
148
  planar/testing/test_memory_storage.py,sha256=So32XL0gbLDFMTl-WJN445x9jL6O8Qsqw8IRaiZnsPs,4797
142
149
  planar/testing/workflow_observer.py,sha256=0Q2xsYuZzNGXHZVwvXBqL9KXPsdIXuSZGBJAxHopzJw,2976
143
- planar/utils.py,sha256=v7q9AJyWgQWl9VPSN_0qxw3rBvYe-_Pb_KcwqSsjOFU,3103
150
+ planar/utils.py,sha256=YP37-ODS8nYOIfHPo11CwCpQRsg8oc57lQ0wkXwqCyo,3607
144
151
  planar/workflows/__init__.py,sha256=yFrrtKYUCx4jBPpHdEWDfKQgZXzGyr9voj5lFe9C-_w,826
145
152
  planar/workflows/context.py,sha256=93kPSmYniqjX_lv6--eUUPnzZEKZJi6IPaAjrT-hFRY,1271
146
- planar/workflows/contrib.py,sha256=b7WhCancxNCKO63mJCez9MahwMQc5_3zQxr_soJoXCY,6478
147
- planar/workflows/decorators.py,sha256=Lsq9ZZdY60rv8-9Ok029x_kE4bHBvRqbfWZ8O0QRNfw,7960
153
+ planar/workflows/contrib.py,sha256=tUqMZ42Jh8KMy1JP1VFJOD4rsiYxzMTd5pJfe2t3yzk,6650
154
+ planar/workflows/decorators.py,sha256=VqYdI2-9vL26Z9TWjtEj7gp3Engk7xt7noC4afFqreo,8033
148
155
  planar/workflows/events.py,sha256=xYGGTwbKFnqhFFI7SuoFIaEeS5oWOLS-1nP9MW0uOhs,6007
149
156
  planar/workflows/exceptions.py,sha256=G2Q4ZhaJwybMLpnpzXJNvKtFqUsEw7Vh0cRMkVxP7PU,927
150
157
  planar/workflows/execution.py,sha256=8c4a2L1qRMPQrCEJ8-sEk-gJi_xKq5gYKDSWSbSspVI,7479
151
158
  planar/workflows/lock.py,sha256=QU5_y_n8RHOC7ppLicH7yWX-Ni7N93hlB14D2zXOQ8A,8773
152
159
  planar/workflows/misc.py,sha256=g3XVRMeU9mgDRi_6RgFdydLEqvTAg49wbIGlmC7kOu8,140
153
- planar/workflows/models.py,sha256=54z19XaMp-OP9qE_HT2yhK12u8NC4ZD7SgwY8sGjyw4,5567
160
+ planar/workflows/models.py,sha256=SKBJTGhd4nVWxtlDkaQrU2RvRTtoj07PJhLT73cF_ac,5591
154
161
  planar/workflows/notifications.py,sha256=JrObfWD-uRZJlZLMSDJDqjDuXfYAoRSLfgEeyoy98Vs,3795
155
162
  planar/workflows/orchestrator.py,sha256=rneB1yOPDZiJcHFbD6UDZ4juU77iSBK1eu1gOFm58vM,15480
156
163
  planar/workflows/query.py,sha256=38B5SLwXf3AlA_1ChR5DicFWdcUqzpQzMkuAUCNHafI,8838
@@ -163,10 +170,10 @@ planar/workflows/test_concurrency_detection.py,sha256=yfgvLOMkPaK7EiW4ihm1KQx82Y
163
170
  planar/workflows/test_lock_timeout.py,sha256=H78N090wJtiEg6SaJosfRWijpX6HwnyWyNNb7WaGPe0,5746
164
171
  planar/workflows/test_serialization.py,sha256=JfaveBRQTNMkucqkTorIMGcvi8S0j6uRtboFaWpCmes,39586
165
172
  planar/workflows/test_suspend_deserialization.py,sha256=ddw2jToSJ-ebQ0RfT7KWTRMCOs1nis1lprQiGIGuaJ0,7751
166
- planar/workflows/test_workflow.py,sha256=KArm9m44IBXKY9j4v_O74MAweFN6jEb7tVRomziaeFU,64011
173
+ planar/workflows/test_workflow.py,sha256=hBLPQYqUsWEQ_SopKgi69ckRC5OpmQEBlsPcftGMu_Q,65266
167
174
  planar/workflows/tracing.py,sha256=E7E_kj2VBQisDqrllviIshbvOmB9QcEeRwMapunqio4,2732
168
- planar/workflows/wrappers.py,sha256=KON6RGg1D6yStboNbuMEeTXRpPTEa8S6Elh1tOnMAlM,1149
169
- planar-0.9.2.dist-info/WHEEL,sha256=Jb20R3Ili4n9P1fcwuLup21eQ5r9WXhs4_qy7VTrgPI,79
170
- planar-0.9.2.dist-info/entry_points.txt,sha256=L3T0w9u2UPKWXv6JbXFWKU1d5xyEAq1xVWbpYS6mLNg,96
171
- planar-0.9.2.dist-info/METADATA,sha256=nF_zOc5hfhs8BYdm83nO8Fp480qDGfCuTbJpx8Yf5FE,12313
172
- planar-0.9.2.dist-info/RECORD,,
175
+ planar/workflows/wrappers.py,sha256=dY_3NqkzGMG4jgX2lkAqvHTYFA1lBzhkQCw7N5CyaQM,1174
176
+ planar-0.10.0.dist-info/WHEEL,sha256=-neZj6nU9KAMg2CnCY6T3w8J53nx1kFGw_9HfoSzM60,79
177
+ planar-0.10.0.dist-info/entry_points.txt,sha256=L3T0w9u2UPKWXv6JbXFWKU1d5xyEAq1xVWbpYS6mLNg,96
178
+ planar-0.10.0.dist-info/METADATA,sha256=yXTyA50EXqt_mZqhbAzm8Z2YRnrSmVzuCJLjvzf1qik,12348
179
+ planar-0.10.0.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: uv 0.8.15
2
+ Generator: uv 0.8.22
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any