mainsequence 4.1.4__tar.gz → 4.1.6__tar.gz
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.
- {mainsequence-4.1.4 → mainsequence-4.1.6}/PKG-INFO +1 -1
- {mainsequence-4.1.4 → mainsequence-4.1.6}/agent_scaffold/skills/data_publishing/data_nodes/SKILL.md +18 -37
- {mainsequence-4.1.4 → mainsequence-4.1.6}/agent_scaffold/skills/ms-markets/SKILL.md +2 -2
- {mainsequence-4.1.4 → mainsequence-4.1.6}/mainsequence/cli/api.py +4 -4
- {mainsequence-4.1.4 → mainsequence-4.1.6}/mainsequence/cli/cli.py +12 -11
- {mainsequence-4.1.4 → mainsequence-4.1.6}/mainsequence/client/base.py +0 -1
- {mainsequence-4.1.4/mainsequence → mainsequence-4.1.6/mainsequence/client}/compute_validation.py +6 -2
- {mainsequence-4.1.4 → mainsequence-4.1.6}/mainsequence/client/data_sources_interfaces/duckdb.py +2 -3
- mainsequence-4.1.6/mainsequence/client/data_sources_interfaces/local_paths.py +14 -0
- {mainsequence-4.1.4 → mainsequence-4.1.6}/mainsequence/client/data_sources_interfaces/sqlite.py +2 -3
- {mainsequence-4.1.4 → mainsequence-4.1.6}/mainsequence/client/models_foundry.py +5 -4
- {mainsequence-4.1.4 → mainsequence-4.1.6}/mainsequence/client/models_helpers.py +2 -2
- {mainsequence-4.1.4 → mainsequence-4.1.6}/mainsequence/logconf.py +23 -39
- {mainsequence-4.1.4 → mainsequence-4.1.6}/mainsequence/meta_tables/__init__.py +0 -9
- mainsequence-4.1.6/mainsequence/meta_tables/compiled_sql/__init__.py +5 -0
- mainsequence-4.1.4/mainsequence/meta_tables/compiled_sql.py → mainsequence-4.1.6/mainsequence/meta_tables/compiled_sql/v1.py +3 -3
- {mainsequence-4.1.4 → mainsequence-4.1.6}/mainsequence/meta_tables/data_nodes/build_operations.py +1 -1
- {mainsequence-4.1.4 → mainsequence-4.1.6}/mainsequence/meta_tables/data_nodes/data_nodes.py +2 -2
- {mainsequence-4.1.4 → mainsequence-4.1.6}/mainsequence/meta_tables/data_nodes/persist_managers.py +2 -2
- {mainsequence-4.1.4 → mainsequence-4.1.6}/mainsequence/runtime_flags.py +2 -2
- {mainsequence-4.1.4 → mainsequence-4.1.6}/mainsequence.egg-info/PKG-INFO +1 -1
- {mainsequence-4.1.4 → mainsequence-4.1.6}/mainsequence.egg-info/SOURCES.txt +4 -5
- {mainsequence-4.1.4 → mainsequence-4.1.6}/pyproject.toml +1 -1
- {mainsequence-4.1.4 → mainsequence-4.1.6}/tests/test_auth_precedence.py +5 -9
- {mainsequence-4.1.4 → mainsequence-4.1.6}/tests/test_build_operations_hashing.py +5 -5
- {mainsequence-4.1.4 → mainsequence-4.1.6}/tests/test_cli.py +30 -18
- {mainsequence-4.1.4 → mainsequence-4.1.6}/tests/test_data_access_mixin_dimension_audit.py +0 -55
- {mainsequence-4.1.4 → mainsequence-4.1.6}/tests/test_data_node_storage_dimension_queries.py +0 -20
- {mainsequence-4.1.4 → mainsequence-4.1.6}/tests/test_data_node_update_flow.py +0 -2
- {mainsequence-4.1.4 → mainsequence-4.1.6}/tests/test_duckdb_interface_dimensions.py +0 -2
- {mainsequence-4.1.4 → mainsequence-4.1.6}/tests/test_filter_normalization.py +0 -26
- {mainsequence-4.1.4 → mainsequence-4.1.6}/tests/test_logconf.py +21 -21
- {mainsequence-4.1.4 → mainsequence-4.1.6}/tests/test_meta_tables_client_models.py +4 -7
- {mainsequence-4.1.4 → mainsequence-4.1.6}/tests/test_meta_tables_sqlalchemy_contracts.py +0 -1
- {mainsequence-4.1.4 → mainsequence-4.1.6}/tests/test_run_configuration.py +5 -9
- {mainsequence-4.1.4 → mainsequence-4.1.6}/tests/test_source_table_configuration.py +1 -71
- {mainsequence-4.1.4 → mainsequence-4.1.6}/tests/test_sqlite_interface_dimensions.py +0 -2
- {mainsequence-4.1.4 → mainsequence-4.1.6}/tests/test_update_statistics.py +1 -4
- mainsequence-4.1.4/mainsequence/meta_tables/config.py +0 -128
- mainsequence-4.1.4/mainsequence/meta_tables/configuration_models.py +0 -5
- mainsequence-4.1.4/mainsequence/meta_tables/utils.py +0 -45
- {mainsequence-4.1.4 → mainsequence-4.1.6}/LICENSE +0 -0
- {mainsequence-4.1.4 → mainsequence-4.1.6}/README.md +0 -0
- {mainsequence-4.1.4 → mainsequence-4.1.6}/agent_scaffold/AGENTS.md +0 -0
- {mainsequence-4.1.4 → mainsequence-4.1.6}/agent_scaffold/skills/a2a_communication/SKILL.md +0 -0
- {mainsequence-4.1.4 → mainsequence-4.1.6}/agent_scaffold/skills/application_surfaces/api_surfaces/SKILL.md +0 -0
- {mainsequence-4.1.4 → mainsequence-4.1.6}/agent_scaffold/skills/command_center/adapter_from_api/SKILL.md +0 -0
- {mainsequence-4.1.4 → mainsequence-4.1.6}/agent_scaffold/skills/command_center/api_mock_prototyping/SKILL.md +0 -0
- {mainsequence-4.1.4 → mainsequence-4.1.6}/agent_scaffold/skills/command_center/app_components/SKILL.md +0 -0
- {mainsequence-4.1.4 → mainsequence-4.1.6}/agent_scaffold/skills/command_center/connections/SKILL.md +0 -0
- {mainsequence-4.1.4 → mainsequence-4.1.6}/agent_scaffold/skills/command_center/workspace_analysis/SKILL.md +0 -0
- {mainsequence-4.1.4 → mainsequence-4.1.6}/agent_scaffold/skills/command_center/workspace_builder/SKILL.md +0 -0
- {mainsequence-4.1.4 → mainsequence-4.1.6}/agent_scaffold/skills/command_center/workspace_design/SKILL.md +0 -0
- {mainsequence-4.1.4 → mainsequence-4.1.6}/agent_scaffold/skills/dashboards/streamlit/SKILL.md +0 -0
- {mainsequence-4.1.4 → mainsequence-4.1.6}/agent_scaffold/skills/data_access/exploration/SKILL.md +0 -0
- {mainsequence-4.1.4 → mainsequence-4.1.6}/agent_scaffold/skills/data_publishing/meta_tables/SKILL.md +0 -0
- {mainsequence-4.1.4 → mainsequence-4.1.6}/agent_scaffold/skills/maintenance/bug_auditor/SKILL.md +0 -0
- {mainsequence-4.1.4 → mainsequence-4.1.6}/agent_scaffold/skills/platform_operations/access_control_and_sharing/SKILL.md +0 -0
- {mainsequence-4.1.4 → mainsequence-4.1.6}/agent_scaffold/skills/platform_operations/orchestration_and_releases/SKILL.md +0 -0
- {mainsequence-4.1.4 → mainsequence-4.1.6}/agent_scaffold/skills/project_builder/SKILL.md +0 -0
- {mainsequence-4.1.4 → mainsequence-4.1.6}/agent_scaffold/skills/project_to_agent/SKILL.md +0 -0
- {mainsequence-4.1.4 → mainsequence-4.1.6}/mainsequence/__init__.py +0 -0
- {mainsequence-4.1.4 → mainsequence-4.1.6}/mainsequence/__main__.py +0 -0
- {mainsequence-4.1.4 → mainsequence-4.1.6}/mainsequence/bootstrap.py +0 -0
- {mainsequence-4.1.4 → mainsequence-4.1.6}/mainsequence/cli/__init__.py +0 -0
- {mainsequence-4.1.4 → mainsequence-4.1.6}/mainsequence/cli/browser_auth.py +0 -0
- {mainsequence-4.1.4 → mainsequence-4.1.6}/mainsequence/cli/config.py +0 -0
- {mainsequence-4.1.4 → mainsequence-4.1.6}/mainsequence/cli/docker_utils.py +0 -0
- {mainsequence-4.1.4 → mainsequence-4.1.6}/mainsequence/cli/doctor.py +0 -0
- {mainsequence-4.1.4 → mainsequence-4.1.6}/mainsequence/cli/local_ops.py +0 -0
- {mainsequence-4.1.4 → mainsequence-4.1.6}/mainsequence/cli/model_filters.py +0 -0
- {mainsequence-4.1.4 → mainsequence-4.1.6}/mainsequence/cli/project_status.py +0 -0
- {mainsequence-4.1.4 → mainsequence-4.1.6}/mainsequence/cli/pydantic_cli.py +0 -0
- {mainsequence-4.1.4 → mainsequence-4.1.6}/mainsequence/cli/sdk_utils.py +0 -0
- {mainsequence-4.1.4 → mainsequence-4.1.6}/mainsequence/cli/ssh_utils.py +0 -0
- {mainsequence-4.1.4 → mainsequence-4.1.6}/mainsequence/cli/ui.py +0 -0
- {mainsequence-4.1.4 → mainsequence-4.1.6}/mainsequence/client/__init__.py +0 -0
- {mainsequence-4.1.4 → mainsequence-4.1.6}/mainsequence/client/agent_runtime_models.py +0 -0
- {mainsequence-4.1.4 → mainsequence-4.1.6}/mainsequence/client/client.py +0 -0
- {mainsequence-4.1.4 → mainsequence-4.1.6}/mainsequence/client/command_center/__init__.py +0 -0
- {mainsequence-4.1.4 → mainsequence-4.1.6}/mainsequence/client/command_center/app_component.py +0 -0
- {mainsequence-4.1.4 → mainsequence-4.1.6}/mainsequence/client/command_center/connections.py +0 -0
- {mainsequence-4.1.4 → mainsequence-4.1.6}/mainsequence/client/command_center/data_models.py +0 -0
- {mainsequence-4.1.4 → mainsequence-4.1.6}/mainsequence/client/command_center/workspace.py +0 -0
- {mainsequence-4.1.4 → mainsequence-4.1.6}/mainsequence/client/command_center/workspace_snapshot.py +0 -0
- {mainsequence-4.1.4 → mainsequence-4.1.6}/mainsequence/client/data_sources_interfaces/__init__.py +0 -0
- {mainsequence-4.1.4 → mainsequence-4.1.6}/mainsequence/client/dtype_codec.py +0 -0
- {mainsequence-4.1.4 → mainsequence-4.1.6}/mainsequence/client/exceptions.py +0 -0
- {mainsequence-4.1.4 → mainsequence-4.1.6}/mainsequence/client/fastapi/__init__.py +0 -0
- {mainsequence-4.1.4 → mainsequence-4.1.6}/mainsequence/client/fastapi/auth.py +0 -0
- {mainsequence-4.1.4 → mainsequence-4.1.6}/mainsequence/client/models_metatables.py +0 -0
- {mainsequence-4.1.4 → mainsequence-4.1.6}/mainsequence/client/models_user.py +0 -0
- {mainsequence-4.1.4 → mainsequence-4.1.6}/mainsequence/client/utils.py +0 -0
- {mainsequence-4.1.4 → mainsequence-4.1.6}/mainsequence/defaults.py +0 -0
- {mainsequence-4.1.4 → mainsequence-4.1.6}/mainsequence/instrumentation/__init__.py +0 -0
- {mainsequence-4.1.4 → mainsequence-4.1.6}/mainsequence/instrumentation/utils.py +0 -0
- {mainsequence-4.1.4 → mainsequence-4.1.6}/mainsequence/meta_tables/__main__.py +0 -0
- {mainsequence-4.1.4 → mainsequence-4.1.6}/mainsequence/meta_tables/data_nodes/__init__.py +0 -0
- {mainsequence-4.1.4 → mainsequence-4.1.6}/mainsequence/meta_tables/data_nodes/models.py +0 -0
- {mainsequence-4.1.4 → mainsequence-4.1.6}/mainsequence/meta_tables/data_nodes/namespacing.py +0 -0
- {mainsequence-4.1.4 → mainsequence-4.1.6}/mainsequence/meta_tables/data_nodes/run_operations.py +0 -0
- {mainsequence-4.1.4 → mainsequence-4.1.6}/mainsequence/meta_tables/data_nodes/utils.py +0 -0
- {mainsequence-4.1.4 → mainsequence-4.1.6}/mainsequence/meta_tables/future_registry.py +0 -0
- {mainsequence-4.1.4 → mainsequence-4.1.6}/mainsequence/meta_tables/hashing.py +0 -0
- {mainsequence-4.1.4 → mainsequence-4.1.6}/mainsequence/meta_tables/pydantic_metadata.py +0 -0
- {mainsequence-4.1.4 → mainsequence-4.1.6}/mainsequence/meta_tables/sqlalchemy_contracts.py +0 -0
- {mainsequence-4.1.4 → mainsequence-4.1.6}/mainsequence.egg-info/dependency_links.txt +0 -0
- {mainsequence-4.1.4 → mainsequence-4.1.6}/mainsequence.egg-info/entry_points.txt +0 -0
- {mainsequence-4.1.4 → mainsequence-4.1.6}/mainsequence.egg-info/requires.txt +0 -0
- {mainsequence-4.1.4 → mainsequence-4.1.6}/mainsequence.egg-info/top_level.txt +0 -0
- {mainsequence-4.1.4 → mainsequence-4.1.6}/setup.cfg +0 -0
- {mainsequence-4.1.4 → mainsequence-4.1.6}/tests/test_cli_browser_auth.py +0 -0
- {mainsequence-4.1.4 → mainsequence-4.1.6}/tests/test_client.py +0 -0
- {mainsequence-4.1.4 → mainsequence-4.1.6}/tests/test_command_center_app_component_models.py +0 -0
- {mainsequence-4.1.4 → mainsequence-4.1.6}/tests/test_command_center_data_models.py +0 -0
- {mainsequence-4.1.4 → mainsequence-4.1.6}/tests/test_command_center_models.py +0 -0
- {mainsequence-4.1.4 → mainsequence-4.1.6}/tests/test_dependency_extras.py +0 -0
- {mainsequence-4.1.4 → mainsequence-4.1.6}/tests/test_models_user_request_bound_auth.py +0 -0
- {mainsequence-4.1.4 → mainsequence-4.1.6}/tests/test_pod_project_resolution.py +0 -0
- {mainsequence-4.1.4 → mainsequence-4.1.6}/tests/test_project_batch_jobs_from_file.py +0 -0
- {mainsequence-4.1.4 → mainsequence-4.1.6}/tests/test_secret_client_model.py +0 -0
- {mainsequence-4.1.4 → mainsequence-4.1.6}/tests/test_update_runner_uid_runtime.py +0 -0
- {mainsequence-4.1.4 → mainsequence-4.1.6}/tests/test_update_uid_guards.py +0 -0
- {mainsequence-4.1.4 → mainsequence-4.1.6}/tests/test_workspace_snapshot.py +0 -0
{mainsequence-4.1.4 → mainsequence-4.1.6}/agent_scaffold/skills/data_publishing/data_nodes/SKILL.md
RENAMED
|
@@ -15,7 +15,7 @@ is defined by a registered `PlatformTimeIndexMetaData` SQLAlchemy model.
|
|
|
15
15
|
Canonical workflow:
|
|
16
16
|
|
|
17
17
|
1. Define a `PlatformTimeIndexMetaData` storage class.
|
|
18
|
-
2. Register
|
|
18
|
+
2. Register that storage class before constructing the DataNode.
|
|
19
19
|
3. Construct the DataNode with `config=...` and `storage_table=StorageClass`.
|
|
20
20
|
4. Return a DataFrame from `update()` that matches the storage class contract.
|
|
21
21
|
|
|
@@ -30,8 +30,7 @@ Canonical workflow:
|
|
|
30
30
|
- `dependencies()`
|
|
31
31
|
- `update()`
|
|
32
32
|
- `prepare_update_statistics()`
|
|
33
|
-
|
|
34
|
-
- design single-index or `(time_index, unique_identifier)` DataFrame outputs
|
|
33
|
+
- design single-index or multidimensional time-first DataFrame outputs
|
|
35
34
|
- validate output shape against a `PlatformTimeIndexMetaData` storage contract
|
|
36
35
|
- define explicit `hash_namespace(...)` validation strategy
|
|
37
36
|
- write or review DataNode smoke tests
|
|
@@ -80,7 +79,6 @@ Before changing code, collect or infer:
|
|
|
80
79
|
- expected time index and identity index shape
|
|
81
80
|
- expected columns and dtypes from the storage class
|
|
82
81
|
- upstream dependencies
|
|
83
|
-
- whether the update is asset scoped
|
|
84
82
|
- first-run or backfill bounds
|
|
85
83
|
- whether the change must preserve the existing table contract
|
|
86
84
|
|
|
@@ -93,7 +91,7 @@ For every non-trivial DataNode task, make these decisions explicitly:
|
|
|
93
91
|
|
|
94
92
|
1. Is this a new dataset or the same dataset?
|
|
95
93
|
2. Is this change storage-contract work or update-process work?
|
|
96
|
-
3. Is the storage class
|
|
94
|
+
3. Is the storage class registered through its MetaTable path, or should the MetaTable skill handle it?
|
|
97
95
|
4. Is the node single-index or MultiIndex?
|
|
98
96
|
5. Does the first validation run happen under an explicit `hash_namespace(...)`?
|
|
99
97
|
|
|
@@ -141,17 +139,17 @@ class PricesTable(PlatformTimeIndexMetaData, Base):
|
|
|
141
139
|
close: Mapped[float] = mapped_column(Float, nullable=False)
|
|
142
140
|
```
|
|
143
141
|
|
|
144
|
-
Register
|
|
142
|
+
Register storage before constructing the DataNode:
|
|
145
143
|
|
|
146
144
|
```python
|
|
147
145
|
PricesTable.register(data_source_uid=data_source_uid)
|
|
148
146
|
```
|
|
149
147
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
148
|
+
`PlatformTimeIndexMetaData.register(...)` is the storage lifecycle path. Treat it
|
|
149
|
+
as an idempotent get-or-create operation: the platform returns the registered
|
|
150
|
+
metadata and UID, and the SDK records that metadata on the class. Do not manually
|
|
151
|
+
attach an existing UID, reconstruct a generic `MetaTable`, or use manual bind
|
|
152
|
+
helpers as an authoring step.
|
|
155
153
|
|
|
156
154
|
### 2. Keep DataNode As Update Logic
|
|
157
155
|
|
|
@@ -169,7 +167,7 @@ dependency, put that dependency storage reference in the config as
|
|
|
169
167
|
`type[PlatformTimeIndexMetaData]`. Do not add an extra constructor argument for
|
|
170
168
|
dependency storage tables. Config values of this type are hashed by the bound
|
|
171
169
|
`TimeIndexMetaData.uid` from `StorageClass.__time_index_metadata__`, so the class
|
|
172
|
-
must be registered
|
|
170
|
+
must be registered before DataNode construction.
|
|
173
171
|
|
|
174
172
|
Do not accept `test_node`. It has been removed. Use explicit
|
|
175
173
|
`hash_namespace(...)` or `hash_namespace="..."`.
|
|
@@ -302,30 +300,19 @@ changing it changes the dependency graph and update identity.
|
|
|
302
300
|
|
|
303
301
|
Do not construct dependency graphs dynamically inside `update()`.
|
|
304
302
|
|
|
305
|
-
### 8.
|
|
306
|
-
|
|
307
|
-
If the node emits `(time_index, unique_identifier)`:
|
|
308
|
-
|
|
309
|
-
- `unique_identifier` should represent an Asset identity
|
|
310
|
-
- asset scope should live in update configuration when it affects the updater
|
|
311
|
-
- `get_asset_list()` must reflect the effective updater asset scope when the
|
|
312
|
-
workflow uses that hook
|
|
313
|
-
- missing assets should be resolved or registered by the relevant workflow
|
|
314
|
-
|
|
315
|
-
### 9. Foreign Keys Belong To The Storage Contract
|
|
303
|
+
### 8. Foreign Keys Belong To The Storage Contract
|
|
316
304
|
|
|
317
305
|
For new code, model foreign keys on the `PlatformTimeIndexMetaData` storage
|
|
318
306
|
class or route the storage-contract work to the MetaTable skill.
|
|
319
307
|
|
|
320
308
|
Do not add DataNode configuration fields just to mutate storage metadata.
|
|
321
309
|
|
|
322
|
-
###
|
|
310
|
+
### 9. Metadata Belongs To Storage
|
|
323
311
|
|
|
324
312
|
Production-quality table identifiers, descriptions, labels, column docs, and
|
|
325
313
|
foreign-key metadata belong to the storage class/MetaTable registration path.
|
|
326
314
|
|
|
327
|
-
Do not
|
|
328
|
-
surface for new DataNode work.
|
|
315
|
+
Do not put schema or published table metadata on the DataNode configuration.
|
|
329
316
|
|
|
330
317
|
## Review Rules
|
|
331
318
|
|
|
@@ -333,7 +320,7 @@ When reviewing an existing DataNode, look for:
|
|
|
333
320
|
|
|
334
321
|
- output storage contract hidden in `DataNodeConfiguration`
|
|
335
322
|
- dependency storage table passed as an ad hoc constructor argument
|
|
336
|
-
-
|
|
323
|
+
- schema or published table metadata hidden in DataNode configuration
|
|
337
324
|
- `update_only`, `runtime_only`, or `ignore_from_storage_hash`
|
|
338
325
|
- `test_node=True`
|
|
339
326
|
- missing explicit `storage_table`
|
|
@@ -342,7 +329,7 @@ When reviewing an existing DataNode, look for:
|
|
|
342
329
|
- misuse of `hash_namespace`
|
|
343
330
|
- non-incremental `update()` behavior
|
|
344
331
|
- hidden dependency creation inside `update()`
|
|
345
|
-
- invalid
|
|
332
|
+
- invalid identity-indexed output shape
|
|
346
333
|
- `time_index` dtype that is not exactly `datetime64[ns, UTC]`
|
|
347
334
|
- DataFrame columns that do not match the `PlatformTimeIndexMetaData` class
|
|
348
335
|
|
|
@@ -351,9 +338,9 @@ When reviewing an existing DataNode, look for:
|
|
|
351
338
|
Do not claim success until you have checked:
|
|
352
339
|
|
|
353
340
|
- the relevant docs were read first
|
|
354
|
-
- storage is a registered
|
|
341
|
+
- storage is a registered `PlatformTimeIndexMetaData` class
|
|
355
342
|
- the DataNode constructor requires `storage_table`
|
|
356
|
-
- dependency storage-table references live in config and are registered
|
|
343
|
+
- dependency storage-table references live in config and are registered
|
|
357
344
|
- config fields are updater-scoped by default
|
|
358
345
|
- no removed hash metadata markers remain
|
|
359
346
|
- no `test_node` usage remains
|
|
@@ -363,17 +350,11 @@ Do not claim success until you have checked:
|
|
|
363
350
|
- non-empty outputs have first index level `time_index` with dtype `datetime64[ns, UTC]`
|
|
364
351
|
- the first validation run uses explicit `hash_namespace(...)` when it touches a shared backend
|
|
365
352
|
|
|
366
|
-
For asset-scoped updates, also check:
|
|
367
|
-
|
|
368
|
-
- `get_asset_list()` is correct when used
|
|
369
|
-
- no duplicate `(time_index, unique_identifier)` rows are emitted
|
|
370
|
-
- assets exist or are registered idempotently when needed
|
|
371
|
-
|
|
372
353
|
## This Skill Must Stop And Escalate When
|
|
373
354
|
|
|
374
355
|
- the change may break an existing published table contract and the versioning decision is unclear
|
|
375
356
|
- the intended storage class or MetaTable registration path is unclear
|
|
376
|
-
- the node needs
|
|
357
|
+
- the node needs identity dimensions but the coordinate strategy is unclear
|
|
377
358
|
- the task is actually an API, MetaTable, orchestration, or sharing problem
|
|
378
359
|
- docs, skill instructions, and code disagree on hashing or runtime behavior
|
|
379
360
|
|
|
@@ -6,8 +6,8 @@ description: Use this skill when a Main Sequence project needs financial markets
|
|
|
6
6
|
# Main Sequence ms-markets
|
|
7
7
|
|
|
8
8
|
`ms-markets` is the Main Sequence supported library for financial markets workflows.
|
|
9
|
-
Use it for market assets, market MetaTables,
|
|
10
|
-
|
|
9
|
+
Use it for market assets, market MetaTables, portfolios, orders, trades, and
|
|
10
|
+
related market-domain APIs.
|
|
11
11
|
|
|
12
12
|
This SDK scaffold skill is intentionally tiny. It does not own market-domain
|
|
13
13
|
implementation rules. Install `ms-markets` and copy its packaged skills into the
|
|
@@ -5136,7 +5136,7 @@ def list_project_job_runs(
|
|
|
5136
5136
|
|
|
5137
5137
|
|
|
5138
5138
|
def get_project_job_run_logs(
|
|
5139
|
-
|
|
5139
|
+
job_run_uid: str,
|
|
5140
5140
|
*,
|
|
5141
5141
|
timeout: int | None = None,
|
|
5142
5142
|
) -> dict[str, Any]:
|
|
@@ -5191,20 +5191,20 @@ def get_project_job_run_logs(
|
|
|
5191
5191
|
BaseObjectOrm.ROOT_URL = root_url
|
|
5192
5192
|
ClientJobRun.ROOT_URL = root_url
|
|
5193
5193
|
|
|
5194
|
-
job_run = ClientJobRun.get(pk=
|
|
5194
|
+
job_run = ClientJobRun.get(pk=job_run_uid, timeout=timeout)
|
|
5195
5195
|
payload = job_run.get_logs(timeout=timeout)
|
|
5196
5196
|
if isinstance(payload, dict):
|
|
5197
5197
|
return payload
|
|
5198
5198
|
if hasattr(payload, "model_dump"):
|
|
5199
5199
|
return payload.model_dump()
|
|
5200
|
-
return {"
|
|
5200
|
+
return {"job_run_uid": job_run_uid, "rows": []}
|
|
5201
5201
|
|
|
5202
5202
|
except Exception as e:
|
|
5203
5203
|
err_name = type(e).__name__
|
|
5204
5204
|
if err_name in {"AuthenticationError", "PermissionDeniedError"}:
|
|
5205
5205
|
raise NotLoggedIn(str(e) or "Not logged in.") from e
|
|
5206
5206
|
if err_name == "NotFoundError":
|
|
5207
|
-
raise ApiError(f"Job run not found: {
|
|
5207
|
+
raise ApiError(f"Job run not found: {job_run_uid}") from e
|
|
5208
5208
|
raise ApiError(f"Project job run logs fetch failed: {e}") from e
|
|
5209
5209
|
finally:
|
|
5210
5210
|
if client_utils is not None:
|
|
@@ -45,7 +45,7 @@ import click
|
|
|
45
45
|
import typer
|
|
46
46
|
import yaml
|
|
47
47
|
|
|
48
|
-
from ..compute_validation import decimal_to_storage, parse_cpu_request, parse_memory_request
|
|
48
|
+
from ..client.compute_validation import decimal_to_storage, parse_cpu_request, parse_memory_request
|
|
49
49
|
from . import config as cfg
|
|
50
50
|
from .api import (
|
|
51
51
|
ApiError,
|
|
@@ -10196,7 +10196,7 @@ def project_jobs_run_cmd(
|
|
|
10196
10196
|
if payload:
|
|
10197
10197
|
preferred_keys = [
|
|
10198
10198
|
("Job ID", str(payload.get("job") or payload.get("job_id") or job_id)),
|
|
10199
|
-
("Job Run
|
|
10199
|
+
("Job Run UID", str(payload.get("uid") or payload.get("job_run_uid") or "-")),
|
|
10200
10200
|
("Name", str(payload.get("name") or payload.get("job_name") or "-")),
|
|
10201
10201
|
("Unique Identifier", str(payload.get("unique_identifier") or "-")),
|
|
10202
10202
|
("Status", str(payload.get("status") or "-")),
|
|
@@ -10208,7 +10208,8 @@ def project_jobs_run_cmd(
|
|
|
10208
10208
|
"job",
|
|
10209
10209
|
"job_id",
|
|
10210
10210
|
"id",
|
|
10211
|
-
"
|
|
10211
|
+
"uid",
|
|
10212
|
+
"job_run_uid",
|
|
10212
10213
|
"name",
|
|
10213
10214
|
"job_name",
|
|
10214
10215
|
"unique_identifier",
|
|
@@ -10254,8 +10255,8 @@ def project_job_runs_list_cmd(
|
|
|
10254
10255
|
|
|
10255
10256
|
@project_job_runs_group.command("logs")
|
|
10256
10257
|
def project_job_runs_logs_cmd(
|
|
10257
|
-
|
|
10258
|
-
JOB_RUN_MODEL_REF, "
|
|
10258
|
+
job_run_uid: str = pydantic_argument(
|
|
10259
|
+
JOB_RUN_MODEL_REF, "uid", ..., help="Job run UID whose logs will be shown."
|
|
10259
10260
|
),
|
|
10260
10261
|
poll_interval: int = typer.Option(
|
|
10261
10262
|
30,
|
|
@@ -10279,10 +10280,10 @@ def project_job_runs_logs_cmd(
|
|
|
10279
10280
|
Examples
|
|
10280
10281
|
--------
|
|
10281
10282
|
```bash
|
|
10282
|
-
mainsequence project jobs runs logs
|
|
10283
|
-
mainsequence project jobs runs logs
|
|
10284
|
-
mainsequence project jobs runs logs
|
|
10285
|
-
mainsequence project jobs runs logs
|
|
10283
|
+
mainsequence project jobs runs logs 4c1d77c8-8a42-42b8-a9c1-06be9a336e5d
|
|
10284
|
+
mainsequence project jobs runs logs 4c1d77c8-8a42-42b8-a9c1-06be9a336e5d --poll-interval 10
|
|
10285
|
+
mainsequence project jobs runs logs 4c1d77c8-8a42-42b8-a9c1-06be9a336e5d --max-wait-seconds 900
|
|
10286
|
+
mainsequence project jobs runs logs 4c1d77c8-8a42-42b8-a9c1-06be9a336e5d --poll-interval 0
|
|
10286
10287
|
```
|
|
10287
10288
|
"""
|
|
10288
10289
|
_require_login()
|
|
@@ -10296,7 +10297,7 @@ def project_job_runs_logs_cmd(
|
|
|
10296
10297
|
|
|
10297
10298
|
while True:
|
|
10298
10299
|
try:
|
|
10299
|
-
payload = get_project_job_run_logs(
|
|
10300
|
+
payload = get_project_job_run_logs(job_run_uid=job_run_uid, timeout=timeout)
|
|
10300
10301
|
except ApiError as e:
|
|
10301
10302
|
error(f"Project job run logs fetch failed: {e}")
|
|
10302
10303
|
raise typer.Exit(1) from e
|
|
@@ -10313,7 +10314,7 @@ def project_job_runs_logs_cmd(
|
|
|
10313
10314
|
print_kv(
|
|
10314
10315
|
"Job Run Logs",
|
|
10315
10316
|
[
|
|
10316
|
-
("Job Run
|
|
10317
|
+
("Job Run UID", str(payload.get("job_run_uid") or payload.get("uid") or job_run_uid)),
|
|
10317
10318
|
("Status", status_value),
|
|
10318
10319
|
],
|
|
10319
10320
|
)
|
|
@@ -84,7 +84,6 @@ class BaseObjectOrm:
|
|
|
84
84
|
"MultiIndexMetadata": "orm/multi_index_metadata",
|
|
85
85
|
"ContinuousAggMultiIndex": "ts_manager/cont_agg_multi_ind",
|
|
86
86
|
"TimeIndexMetaData": "ts_manager/dynamic_table",
|
|
87
|
-
# "LocalTimeSerieNodesMethods": "ogm/local_time_serie",
|
|
88
87
|
"LocalTimeSerieNodesMethods": "ts_manager/local_time_serie",
|
|
89
88
|
"DataNodeUpdate": "ts_manager/local_time_serie",
|
|
90
89
|
"DataNodeUpdateDetails": "ts_manager/local_time_serie_update_details",
|
{mainsequence-4.1.4/mainsequence → mainsequence-4.1.6/mainsequence/client}/compute_validation.py
RENAMED
|
@@ -114,7 +114,9 @@ def parse_gpu_request(value: Any, *, field_name: str = "gpu_request") -> int | N
|
|
|
114
114
|
raise ValueError(f"{field_name} must be a valid integer.") from exc
|
|
115
115
|
|
|
116
116
|
|
|
117
|
-
def format_cpu_request(
|
|
117
|
+
def format_cpu_request(
|
|
118
|
+
value: Decimal | None, *, output_format: Literal["decimal", "k8s"] = "decimal"
|
|
119
|
+
) -> str | None:
|
|
118
120
|
if value is None:
|
|
119
121
|
return None
|
|
120
122
|
if output_format == "decimal":
|
|
@@ -129,7 +131,9 @@ def format_cpu_request(value: Decimal | None, *, output_format: Literal["decimal
|
|
|
129
131
|
return decimal_to_storage(value)
|
|
130
132
|
|
|
131
133
|
|
|
132
|
-
def format_memory_request(
|
|
134
|
+
def format_memory_request(
|
|
135
|
+
value: Decimal | None, *, output_format: Literal["decimal", "k8s"] = "decimal"
|
|
136
|
+
) -> str | None:
|
|
133
137
|
if value is None:
|
|
134
138
|
return None
|
|
135
139
|
if output_format == "decimal":
|
{mainsequence-4.1.4 → mainsequence-4.1.6}/mainsequence/client/data_sources_interfaces/duckdb.py
RENAMED
|
@@ -23,6 +23,7 @@ from ..dtype_codec import (
|
|
|
23
23
|
token_to_pandas_series,
|
|
24
24
|
)
|
|
25
25
|
from ..utils import DataFrequency
|
|
26
|
+
from .local_paths import local_data_path
|
|
26
27
|
|
|
27
28
|
|
|
28
29
|
def get_logger():
|
|
@@ -53,12 +54,10 @@ class DuckDBInterface:
|
|
|
53
54
|
environment variable or 'analytics.duckdb'
|
|
54
55
|
in the current directory if the variable is not set.
|
|
55
56
|
"""
|
|
56
|
-
from mainsequence.meta_tables.config import META_TABLES_DATA_PATH
|
|
57
|
-
|
|
58
57
|
# ── choose default & normalise to string ───────────────────────────
|
|
59
58
|
default_path = os.getenv(
|
|
60
59
|
"DUCKDB_PATH",
|
|
61
|
-
os.
|
|
60
|
+
os.fspath(local_data_path() / "duck_db"),
|
|
62
61
|
)
|
|
63
62
|
db_uri = str(db_path or default_path).rstrip("/")
|
|
64
63
|
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def local_data_path() -> Path:
|
|
8
|
+
configured = (os.getenv("MAINSEQUENCE_LOCAL_DATA_PATH") or "").strip()
|
|
9
|
+
if configured:
|
|
10
|
+
return Path(configured).expanduser()
|
|
11
|
+
return Path.home() / "meta_tables" / "data"
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
__all__ = ["local_data_path"]
|
{mainsequence-4.1.4 → mainsequence-4.1.6}/mainsequence/client/data_sources_interfaces/sqlite.py
RENAMED
|
@@ -16,6 +16,7 @@ from ..dtype_codec import (
|
|
|
16
16
|
token_to_backend_type,
|
|
17
17
|
token_to_pandas_series,
|
|
18
18
|
)
|
|
19
|
+
from .local_paths import local_data_path
|
|
19
20
|
|
|
20
21
|
|
|
21
22
|
def get_logger():
|
|
@@ -32,11 +33,9 @@ class SQLiteInterface:
|
|
|
32
33
|
"""
|
|
33
34
|
|
|
34
35
|
def __init__(self, db_path: str | Path | None = None):
|
|
35
|
-
from mainsequence.meta_tables.config import META_TABLES_DATA_PATH
|
|
36
|
-
|
|
37
36
|
default_path = os.getenv(
|
|
38
37
|
"SQLITE_PATH",
|
|
39
|
-
os.
|
|
38
|
+
os.fspath(local_data_path() / "sqlite"),
|
|
40
39
|
)
|
|
41
40
|
raw_path = Path(str(db_path or default_path)).expanduser()
|
|
42
41
|
if raw_path.suffix in {".db", ".sqlite", ".sqlite3"}:
|
|
@@ -760,10 +760,11 @@ def add_created_object_to_jobrun(
|
|
|
760
760
|
Returns:
|
|
761
761
|
A dictionary representing the created record.
|
|
762
762
|
"""
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
763
|
+
job_run_uid = (os.getenv("JOB_RUN_UID") or "").strip()
|
|
764
|
+
if not job_run_uid:
|
|
765
|
+
raise RuntimeError("JOB_RUN_UID is required to attach created objects to a job run.")
|
|
766
|
+
|
|
767
|
+
url = MAINSEQUENCE_ENDPOINT + f"/orm/api/pods/job-run/{job_run_uid}/add_created_object/"
|
|
767
768
|
payload = {"json": {"app_label": app_label, "model_name": model_name, "object_id": object_id}}
|
|
768
769
|
|
|
769
770
|
r = make_request(
|
|
@@ -13,12 +13,12 @@ from uuid import UUID
|
|
|
13
13
|
import yaml
|
|
14
14
|
from pydantic import BaseModel, Field, PositiveInt
|
|
15
15
|
|
|
16
|
-
from
|
|
16
|
+
from .base import BaseObjectOrm, BasePydanticModel, ShareableObjectMixin
|
|
17
|
+
from .compute_validation import (
|
|
17
18
|
decimal_to_storage,
|
|
18
19
|
normalize_string,
|
|
19
20
|
validate_and_normalize_compute_fields,
|
|
20
21
|
)
|
|
21
|
-
from .base import BaseObjectOrm, BasePydanticModel, ShareableObjectMixin
|
|
22
22
|
from .exceptions import raise_for_response
|
|
23
23
|
from .models_foundry import (
|
|
24
24
|
Project,
|
|
@@ -71,7 +71,7 @@ class CustomConsoleRenderer(ConsoleRenderer):
|
|
|
71
71
|
|
|
72
72
|
def _request_job_startup_state(*, timeout_s: float = 10.0) -> dict[str, Any]:
|
|
73
73
|
"""
|
|
74
|
-
Fetch startup state from backend using current env vars (JWT auth, endpoint,
|
|
74
|
+
Fetch startup state from backend using current env vars (JWT auth, endpoint, job_run_uid).
|
|
75
75
|
Safe to call later after auth when access/refresh tokens become available.
|
|
76
76
|
"""
|
|
77
77
|
if not is_running_in_pod():
|
|
@@ -183,16 +183,12 @@ def _request_job_startup_state(*, timeout_s: float = 10.0) -> dict[str, Any]:
|
|
|
183
183
|
|
|
184
184
|
headers, using_jwt = _auth_headers()
|
|
185
185
|
|
|
186
|
-
|
|
187
|
-
if not
|
|
186
|
+
job_run_uid = (os.getenv("JOB_RUN_UID") or "").strip()
|
|
187
|
+
if not job_run_uid:
|
|
188
188
|
return {}
|
|
189
189
|
|
|
190
|
-
endpoint = f"{_backend_base_url()}/orm/api/pods/job-run/{
|
|
191
|
-
|
|
192
|
-
command_id = os.getenv("COMMAND_ID")
|
|
190
|
+
endpoint = f"{_backend_base_url()}/orm/api/pods/job-run/{job_run_uid}/startup-state/"
|
|
193
191
|
params: dict[str, Any] = {}
|
|
194
|
-
if command_id:
|
|
195
|
-
params["command_id"] = command_id
|
|
196
192
|
|
|
197
193
|
resp = requests.get(endpoint, headers=headers, params=params, timeout=timeout_s)
|
|
198
194
|
if resp.status_code in {401, 403} and using_jwt and _refresh_access_token():
|
|
@@ -225,8 +221,6 @@ def _apply_additional_environment(startup_state: Mapping[str, Any]) -> None:
|
|
|
225
221
|
|
|
226
222
|
def _build_backend_bindings(
|
|
227
223
|
startup_state: Mapping[str, Any],
|
|
228
|
-
*,
|
|
229
|
-
command_id: str | None = None,
|
|
230
224
|
) -> dict[str, Any]:
|
|
231
225
|
"""
|
|
232
226
|
Pure function: compute the keys you want to bind on the logger
|
|
@@ -242,15 +236,11 @@ def _build_backend_bindings(
|
|
|
242
236
|
if project_id is not None:
|
|
243
237
|
bindings["project_id"] = project_id
|
|
244
238
|
bindings["data_source_id"] = startup_state.get("data_source_id")
|
|
245
|
-
bindings["
|
|
246
|
-
|
|
247
|
-
if command_id is None:
|
|
248
|
-
command_id = os.getenv("COMMAND_ID")
|
|
249
|
-
bindings["command_id"] = int(command_id) if command_id else None
|
|
239
|
+
bindings["job_run_uid"] = startup_state.get("job_run_uid")
|
|
240
|
+
bindings["command_id"] = startup_state.get("command_id")
|
|
250
241
|
else:
|
|
251
|
-
# your existing behavior: bind job_run_id to user_id in local-ish mode
|
|
252
242
|
if "user_id" in startup_state:
|
|
253
|
-
bindings["
|
|
243
|
+
bindings["user_id"] = startup_state.get("user_id")
|
|
254
244
|
else:
|
|
255
245
|
bindings["local_mode"] = "no_app"
|
|
256
246
|
|
|
@@ -276,14 +266,12 @@ def _bind_runtime(logger_: BoundLogger, **bindings: Any) -> BoundLogger:
|
|
|
276
266
|
def apply_startup_state_bindings(
|
|
277
267
|
logger_: BoundLogger,
|
|
278
268
|
startup_state: Mapping[str, Any],
|
|
279
|
-
*,
|
|
280
|
-
command_id: str | None = None,
|
|
281
269
|
) -> BoundLogger:
|
|
282
270
|
"""
|
|
283
271
|
Apply env + bindings derived from startup_state to the given logger.
|
|
284
272
|
"""
|
|
285
273
|
_apply_additional_environment(startup_state)
|
|
286
|
-
binds = _build_backend_bindings(startup_state
|
|
274
|
+
binds = _build_backend_bindings(startup_state)
|
|
287
275
|
return _bind_runtime(logger_, **binds)
|
|
288
276
|
|
|
289
277
|
|
|
@@ -295,7 +283,6 @@ def build_application_logger(application_name: str = "ms-sdk", **metadata):
|
|
|
295
283
|
"""
|
|
296
284
|
|
|
297
285
|
# do initial request when on logger initialization
|
|
298
|
-
command_id = os.getenv("COMMAND_ID")
|
|
299
286
|
json_response = _request_job_startup_state()
|
|
300
287
|
|
|
301
288
|
# set additional args from backend
|
|
@@ -341,22 +328,22 @@ def build_application_logger(application_name: str = "ms-sdk", **metadata):
|
|
|
341
328
|
}
|
|
342
329
|
else:
|
|
343
330
|
handlers["console"] = {
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
331
|
+
"class": "logging.StreamHandler",
|
|
332
|
+
"formatter": "colored",
|
|
333
|
+
"level": os.getenv("LOG_LEVEL", "DEBUG"),
|
|
347
334
|
}
|
|
348
335
|
|
|
349
336
|
if logger_file is not None:
|
|
350
337
|
ensure_dir(logger_file) # Ensure the directory for the log file exists
|
|
351
338
|
handlers["file"] = {
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
339
|
+
"class": "concurrent_log_handler.ConcurrentRotatingFileHandler",
|
|
340
|
+
"formatter": "plain",
|
|
341
|
+
"level": os.getenv("LOG_LEVEL_FILE", "DEBUG"),
|
|
342
|
+
"filename": logger_file,
|
|
343
|
+
"mode": "a",
|
|
344
|
+
"delay": True,
|
|
345
|
+
"maxBytes": 5 * 1024 * 1024, # Rotate after 5 MB
|
|
346
|
+
"backupCount": 5, # Keep up to 5 backup files
|
|
360
347
|
}
|
|
361
348
|
|
|
362
349
|
logging_config = {
|
|
@@ -421,20 +408,17 @@ def build_application_logger(application_name: str = "ms-sdk", **metadata):
|
|
|
421
408
|
)
|
|
422
409
|
|
|
423
410
|
try:
|
|
424
|
-
|
|
425
|
-
backend_binds = _build_backend_bindings(json_response, command_id=command_id)
|
|
411
|
+
backend_binds = _build_backend_bindings(json_response)
|
|
426
412
|
logger = _bind_runtime(logger, **backend_binds)
|
|
427
413
|
|
|
428
|
-
|
|
429
|
-
|
|
430
414
|
except Exception:
|
|
431
|
-
|
|
432
415
|
logger.exception("Logger could not be binded running in local mode")
|
|
433
416
|
logger = logger.bind(local_mode="no_app", **metadata)
|
|
434
417
|
|
|
435
418
|
logger = logger.bind()
|
|
436
419
|
return logger
|
|
437
420
|
|
|
421
|
+
|
|
438
422
|
def refresh_application_logger_bindings(*, timeout_s: float = 10.0) -> BoundLogger:
|
|
439
423
|
"""
|
|
440
424
|
Importable helper: call this AFTER the user authenticates / token exists.
|
|
@@ -442,13 +426,12 @@ def refresh_application_logger_bindings(*, timeout_s: float = 10.0) -> BoundLogg
|
|
|
442
426
|
"""
|
|
443
427
|
global logger
|
|
444
428
|
|
|
445
|
-
command_id = os.getenv("COMMAND_ID")
|
|
446
429
|
json_response = _request_job_startup_state(timeout_s=timeout_s)
|
|
447
430
|
|
|
448
431
|
# set additional args from backend
|
|
449
432
|
_apply_additional_environment(json_response)
|
|
450
433
|
|
|
451
|
-
backend_binds = _build_backend_bindings(json_response
|
|
434
|
+
backend_binds = _build_backend_bindings(json_response)
|
|
452
435
|
|
|
453
436
|
# if somebody calls this super early
|
|
454
437
|
if logger is None:
|
|
@@ -458,6 +441,7 @@ def refresh_application_logger_bindings(*, timeout_s: float = 10.0) -> BoundLogg
|
|
|
458
441
|
logger = _bind_runtime(logger, **backend_binds)
|
|
459
442
|
return logger
|
|
460
443
|
|
|
444
|
+
|
|
461
445
|
def dump_structlog_bound_logger(logger: BoundLogger) -> dict[str, Any]:
|
|
462
446
|
"""
|
|
463
447
|
Serialize a fully‑initialized structlog BoundLogger into a dict:
|
|
@@ -5,10 +5,6 @@ from importlib import import_module
|
|
|
5
5
|
from mainsequence.instrumentation import TracerInstrumentator
|
|
6
6
|
|
|
7
7
|
_LAZY_IMPORTS = {
|
|
8
|
-
"TIME_SERIES_SOURCE_TIMESCALE": (".config", "TIME_SERIES_SOURCE_TIMESCALE"),
|
|
9
|
-
"RunningMode": (".config", "RunningMode"),
|
|
10
|
-
"configuration": (".config", "configuration"),
|
|
11
|
-
"ogm": (".config", "ogm"),
|
|
12
8
|
"DEFAULT_PLATFORM_MANAGED_PROVISIONING": (
|
|
13
9
|
".sqlalchemy_contracts",
|
|
14
10
|
"DEFAULT_PLATFORM_MANAGED_PROVISIONING",
|
|
@@ -20,16 +16,11 @@ _LAZY_IMPORTS = {
|
|
|
20
16
|
"APIDataNode": (".data_nodes", "APIDataNode"),
|
|
21
17
|
"DataNode": (".data_nodes", "DataNode"),
|
|
22
18
|
"DataNodeConfiguration": (".data_nodes", "DataNodeConfiguration"),
|
|
23
|
-
"build_compiled_sql_v1_operation": (
|
|
24
|
-
".compiled_sql",
|
|
25
|
-
"build_compiled_sql_v1_operation",
|
|
26
|
-
),
|
|
27
19
|
"build_meta_table_configured_storage_hash": (
|
|
28
20
|
".hashing",
|
|
29
21
|
"build_meta_table_configured_storage_hash",
|
|
30
22
|
),
|
|
31
23
|
"build_meta_table_storage_hash": (".hashing", "build_meta_table_storage_hash"),
|
|
32
|
-
"compile_sqlalchemy_statement": (".compiled_sql", "compile_sqlalchemy_statement"),
|
|
33
24
|
"external_registered_registration_request_from_sqlalchemy_model": (
|
|
34
25
|
".sqlalchemy_contracts",
|
|
35
26
|
"external_registered_registration_request_from_sqlalchemy_model",
|
|
@@ -17,7 +17,7 @@ from mainsequence.client.models_metatables import (
|
|
|
17
17
|
)
|
|
18
18
|
|
|
19
19
|
|
|
20
|
-
def
|
|
20
|
+
def build_operation(
|
|
21
21
|
*,
|
|
22
22
|
operation: MetaTableOperation,
|
|
23
23
|
sql: str,
|
|
@@ -115,7 +115,7 @@ def compile_sqlalchemy_statement(
|
|
|
115
115
|
for table in scope_tables
|
|
116
116
|
]
|
|
117
117
|
)
|
|
118
|
-
return
|
|
118
|
+
return build_operation(
|
|
119
119
|
operation=operation,
|
|
120
120
|
sql=str(compiled),
|
|
121
121
|
parameters=dict(compiled.params),
|
|
@@ -143,6 +143,6 @@ def _compiled_sqlalchemy_parameter_types(compiled: Any) -> dict[str, str]:
|
|
|
143
143
|
|
|
144
144
|
|
|
145
145
|
__all__ = [
|
|
146
|
-
"
|
|
146
|
+
"build_operation",
|
|
147
147
|
"compile_sqlalchemy_statement",
|
|
148
148
|
]
|
{mainsequence-4.1.4 → mainsequence-4.1.6}/mainsequence/meta_tables/data_nodes/build_operations.py
RENAMED
|
@@ -96,7 +96,7 @@ def _(value: type[Any]) -> Any:
|
|
|
96
96
|
uid = getattr(time_index_metadata, "uid", None)
|
|
97
97
|
if uid in (None, ""):
|
|
98
98
|
raise ValueError(
|
|
99
|
-
"PlatformTimeIndexMetaData config values must be registered
|
|
99
|
+
"PlatformTimeIndexMetaData config values must be registered "
|
|
100
100
|
"before they can be hashed."
|
|
101
101
|
)
|
|
102
102
|
return {
|
|
@@ -647,7 +647,7 @@ class DataNode(DataAccessMixin, ABC):
|
|
|
647
647
|
)
|
|
648
648
|
if value.get_time_index_metadata() is None:
|
|
649
649
|
raise ValueError(
|
|
650
|
-
"DataNode storage_table must be registered
|
|
650
|
+
"DataNode storage_table must be registered before construction."
|
|
651
651
|
)
|
|
652
652
|
if value.get_meta_table_uid() in (None, ""):
|
|
653
653
|
raise ValueError("DataNode storage_table must provide a MetaTable UID.")
|
|
@@ -659,7 +659,7 @@ class DataNode(DataAccessMixin, ABC):
|
|
|
659
659
|
def storage_metadata(self) -> Any:
|
|
660
660
|
storage_metadata = self.storage_table.get_time_index_metadata()
|
|
661
661
|
if storage_metadata is None:
|
|
662
|
-
raise ValueError("DataNode storage_table must be registered
|
|
662
|
+
raise ValueError("DataNode storage_table must be registered before use.")
|
|
663
663
|
return storage_metadata
|
|
664
664
|
|
|
665
665
|
def _initialize_configuration(self, init_kwargs: dict) -> None:
|