planar 0.11.0__py3-none-any.whl → 0.13.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.
@@ -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,
@@ -3,8 +3,16 @@ name = "{{ name }}"
3
3
  version = "0.1.0"
4
4
  requires-python = ">=3.12"
5
5
  dependencies = [
6
- "planar[data]>=0.10.0",
6
+ {%- if local_source %}
7
+ "planar",
8
+ {%- else %}
9
+ "planar>=0.10.0",
10
+ {%- endif %}
7
11
  ]
8
12
 
9
- [[tool.uv.index]]
10
- url = "https://coplane.github.io/planar/simple/"
13
+ {%- if local_source %}
14
+
15
+ [tool.uv.sources]
16
+ planar = { path = "{{ planar_source_path }}", editable = true }
17
+
18
+ {%- endif %}
planar/sse/proxy.py CHANGED
@@ -178,7 +178,13 @@ class SSEProxy:
178
178
  # builtin hub. That's why we check for self.builtin_process instead of
179
179
  # self.enable_builtin_hub. Also helps with type checking.
180
180
  logger.info("terminating builtin sse hub process")
181
- self.builtin_process.terminate()
181
+ try:
182
+ self.builtin_process.terminate()
183
+ except AttributeError:
184
+ # Race condition: _popen may be None if process already terminated.
185
+ # This can happen when stop() is called multiple times during shutdown.
186
+ logger.debug("process already terminated or cleaned up")
187
+ self.builtin_process = None
182
188
 
183
189
  def setup_proxy_endpoint(self):
184
190
  @self.router.get("/")
@@ -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
@@ -104,11 +104,15 @@ def agent_notify(kind: Notification, data: str):
104
104
  if callback is not None:
105
105
  context = get_context()
106
106
  logger.debug("notifying agent event", kind=kind)
107
+ if context.step_stack:
108
+ step_id = context.step_stack[-1].step_id
109
+ else:
110
+ step_id = -1
107
111
  callback(
108
112
  WorkflowNotification(
109
113
  kind=kind,
110
114
  workflow_id=context.workflow_id,
111
- data=AgentEventData(data=data, step_id=context.step_stack[-1].step_id),
115
+ data=AgentEventData(data=data, step_id=step_id),
112
116
  )
113
117
  )
114
118
 
