planar 0.11.0__py3-none-any.whl → 0.12.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.
@@ -2,7 +2,7 @@ from __future__ import annotations
2
2
 
3
3
  from typing import TYPE_CHECKING, Annotated, Literal
4
4
 
5
- from pydantic import BaseModel, Field, model_validator
5
+ from pydantic import BaseModel, ConfigDict, Field, model_validator
6
6
 
7
7
  from .local_directory import LocalDirectoryStorage
8
8
  from .s3 import S3Storage
@@ -15,6 +15,8 @@ class LocalDirectoryConfig(BaseModel):
15
15
  backend: Literal["localdir"]
16
16
  directory: str
17
17
 
18
+ model_config = ConfigDict(frozen=True)
19
+
18
20
 
19
21
  class S3Config(BaseModel):
20
22
  backend: Literal["s3"]
@@ -25,6 +27,8 @@ class S3Config(BaseModel):
25
27
  endpoint_url: str | None = None
26
28
  presigned_url_ttl: int = 3600
27
29
 
30
+ model_config = ConfigDict(frozen=True)
31
+
28
32
 
29
33
  class AzureBlobConfig(BaseModel):
30
34
  backend: Literal["azure_blob"]
@@ -39,6 +43,8 @@ class AzureBlobConfig(BaseModel):
39
43
  # Common settings
40
44
  sas_ttl: int = 3600 # SAS URL expiry time in seconds
41
45
 
46
+ model_config = ConfigDict(frozen=True)
47
+
42
48
  @model_validator(mode="after")
43
49
  def validate_auth_config(self):
44
50
  """Ensure exactly one valid authentication configuration."""
@@ -12,6 +12,7 @@ from planar.data.exceptions import DatasetNotFoundError
12
12
  from planar.data.utils import (
13
13
  get_dataset,
14
14
  get_dataset_metadata,
15
+ get_datasets_metadata,
15
16
  list_datasets,
16
17
  list_schemas,
17
18
  )
@@ -51,9 +52,12 @@ def create_dataset_router() -> APIRouter:
51
52
  validate_authorization_for(DatasetResource(), DatasetAction.DATASET_LIST)
52
53
  datasets = await list_datasets(limit, offset)
53
54
 
55
+ dataset_names = [dataset.name for dataset in datasets]
56
+ metadata_by_dataset = await get_datasets_metadata(dataset_names, schema_name)
57
+
54
58
  response = []
55
59
  for dataset in datasets:
56
- metadata = await get_dataset_metadata(dataset.name, schema_name)
60
+ metadata = metadata_by_dataset.get(dataset.name)
57
61
 
58
62
  if not metadata:
59
63
  continue
planar/routers/info.py CHANGED
@@ -1,4 +1,3 @@
1
- import importlib.metadata
2
1
  from typing import Literal, TypedDict
3
2
 
4
3
  from fastapi import APIRouter, Depends
@@ -13,6 +12,7 @@ from planar.human.models import HumanTask, HumanTaskStatus
13
12
  from planar.logging import get_logger
14
13
  from planar.object_registry import ObjectRegistry
15
14
  from planar.session import get_session
15
+ from planar.version import FALLBACK_VERSION, get_version
16
16
  from planar.workflows.models import Workflow, WorkflowStatus
17
17
 
18
18
  logger = get_logger(__name__)
@@ -113,14 +113,6 @@ async def get_system_stats(
113
113
  }
114
114
 
115
115
 
116
- def get_app_version() -> str:
117
- try:
118
- return importlib.metadata.version("planar")
119
- except importlib.metadata.PackageNotFoundError:
120
- logger.warning("Planar package not found, returning development version")
121
- return "development"
122
-
123
-
124
116
  def get_storage_info(cfg: StorageConfig) -> StorageInfo:
125
117
  return cfg.backend
126
118
 
@@ -159,10 +151,18 @@ def create_info_router(
159
151
  SystemInfo object containing app details and system stats
160
152
  """
161
153
  stats = await get_system_stats(registry, session)
154
+ version = get_version()
155
+ if version == FALLBACK_VERSION:
156
+ logger.warning(
157
+ "planar package version not found",
158
+ package_name="planar",
159
+ fallback_version=FALLBACK_VERSION,
160
+ )
161
+
162
162
  return SystemInfo(
163
163
  title=title,
164
164
  description=description,
165
- version=get_app_version(),
165
+ version=version,
166
166
  environment=get_environment(),
167
167
  features=SystemFeatures(
168
168
  storage=get_storage_info(config.storage) if config.storage else None,
@@ -41,6 +41,14 @@ async def planar_test_client(
41
41
  session_var.reset(token)
42
42
  await wait_all_event_loop_tasks()
43
43
 
44
+ if getattr(app.config, "data", None):
45
+ try:
46
+ from planar.data.connection import reset_connection_cache
47
+ except ImportError:
48
+ pass
49
+ else:
50
+ await reset_connection_cache()
51
+
44
52
 
45
53
  async def wait_all_event_loop_tasks():
46
54
  # Workaround prevent the event loop from exiting before aiosqlite
planar/version.py ADDED
@@ -0,0 +1,27 @@
1
+ """Utilities for working with Planar package version information."""
2
+
3
+ from functools import lru_cache
4
+ from importlib import metadata
5
+ from typing import Final
6
+
7
+ PACKAGE_NAME: Final[str] = "planar"
8
+ FALLBACK_VERSION: Final[str] = "0.0.0.dev0"
9
+
10
+
11
+ @lru_cache(maxsize=1)
12
+ def get_version(
13
+ fallback: str = FALLBACK_VERSION,
14
+ ) -> str:
15
+ """Return the installed Planar version or a fallback value.
16
+
17
+ Args:
18
+ fallback: Value returned if the package metadata is unavailable.
19
+
20
+ Returns:
21
+ The package version string if available, otherwise the fallback value.
22
+ """
23
+
24
+ try:
25
+ return metadata.version(PACKAGE_NAME)
26
+ except metadata.PackageNotFoundError:
27
+ return fallback
@@ -0,0 +1,202 @@
1
+ Metadata-Version: 2.4
2
+ Name: planar
3
+ Version: 0.12.0
4
+ Summary: Batteries-included framework for building durable agentic workflows and business applications.
5
+ License-Expression: LicenseRef-Proprietary
6
+ Requires-Dist: aiofiles>=24.1.0
7
+ Requires-Dist: aiosqlite>=0.21.0
8
+ Requires-Dist: alembic>=1.14.1
9
+ Requires-Dist: anthropic>=0.49.0
10
+ Requires-Dist: asyncpg
11
+ Requires-Dist: boto3>=1.39.15
12
+ Requires-Dist: cedarpy>=4.1.0
13
+ Requires-Dist: fastapi[standard]>=0.115.7
14
+ Requires-Dist: inflection>=0.5.1
15
+ Requires-Dist: openai>=1.75
16
+ Requires-Dist: pydantic-ai-slim[anthropic,bedrock,google,openai]>=0.7.5
17
+ Requires-Dist: pygments>=2.19.1
18
+ Requires-Dist: pyjwt[crypto]
19
+ Requires-Dist: python-multipart>=0.0.20
20
+ Requires-Dist: sqlalchemy[asyncio]>=2.0.37
21
+ Requires-Dist: sqlmodel>=0.0.22
22
+ Requires-Dist: typer>=0.15.2
23
+ Requires-Dist: typing-extensions>=4.12.2
24
+ Requires-Dist: zen-engine>=0.40.0
25
+ Requires-Dist: azure-storage-blob>=12.19.0 ; extra == 'azure'
26
+ Requires-Dist: azure-identity>=1.15.0 ; extra == 'azure'
27
+ Requires-Dist: aiohttp>=3.8.0 ; extra == 'azure'
28
+ Requires-Dist: ducklake>=0.1.1 ; extra == 'data'
29
+ Requires-Dist: ibis-framework[duckdb]>=10.8.0 ; extra == 'data'
30
+ Requires-Dist: polars>=1.31.0 ; extra == 'data'
31
+ Requires-Dist: opentelemetry-api>=1.34.1 ; extra == 'otel'
32
+ Requires-Dist: opentelemetry-exporter-otlp>=1.34.1 ; extra == 'otel'
33
+ Requires-Dist: opentelemetry-instrumentation-logging>=0.55b1 ; extra == 'otel'
34
+ Requires-Dist: opentelemetry-sdk>=1.34.1 ; extra == 'otel'
35
+ Requires-Python: >=3.12
36
+ Provides-Extra: azure
37
+ Provides-Extra: data
38
+ Provides-Extra: otel
39
+ Description-Content-Type: text/markdown
40
+
41
+ # Planar
42
+
43
+ Planar is a batteries-included Python framework for building durable workflows, agent automations, and stateful APIs. Built on FastAPI and SQLModel, it combines orchestration, data modeling, and file management into a cohesive developer experience.
44
+
45
+ ## Feature Highlights
46
+
47
+ - Durable workflow engine with resumable async steps, automatic retries, and suspension points
48
+ - Agent step framework with first-class support for OpenAI, Anthropic, and other providers
49
+ - Human task assignments and rule engine tooling baked into workflow execution
50
+ - SQLModel-powered data layer with Alembic migrations and CRUD scaffolding out of the box
51
+ - Built-in file management and storage adapters for local disk, Amazon S3, and Azure Blob Storage
52
+ - CLI-driven developer workflow with templated scaffolding, hot reload, and environment-aware configuration
53
+
54
+ ## Installation
55
+
56
+ Planar is published on PyPI. Add it to an existing project with `uv`:
57
+
58
+ ```bash
59
+ uv add planar
60
+ ```
61
+
62
+ To explore the CLI without updating `pyproject.toml`, use the ephemeral uvx runner:
63
+
64
+ ```bash
65
+ uvx planar --help
66
+ ```
67
+
68
+ ## Quickstart
69
+
70
+ Generate a new service, start up the dev server, and inspect the auto-generated APIs:
71
+
72
+ ```bash
73
+ uvx planar scaffold --name my_service
74
+ cd my_service
75
+ uv run planar dev src/main.py
76
+ ```
77
+
78
+ Open `http://127.0.0.1:8000/docs` to explore your service's routes and workflow endpoints. The scaffold prints the exact app path if it differs from `src/main.py`.
79
+
80
+ ## Define a Durable Workflow
81
+
82
+ ```python
83
+ from datetime import timedelta
84
+
85
+ from planar import PlanarApp
86
+ from planar.workflows import step, suspend, workflow
87
+
88
+ @step
89
+ async def charge_customer(order_id: str) -> None:
90
+ ...
91
+
92
+ @step
93
+ async def notify_success(order_id: str) -> None:
94
+ ...
95
+
96
+ @workflow
97
+ async def process_order(order_id: str) -> None:
98
+ await charge_customer(order_id)
99
+ await suspend(interval=timedelta(hours=1))
100
+ await notify_success(order_id)
101
+
102
+
103
+ app = PlanarApp()
104
+ app.register_workflow(process_order)
105
+ ```
106
+
107
+ Workflows are async functions composed of resumable steps. Planar persists every step, applies configurable retry policies, and resumes suspended workflows even after process restarts. Check `docs/workflows.md` for deeper concepts including event-driven waits, human steps, and agent integrations.
108
+
109
+ ## Core Capabilities
110
+
111
+ - **Workflow orchestration**: Compose async steps with guaranteed persistence, scheduling, and concurrency control.
112
+ - **Agent steps**: Run LLM-powered actions durably with provider-agnostic adapters and structured prompts.
113
+ - **Human tasks and rules**: Build human-in-the-loop approvals and declarative rule evaluations alongside automated logic.
114
+ - **Stateful data and files**: Model entities with SQLModel, manage migrations through Alembic, and store files using pluggable backends.
115
+ - **Observability**: Structured logging and OpenTelemetry hooks surface workflow progress and performance metrics.
116
+
117
+ ## Command Line Interface
118
+
119
+ ```bash
120
+ uvx planar scaffold --help # generate a new project from the official template
121
+ uv run planar dev [PATH] # run with hot reload and development defaults
122
+ uv run planar prod [PATH] # run with production defaults
123
+ ```
124
+
125
+ `[PATH]` points to the module that exports a `PlanarApp` instance (defaults to `app.py` or `main.py`). Use `--config PATH` to load a specific configuration file and `--app NAME` if your application variable is not named `app`.
126
+
127
+ ## Configuration
128
+
129
+ Planar merges environment defaults with an optional YAML override. By convention it looks for `planar.dev.yaml`, `planar.prod.yaml`, or `planar.yaml` in your project directory, but you can supply a path explicitly via `--config` or the `PLANAR_CONFIG` environment variable.
130
+
131
+ Example minimal override:
132
+
133
+ ```yaml
134
+ ai_providers:
135
+ openai:
136
+ api_key: ${OPENAI_API_KEY}
137
+
138
+ storage:
139
+ directory: .files
140
+ ```
141
+
142
+ For more configuration patterns and workflow design guidance, browse the documents in `docs/`.
143
+
144
+ ## Examples
145
+
146
+ - `examples/expense_approval_workflow` — human approvals with AI agent collaboration
147
+ - `examples/event_based_workflow` — event-driven orchestration and external wakeups
148
+ - `examples/simple_service` — CRUD service paired with workflows
149
+
150
+ Run any example with `uv run planar dev path/to/main.py`.
151
+
152
+ ## Local Development
153
+
154
+ Planar is built with `uv`. Clone the repository and install dev dependencies:
155
+
156
+ ```bash
157
+ uv sync --extra otel
158
+ ```
159
+
160
+ Useful commands:
161
+
162
+ - `uv run ruff check --fix` and `uv run ruff format` to lint and format
163
+ - `uv run pyright` for static type checking
164
+ - `uv run pytest` to run the test suite (use `-n auto` for parallel execution)
165
+ - `uv run pytest --cov=planar` to collect coverage
166
+ - `uv tool install pre-commit && uv tool run pre-commit install` to enable git hooks
167
+
168
+ ### PostgreSQL Test Suite
169
+
170
+ ```bash
171
+ docker run --restart=always --name planar-postgres \
172
+ -e POSTGRES_PASSWORD=postgres \
173
+ -p 127.0.0.1:5432:5432 \
174
+ -d docker.io/library/postgres
175
+
176
+ PLANAR_TEST_POSTGRESQL=1 PLANAR_TEST_POSTGRESQL_CONTAINER=planar-postgres \
177
+ uv run pytest -s
178
+ ```
179
+
180
+ Disable SQLite with `PLANAR_TEST_SQLITE=0`.
181
+
182
+ ### Cairo SVG Dependencies
183
+
184
+ Some AI integration tests convert SVG assets using `cairosvg`. Install Cairo libraries locally before running those tests:
185
+
186
+ ```bash
187
+ brew install cairo libffi pkg-config
188
+ export DYLD_FALLBACK_LIBRARY_PATH="/opt/homebrew/lib:${DYLD_FALLBACK_LIBRARY_PATH}"
189
+ ```
190
+
191
+ Most Linux distributions ship the required libraries via their package manager.
192
+
193
+ ## Documentation
194
+
195
+ Dive deeper into Planar's design and APIs in the `docs/` directory:
196
+
197
+ - `docs/workflows.md`
198
+ - `docs/design/event_based_waiting.md`
199
+ - `docs/design/human_step.md`
200
+ - `docs/design/agent_step.md`
201
+
202
+ For agentic coding tools, use `docs/llm_prompt.md` as a drop-in reference document in whatever tool you are using.
@@ -7,28 +7,28 @@ planar/ai/models.py,sha256=bZd4MoBBJMqzXJqsmsbMdZtOaRrNeX438CHAqOvmpfw,4598
7
7
  planar/ai/pydantic_ai.py,sha256=FpD0pE7wWNYwmEUZ90D7_J8gbAoqKmWtrLr2fhAd7rg,23503
8
8
  planar/ai/state.py,sha256=6vQ8VMLxJYB75QXkm8AVPkdXHUMwwjKxBWH-hGIK9p0,278
9
9
  planar/ai/utils.py,sha256=WVBW0TGaoKytC4bNd_a9lXrBf5QsDRut4GBcA53U2Ww,3116
10
- planar/app.py,sha256=SKP7xinjQZfVKssKdfq0eK7VaJru99ReGJpn5KeTD3w,19108
11
- planar/cli.py,sha256=SIyQOY3MbNDuohNcXFRIrHJuGxFNNC8C_ihfCXIUvbE,9900
10
+ planar/app.py,sha256=2ijbrORCfjKReDieLbwgey_9poJJwEfWkvCNKcVYcdk,19484
11
+ planar/cli.py,sha256=9LINDDiAUBDmzWQY9BuCYTssM7eb-ypa5bL9HAY3Ld8,10500
12
12
  planar/config.py,sha256=6J42G9rEVUiOyCAY3EwUTU3PPmWthGTnrHMzST9TMcc,17809
13
- planar/data/__init__.py,sha256=LwrWl925w1CN0aW645Wpj_kDp0B8j5SsPzjr9iyrcmI,285
14
- planar/data/config.py,sha256=zp6ChI_2MUMbupEVQNY-BxzcdLvejXG33DCp0BujGVU,1209
15
- planar/data/connection.py,sha256=OGBVVapxDu1-vxAHjlEmSQiapBXBegetb4Nu0wg4n2Q,3846
16
- planar/data/dataset.py,sha256=FKvuM2-xI101mEf1eeOYfNjSpHk8XjFXnAktTNR8Nig,5800
13
+ planar/data/__init__.py,sha256=eqSREzJ58HM05DXpR_00M6RDFxtHSIh-OEuqXBPVsVc,362
14
+ planar/data/config.py,sha256=oaLiwN3OUt3i85MS0zxpdMNG5VjaM5xB6VtPc1f4MFU,1484
15
+ planar/data/connection.py,sha256=OQL-EEBtfEOtN5PYZA5TswCTD8Cebt9-pP_w5Qifs24,6705
16
+ planar/data/dataset.py,sha256=f-x9cOuGyQQldC98mCwpFVOXMiDNN6LQDQ9vtljXVRo,6095
17
17
  planar/data/exceptions.py,sha256=AlhGQ_TReyEzfPSlqoXCjoZ1206Ut7dS4lrukVfGHaw,358
18
- planar/data/utils.py,sha256=hhHKpYBvzLdzjNy_OElpAqIU-3XuHqUkFCiF5YWsShs,2556
18
+ planar/data/utils.py,sha256=NhxJFSxPLNX1ddSANS3-bVhMr1Q_-25qDRRXxGug4Vc,6312
19
19
  planar/db/__init__.py,sha256=SNgB6unQ1f1E9dB9O-KrsPsYM17KLsgOW1u0ajqs57I,318
20
- planar/db/alembic/env.py,sha256=4yX_aCqrXScVN3q7ISiMEDz40-5Dmociqh6d7VCUPwc,6051
20
+ planar/db/alembic/env.py,sha256=gOKwdugTO1tyUl8BAlpYJ7AweOXqgX1Arg88lle1944,6180
21
21
  planar/db/alembic/script.py.mako,sha256=BgXfi4ClINnJU-PaaWqh1-Sjqu4brkWpbVd-0rEPzLU,665
22
22
  planar/db/alembic/versions/3476068c153c_initial_system_tables_migration.py,sha256=1FbzJyfapjegM-Mxd3HMMVA-8zVU6AnrnzEgIoc6eoQ,13204
23
23
  planar/db/alembic/versions/8855a78a408f_message_step_type.py,sha256=iH13r8swy79lw8icGNKW1lqN09TX93MvR1zi-qvWNlU,869
24
- planar/db/alembic.ini,sha256=FI1S0DlTn7IVp3-eT17PNxbVBbqhn84k2VzwRHpNz_Q,4304
24
+ planar/db/alembic.ini,sha256=KtC8QRYmJoWV04tYZ94FDvE4xrYm-vhTTdCRfryPdes,4303
25
25
  planar/db/db.py,sha256=VNpHH1R62tdWVLIV1I2ULmw3B8M6-RsM2ALG3VAVjSg,12790
26
26
  planar/dependencies.py,sha256=PH78fGk3bQfGnz-AphxH49307Y0XVgl3EY0LdGJnoik,1008
27
27
  planar/files/__init__.py,sha256=uXqwnoIaJAuDYXFA-9gqcSq1R4mZLNyfem1zZyGI5Ek,206
28
28
  planar/files/models.py,sha256=zbZvMkoqoSnn7yOo26SRtEgtlHJbFIvwSht75APHQXk,6145
29
29
  planar/files/storage/azure_blob.py,sha256=QM-j9NHZmbwGv7H04yNpakJ54BJMseWEjehSekL3yr8,12316
30
30
  planar/files/storage/base.py,sha256=KO7jyKwjKg5fNSLvhxJWE-lsypv6LXXf7bgA34aflwY,2495
31
- planar/files/storage/config.py,sha256=jE9Dn6cG_a4x9pdaZkasOxjyWkK6hmplLrPjEsRXGLM,3473
31
+ planar/files/storage/config.py,sha256=lzODgufhZliwQDikqMQCX3KKiap0CL6Cc9qbIdeUMCU,3617
32
32
  planar/files/storage/context.py,sha256=Qadlz4T-FQ1A0TdGsOfuNmM679ohayU7oaexUpT8AY0,361
33
33
  planar/files/storage/local_directory.py,sha256=1SsEfr0Ud9TvSQJneDl_M-D7AFYixLE9t-bVIiY3aSI,7395
34
34
  planar/files/storage/s3.py,sha256=1861rSw3kplXtugUWD7mdSD_EnPSHME1mGc82V69r5g,8234
@@ -60,12 +60,12 @@ planar/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
60
60
  planar/registry_items.py,sha256=slRQWmrK39wn5BQ3ohHmbiwvkEq1yr1nB8jSc7QG2CE,2132
61
61
  planar/routers/__init__.py,sha256=B_ZEbBuosX4ahPfvWZsyMIPmQm0rt6ail4nJA6NLfOk,379
62
62
  planar/routers/agents_router.py,sha256=trb1JPYVlaV7O2uoYvKIrLuTNGP_PmQSLZmXYFWrHkg,8251
63
- planar/routers/dataset_router.py,sha256=wTFI-NCNsFLWZEmcq0g1Sj9wxrhrh6vGglpriuHoHrk,7424
63
+ planar/routers/dataset_router.py,sha256=V712DNeqycejP1daoEIDShoH3pW4wJ3U0fF3F3Wxv_0,7585
64
64
  planar/routers/entity_router.py,sha256=7Y1LDSqI_ovoOGr9DGylGM8BmRxF-WSPQSwITJHc6NE,4841
65
65
  planar/routers/event.py,sha256=yvzzMQaKRoS2A0KSjQTyWcfmBzpt8xPNDfVW50XUSCw,2961
66
66
  planar/routers/files.py,sha256=udu6PeZ9AuOpNyJete21rWAVQyE0qnC7tnSyJ97AH4Y,5644
67
67
  planar/routers/human.py,sha256=m_CbH97_QGmzriui_xopLOq-2D1kR0WgvO92fMaFeBQ,5010
68
- planar/routers/info.py,sha256=_7edvZjWbI65htI8nrQdHNxjMfSn2u-JHmxnpNWUAiU,5396
68
+ planar/routers/info.py,sha256=XaDTuqZl4jaF5i4po4j2M2Alhq6HcOC4GI1Fq9QVN30,5418
69
69
  planar/routers/models.py,sha256=zknkVs9-B4UJlMe9fl2EpXx7sdzfjQfwAbNoL1a0wmI,4694
70
70
  planar/routers/object_config_router.py,sha256=zA8-gGBQp1-Gm3uCC4WJ6nLicFwt4CsCqCYLFp1lRN8,4802
71
71
  planar/routers/rule.py,sha256=d6giUwYRKzxQFPeoWbe8Ylp2Cxd71_uK8yoS9NrOOBg,3563
@@ -97,10 +97,11 @@ planar/task_local.py,sha256=pyvT0bdzAn15HL2yQUs9YrU5MVXh9njQt9MH51AGljs,1102
97
97
  planar/testing/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
98
98
  planar/testing/fixtures.py,sha256=z0VkKTqAg9z_1L_ojB0pTzKSaLPcDeNxRq_RB36rUU8,9740
99
99
  planar/testing/memory_storage.py,sha256=apcuFisC3hW9KiU3kO8zwHQ6oK9Lu20NSX5fJ0LSZUY,2824
100
- planar/testing/planar_test_client.py,sha256=2atx5zER5bGrCVoa-lcag8xP2ZcbnOLKoGRKpfOJCg8,1992
100
+ planar/testing/planar_test_client.py,sha256=yMEmEUxlnoO4OeErx0DO_Fch0XrKyJBcsKCq-qrZrZA,2220
101
101
  planar/testing/synchronizable_tracer.py,sha256=SWeta1CgwGsN5duC0FR8NyXOQ1b1L8nDpvGdjZVJ9Bg,4938
102
102
  planar/testing/workflow_observer.py,sha256=0Q2xsYuZzNGXHZVwvXBqL9KXPsdIXuSZGBJAxHopzJw,2976
103
103
  planar/utils.py,sha256=YP37-ODS8nYOIfHPo11CwCpQRsg8oc57lQ0wkXwqCyo,3607
104
+ planar/version.py,sha256=FvzlKrPfP1lqDNc-m3AIyd0wijm3VtvpUS5VKdUHq3Y,699
104
105
  planar/workflows/__init__.py,sha256=yFrrtKYUCx4jBPpHdEWDfKQgZXzGyr9voj5lFe9C-_w,826
105
106
  planar/workflows/context.py,sha256=93kPSmYniqjX_lv6--eUUPnzZEKZJi6IPaAjrT-hFRY,1271
106
107
  planar/workflows/contrib.py,sha256=tUqMZ42Jh8KMy1JP1VFJOD4rsiYxzMTd5pJfe2t3yzk,6650
@@ -121,7 +122,7 @@ planar/workflows/step_testing_utils.py,sha256=WiTwxB4mM2y6dW7CJ3PlIR1BkBodSxQV7-
121
122
  planar/workflows/sub_workflow_runner.py,sha256=EpS7DhhXRbC6ABm-Sho6Uyxh2TqCjcTPDYvcTQN4FjY,8313
122
123
  planar/workflows/tracing.py,sha256=E7E_kj2VBQisDqrllviIshbvOmB9QcEeRwMapunqio4,2732
123
124
  planar/workflows/wrappers.py,sha256=dY_3NqkzGMG4jgX2lkAqvHTYFA1lBzhkQCw7N5CyaQM,1174
124
- planar-0.11.0.dist-info/WHEEL,sha256=-neZj6nU9KAMg2CnCY6T3w8J53nx1kFGw_9HfoSzM60,79
125
- planar-0.11.0.dist-info/entry_points.txt,sha256=L3T0w9u2UPKWXv6JbXFWKU1d5xyEAq1xVWbpYS6mLNg,96
126
- planar-0.11.0.dist-info/METADATA,sha256=jlCvhwa-3Djk8_A05TJqgcGxE4Hj5U3wbYrDp5hNSi4,12556
127
- planar-0.11.0.dist-info/RECORD,,
125
+ planar-0.12.0.dist-info/WHEEL,sha256=-neZj6nU9KAMg2CnCY6T3w8J53nx1kFGw_9HfoSzM60,79
126
+ planar-0.12.0.dist-info/entry_points.txt,sha256=L3T0w9u2UPKWXv6JbXFWKU1d5xyEAq1xVWbpYS6mLNg,96
127
+ planar-0.12.0.dist-info/METADATA,sha256=QzYhhuXw0VLyymqS31qadZ_DeIYbG7v93MZAe5t2Esw,7285
128
+ planar-0.12.0.dist-info/RECORD,,