@@ -0,0 +1,203 @@
1
+ Metadata-Version: 2.4
2
+ Name: planar
3
+ Version: 0.13.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: duckdb>=1.3,<1.4 ; extra == 'data'
29
+ Requires-Dist: ducklake>=0.1.1 ; extra == 'data'
30
+ Requires-Dist: ibis-framework[duckdb]>=10.8.0 ; extra == 'data'
31
+ Requires-Dist: polars>=1.31.0 ; extra == 'data'
32
+ Requires-Dist: opentelemetry-api>=1.34.1 ; extra == 'otel'
33
+ Requires-Dist: opentelemetry-exporter-otlp>=1.34.1 ; extra == 'otel'
34
+ Requires-Dist: opentelemetry-instrumentation-logging>=0.55b1 ; extra == 'otel'
35
+ Requires-Dist: opentelemetry-sdk>=1.34.1 ; extra == 'otel'
36
+ Requires-Python: >=3.12
37
+ Provides-Extra: azure
38
+ Provides-Extra: data
39
+ Provides-Extra: otel
40
+ Description-Content-Type: text/markdown
41
+
42
+ # Planar
43
+
44
+ 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.
45
+
46
+ ## Feature Highlights
47
+
48
+ - Durable workflow engine with resumable async steps, automatic retries, and suspension points
49
+ - Agent step framework with first-class support for OpenAI, Anthropic, and other providers
50
+ - Human task assignments and rule engine tooling baked into workflow execution
51
+ - SQLModel-powered data layer with Alembic migrations and CRUD scaffolding out of the box
52
+ - Built-in file management and storage adapters for local disk, Amazon S3, and Azure Blob Storage
53
+ - CLI-driven developer workflow with templated scaffolding, hot reload, and environment-aware configuration
54
+
55
+ ## Installation
56
+
57
+ Planar is published on PyPI. Add it to an existing project with `uv`:
58
+
59
+ ```bash
60
+ uv add planar
61
+ ```
62
+
63
+ To explore the CLI without updating `pyproject.toml`, use the ephemeral uvx runner:
64
+
65
+ ```bash
66
+ uvx planar --help
67
+ ```
68
+
69
+ ## Quickstart
70
+
71
+ Generate a new service, start up the dev server, and inspect the auto-generated APIs:
72
+
73
+ ```bash
74
+ uvx planar scaffold --name my_service
75
+ cd my_service
76
+ uv run planar dev src/main.py
77
+ ```
78
+
79
+ 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`.
80
+
81
+ ## Define a Durable Workflow
82
+
83
+ ```python
84
+ from datetime import timedelta
85
+
86
+ from planar import PlanarApp
87
+ from planar.workflows import step, suspend, workflow
88
+
89
+ @step
90
+ async def charge_customer(order_id: str) -> None:
91
+ ...
92
+
93
+ @step
94
+ async def notify_success(order_id: str) -> None:
95
+ ...
96
+
97
+ @workflow
98
+ async def process_order(order_id: str) -> None:
99
+ await charge_customer(order_id)
100
+ await suspend(interval=timedelta(hours=1))
101
+ await notify_success(order_id)
102
+
103
+
104
+ app = PlanarApp()
105
+ app.register_workflow(process_order)
106
+ ```
107
+
108
+ 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.
109
+
110
+ ## Core Capabilities
111
+
112
+ - **Workflow orchestration**: Compose async steps with guaranteed persistence, scheduling, and concurrency control.
113
+ - **Agent steps**: Run LLM-powered actions durably with provider-agnostic adapters and structured prompts.
114
+ - **Human tasks and rules**: Build human-in-the-loop approvals and declarative rule evaluations alongside automated logic.
115
+ - **Stateful data and files**: Model entities with SQLModel, manage migrations through Alembic, and store files using pluggable backends.
116
+ - **Observability**: Structured logging and OpenTelemetry hooks surface workflow progress and performance metrics.
117
+
118
+ ## Command Line Interface
119
+
120
+ ```bash
121
+ uvx planar scaffold --help # generate a new project from the official template
122
+ uv run planar dev [PATH] # run with hot reload and development defaults
123
+ uv run planar prod [PATH] # run with production defaults
124
+ ```
125
+
126
+ `[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`.
127
+
128
+ ## Configuration
129
+
130
+ 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.
131
+
132
+ Example minimal override:
133
+
134
+ ```yaml
135
+ ai_providers:
136
+ openai:
137
+ api_key: ${OPENAI_API_KEY}
138
+
139
+ storage:
140
+ directory: .files
141
+ ```
142
+
143
+ For more configuration patterns and workflow design guidance, browse the documents in `docs/`.
144
+
145
+ ## Examples
146
+
147
+ - `examples/expense_approval_workflow` — human approvals with AI agent collaboration
148
+ - `examples/event_based_workflow` — event-driven orchestration and external wakeups
149
+ - `examples/simple_service` — CRUD service paired with workflows
150
+
151
+ Run any example with `uv run planar dev path/to/main.py`.
152
+
153
+ ## Local Development
154
+
155
+ Planar is built with `uv`. Clone the repository and install dev dependencies:
156
+
157
+ ```bash
158
+ uv sync --extra otel
159
+ ```
160
+
161
+ Useful commands:
162
+
163
+ - `uv run ruff check --fix` and `uv run ruff format` to lint and format
164
+ - `uv run pyright` for static type checking
165
+ - `uv run pytest` to run the test suite (use `-n auto` for parallel execution)
166
+ - `uv run pytest --cov=planar` to collect coverage
167
+ - `uv tool install pre-commit && uv tool run pre-commit install` to enable git hooks
168
+
169
+ ### PostgreSQL Test Suite
170
+
171
+ ```bash
172
+ docker run --restart=always --name planar-postgres \
173
+ -e POSTGRES_PASSWORD=postgres \
174
+ -p 127.0.0.1:5432:5432 \
175
+ -d docker.io/library/postgres
176
+
177
+ PLANAR_TEST_POSTGRESQL=1 PLANAR_TEST_POSTGRESQL_CONTAINER=planar-postgres \
178
+ uv run pytest -s
179
+ ```
180
+
181
+ Disable SQLite with `PLANAR_TEST_SQLITE=0`.
182
+
183
+ ### Cairo SVG Dependencies
184
+
185
+ Some AI integration tests convert SVG assets using `cairosvg`. Install Cairo libraries locally before running those tests:
186
+
187
+ ```bash
188
+ brew install cairo libffi pkg-config
189
+ export DYLD_FALLBACK_LIBRARY_PATH="/opt/homebrew/lib:${DYLD_FALLBACK_LIBRARY_PATH}"
190
+ ```
191
+
192
+ Most Linux distributions ship the required libraries via their package manager.
193
+
194
+ ## Documentation
195
+
196
+ Dive deeper into Planar's design and APIs in the `docs/` directory:
197
+
198
+ - `docs/workflows.md`
199
+ - `docs/design/event_based_waiting.md`
200
+ - `docs/design/human_step.md`
201
+ - `docs/design/agent_step.md`
202
+
203
+ For agentic coding tools, use `docs/llm_prompt.md` as a drop-in reference document in whatever tool you are using.
@@ -1,42 +1,42 @@
1
1
  planar/__init__.py,sha256=FAYRGjuJOH2Y_XYFA0-BrRFjuKdPzIShNbaYwJbtu6A,499
2
- planar/ai/__init__.py,sha256=ABOKvqQOLlVJkptcvXcuLjVZZWEsK8h-1RyFGK7kib8,231
3
- planar/ai/agent.py,sha256=HAyQvdA-NOEYMtze3Gh_BtOzk-rD1DXnv1jNGWd-9dA,12499
4
- planar/ai/agent_base.py,sha256=5UURilfMldIYoTNzwlSY9eVaub5LDovCGFeAszyuGWE,6198
2
+ planar/ai/__init__.py,sha256=lgGmY3ffmKqt35JncZmJOK5jWZ0bJRAksR54hYqV8is,298
3
+ planar/ai/agent.py,sha256=xNJiQV-FC1BVkIBb9zpIy8NKN7jQl1j21TMiACyxBZg,12513
4
+ planar/ai/agent_base.py,sha256=0P4vjTvka8MERP9z360J4nGd-TAfeafK9zczbhcvU9k,6410
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
+ planar/ai/tool_context.py,sha256=9W7VFrHPhNeieEvlJlv-OrFPVzySItdUjKCutkXpYFU,298
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
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
10
+ planar/app.py,sha256=2ijbrORCfjKReDieLbwgey_9poJJwEfWkvCNKcVYcdk,19484
11
+ planar/cli.py,sha256=GONw7Dpyxy_7Vf48rLmQXRQnC_IyWENRULQF0DwiCuY,11108
12
+ planar/config.py,sha256=54N-qPaxihEn6QUQvXsdtbEN-pTTrd_5NG8WFYb0CRI,18879
13
+ planar/data/__init__.py,sha256=eqSREzJ58HM05DXpR_00M6RDFxtHSIh-OEuqXBPVsVc,362
14
+ planar/data/config.py,sha256=oaLiwN3OUt3i85MS0zxpdMNG5VjaM5xB6VtPc1f4MFU,1484
15
+ planar/data/connection.py,sha256=QPcbomoWDdttu28cfeQAtnUdc_ptayQTaqwcC8Gq4vc,8056
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
35
35
  planar/human/__init__.py,sha256=FwpV-FFssKKlvKSjWoI4gJB1XTMaNb1UNCSBxjAtIBw,147
36
36
  planar/human/human.py,sha256=-oRtN_8bCtSV7Sxku7yG4rof7T5pr4j18Cfm3u4Z3PM,14925
37
- planar/human/models.py,sha256=Cec1Y9NGGtuAl1ZhqNc9PWIq__BbiWVTh7IYKR4yl3w,2317
37
+ planar/human/models.py,sha256=uYqH79qgwH2HM6BO7dR54WFcvleVCfpZOYRSNJZ9P2o,2272
38
38
  planar/logging/__init__.py,sha256=BW101gskQS3C2agKSDiJEy4L-j5z6BP1AwEfd2JMXHM,254
39
- planar/logging/attributes.py,sha256=SB-lC-Osa55zXkX2UAWm56vKXvHgbF7TmhGnSiBWejk,1529
39
+ planar/logging/attributes.py,sha256=4JCmncF46MbGt6q4wD60DZss8eBWDdKDvxS8w8lE9fc,1580
40
40
  planar/logging/context.py,sha256=mGVpL-276VWpRUIGlkGwbn9gkATqFS7lcFn1aM0v-eQ,384
41
41
  planar/logging/formatter.py,sha256=NMDhpo7ezsfGO7cPwOWbClqODviEgSjqHCoqrCCIu2c,3560
42
42
  planar/logging/logger.py,sha256=vj3-z2ea0J1ppgDpJBsrueA3jg5kjk9ceIo-4tWarXk,2650
@@ -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
@@ -81,7 +81,7 @@ planar/scaffold_templates/app/flows/process_invoice.py.j2,sha256=R3EII_O2DHV1kvf
81
81
  planar/scaffold_templates/main.py.j2,sha256=zrqsuv3Fp4lcknvB37RrRHy11msdFB1yDguYmTLLPhw,398
82
82
  planar/scaffold_templates/planar.dev.yaml.j2,sha256=I5-IqX7GJm6qA91WtUMw43L4hKACqgnER_H2racim4c,998
83
83
  planar/scaffold_templates/planar.prod.yaml.j2,sha256=FahJ2atDtvVH7IUCatGq6h9hmyF8meeiWC8RLfWphOQ,867
84
- planar/scaffold_templates/pyproject.toml.j2,sha256=HpBc3cuTr-VeVN3BQ8y1Vr2eOtkL7TLH5mNz_T-akpA,190
84
+ planar/scaffold_templates/pyproject.toml.j2,sha256=XdOf3B_fkTDwEzQsneNdmC43rptmZoqwFRj7QpaL7OI,299
85
85
  planar/security/auth_context.py,sha256=i63JkHQ3oXNlTis7GIKRkZJbkcvZhD2jVDuO7blgbSc,5068
86
86
  planar/security/auth_middleware.py,sha256=Grrm0i2bstWZ83ukrNZsHvFbNzffN0rvbbCcb2OxRY0,5746
87
87
  planar/security/authorization.py,sha256=zTh5rLmVJZnGDq540_1WYljJ7Hws-BY_P6VqUCONqLE,12760
@@ -92,15 +92,16 @@ planar/sse/constants.py,sha256=jE3SooTEWPuuL_Bi6DisJYMR9pKOiHVfboU2h5QTJRg,22
92
92
  planar/sse/example.html,sha256=SgTJbdJ3B1F1DxLC2YWuX2F1XVwKcTjX34CbJCXoCTM,4144
93
93
  planar/sse/hub.py,sha256=5jhfk7zdCivau3TT1MxU2qtvETSskhqEiXzt-t0sRpE,6859
94
94
  planar/sse/model.py,sha256=fU_Fx9LS2ouS6-Dj1TIF-PLGul9YratKWafoWfZR1gc,123
95
- planar/sse/proxy.py,sha256=aJGo_-JIeQ0xSmE4HJdulZxIgCVRsBMMXqqSqtPvTvo,9177
95
+ planar/sse/proxy.py,sha256=LgfnCjZHtnDquV5HpdoSru43pxk-T5aY9NCjQLNrrcQ,9518
96
96
  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
@@ -111,7 +112,7 @@ planar/workflows/execution.py,sha256=8c4a2L1qRMPQrCEJ8-sEk-gJi_xKq5gYKDSWSbSspVI
111
112
  planar/workflows/lock.py,sha256=QU5_y_n8RHOC7ppLicH7yWX-Ni7N93hlB14D2zXOQ8A,8773
112
113
  planar/workflows/misc.py,sha256=g3XVRMeU9mgDRi_6RgFdydLEqvTAg49wbIGlmC7kOu8,140
113
114
  planar/workflows/models.py,sha256=SKBJTGhd4nVWxtlDkaQrU2RvRTtoj07PJhLT73cF_ac,5591
114
- planar/workflows/notifications.py,sha256=JrObfWD-uRZJlZLMSDJDqjDuXfYAoRSLfgEeyoy98Vs,3795
115
+ planar/workflows/notifications.py,sha256=APAUKk1-Y7R5E1LHA4RWQK5Z6vh2lIvf5tHYWwhD5WM,3895
115
116
  planar/workflows/orchestrator.py,sha256=rneB1yOPDZiJcHFbD6UDZ4juU77iSBK1eu1gOFm58vM,15480
116
117
  planar/workflows/query.py,sha256=38B5SLwXf3AlA_1ChR5DicFWdcUqzpQzMkuAUCNHafI,8838
117
118
  planar/workflows/serialization.py,sha256=v3eqUS0odUFS7PnIrKyKUrK-feIv0ssxEp2VxjkddyI,13733
@@ -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.13.0.dist-info/WHEEL,sha256=eh7sammvW2TypMMMGKgsM83HyA_3qQ5Lgg3ynoecH3M,79
126
+ planar-0.13.0.dist-info/entry_points.txt,sha256=L3T0w9u2UPKWXv6JbXFWKU1d5xyEAq1xVWbpYS6mLNg,96
127
+ planar-0.13.0.dist-info/METADATA,sha256=tJ-l6OnJC3bTt3e6QGw1S0EYZIr72eIq7Py1zrkczuQ,7335
128
+ planar-0.13.0.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: uv 0.8.22
2
+ Generator: uv 0.8.24
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any