mainsequence 4.2.1__tar.gz → 4.2.2__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.2.1/mainsequence.egg-info → mainsequence-4.2.2}/PKG-INFO +1 -1
- {mainsequence-4.2.1 → mainsequence-4.2.2}/agent_scaffold/skills/data_publishing/meta_tables/SKILL.md +23 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/mainsequence/client/metatables/core.py +19 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/mainsequence/meta_tables/data_nodes/persist_managers.py +7 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/mainsequence/meta_tables/migrations.py +75 -11
- {mainsequence-4.2.1 → mainsequence-4.2.2}/mainsequence/meta_tables/sqlalchemy_contracts.py +40 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2/mainsequence.egg-info}/PKG-INFO +1 -1
- {mainsequence-4.2.1 → mainsequence-4.2.2}/pyproject.toml +1 -1
- {mainsequence-4.2.1 → mainsequence-4.2.2}/tests/test_meta_table_migrations.py +74 -3
- {mainsequence-4.2.1 → mainsequence-4.2.2}/tests/test_meta_tables_sqlalchemy_contracts.py +52 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/tests/test_run_configuration.py +6 -2
- {mainsequence-4.2.1 → mainsequence-4.2.2}/LICENSE +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/README.md +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/agent_scaffold/AGENTS.md +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/agent_scaffold/skills/a2a_communication/SKILL.md +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/agent_scaffold/skills/application_surfaces/api_surfaces/SKILL.md +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/agent_scaffold/skills/command_center/adapter_from_api/SKILL.md +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/agent_scaffold/skills/command_center/api_mock_prototyping/SKILL.md +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/agent_scaffold/skills/command_center/app_components/SKILL.md +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/agent_scaffold/skills/command_center/connections/SKILL.md +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/agent_scaffold/skills/command_center/workspace_analysis/SKILL.md +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/agent_scaffold/skills/command_center/workspace_builder/SKILL.md +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/agent_scaffold/skills/command_center/workspace_design/SKILL.md +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/agent_scaffold/skills/dashboards/streamlit/SKILL.md +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/agent_scaffold/skills/data_access/exploration/SKILL.md +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/agent_scaffold/skills/data_publishing/data_nodes/SKILL.md +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/agent_scaffold/skills/maintenance/bug_auditor/SKILL.md +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/agent_scaffold/skills/ms-markets/SKILL.md +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/agent_scaffold/skills/platform_operations/access_control_and_sharing/SKILL.md +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/agent_scaffold/skills/platform_operations/orchestration_and_releases/SKILL.md +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/agent_scaffold/skills/project_builder/SKILL.md +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/agent_scaffold/skills/project_to_agent/SKILL.md +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/mainsequence/__init__.py +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/mainsequence/__main__.py +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/mainsequence/bootstrap.py +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/mainsequence/cli/__init__.py +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/mainsequence/cli/api.py +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/mainsequence/cli/browser_auth.py +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/mainsequence/cli/cli.py +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/mainsequence/cli/config.py +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/mainsequence/cli/docker_utils.py +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/mainsequence/cli/doctor.py +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/mainsequence/cli/local_ops.py +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/mainsequence/cli/migrations.py +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/mainsequence/cli/model_filters.py +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/mainsequence/cli/project_status.py +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/mainsequence/cli/pydantic_cli.py +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/mainsequence/cli/sdk_utils.py +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/mainsequence/cli/ssh_utils.py +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/mainsequence/cli/ui.py +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/mainsequence/client/__init__.py +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/mainsequence/client/agent_runtime_models.py +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/mainsequence/client/base.py +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/mainsequence/client/client.py +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/mainsequence/client/command_center/__init__.py +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/mainsequence/client/command_center/app_component.py +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/mainsequence/client/command_center/connections.py +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/mainsequence/client/command_center/data_models.py +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/mainsequence/client/command_center/workspace.py +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/mainsequence/client/command_center/workspace_snapshot.py +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/mainsequence/client/compute_validation.py +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/mainsequence/client/data_sources_interfaces/__init__.py +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/mainsequence/client/data_sources_interfaces/duckdb.py +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/mainsequence/client/data_sources_interfaces/local_paths.py +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/mainsequence/client/data_sources_interfaces/sqlite.py +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/mainsequence/client/dtype_codec.py +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/mainsequence/client/exceptions.py +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/mainsequence/client/fastapi/__init__.py +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/mainsequence/client/fastapi/auth.py +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/mainsequence/client/metatables/__init__.py +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/mainsequence/client/metatables/migrations.py +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/mainsequence/client/models_foundry.py +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/mainsequence/client/models_helpers.py +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/mainsequence/client/models_user.py +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/mainsequence/client/utils.py +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/mainsequence/defaults.py +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/mainsequence/instrumentation/__init__.py +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/mainsequence/instrumentation/utils.py +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/mainsequence/logconf.py +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/mainsequence/meta_tables/__init__.py +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/mainsequence/meta_tables/__main__.py +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/mainsequence/meta_tables/compiled_sql/__init__.py +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/mainsequence/meta_tables/compiled_sql/v1.py +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/mainsequence/meta_tables/data_nodes/__init__.py +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/mainsequence/meta_tables/data_nodes/build_operations.py +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/mainsequence/meta_tables/data_nodes/data_nodes.py +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/mainsequence/meta_tables/data_nodes/models.py +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/mainsequence/meta_tables/data_nodes/namespacing.py +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/mainsequence/meta_tables/data_nodes/run_operations.py +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/mainsequence/meta_tables/data_nodes/utils.py +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/mainsequence/meta_tables/future_registry.py +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/mainsequence/meta_tables/hashing.py +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/mainsequence/meta_tables/pydantic_metadata.py +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/mainsequence/runtime_flags.py +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/mainsequence.egg-info/SOURCES.txt +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/mainsequence.egg-info/dependency_links.txt +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/mainsequence.egg-info/entry_points.txt +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/mainsequence.egg-info/requires.txt +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/mainsequence.egg-info/top_level.txt +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/setup.cfg +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/tests/test_auth_precedence.py +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/tests/test_build_operations_hashing.py +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/tests/test_cli.py +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/tests/test_cli_browser_auth.py +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/tests/test_cli_migrations.py +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/tests/test_client.py +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/tests/test_command_center_app_component_models.py +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/tests/test_command_center_data_models.py +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/tests/test_command_center_models.py +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/tests/test_data_access_mixin_dimension_audit.py +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/tests/test_data_node_storage_dimension_queries.py +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/tests/test_data_node_update_flow.py +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/tests/test_dependency_extras.py +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/tests/test_duckdb_interface_dimensions.py +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/tests/test_filter_normalization.py +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/tests/test_logconf.py +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/tests/test_meta_tables_client_models.py +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/tests/test_models_user_request_bound_auth.py +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/tests/test_pod_project_resolution.py +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/tests/test_project_batch_jobs_from_file.py +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/tests/test_secret_client_model.py +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/tests/test_source_table_configuration.py +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/tests/test_sqlite_interface_dimensions.py +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/tests/test_update_runner_uid_runtime.py +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/tests/test_update_statistics.py +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/tests/test_update_uid_guards.py +0 -0
- {mainsequence-4.2.1 → mainsequence-4.2.2}/tests/test_workspace_snapshot.py +0 -0
{mainsequence-4.2.1 → mainsequence-4.2.2}/agent_scaffold/skills/data_publishing/meta_tables/SKILL.md
RENAMED
|
@@ -95,6 +95,29 @@ For every non-trivial task, decide:
|
|
|
95
95
|
|
|
96
96
|
## Build Rules
|
|
97
97
|
|
|
98
|
+
### 0. Creation And Deletion Are SDK-Managed
|
|
99
|
+
|
|
100
|
+
Do not build custom migrations for creating or deleting MetaTables.
|
|
101
|
+
|
|
102
|
+
MetaTable creation and deletion are handled through `mainsequence-sdk` and the
|
|
103
|
+
Main Sequence CLI. Assistants should define the SQLAlchemy MetaTable model,
|
|
104
|
+
select the SDK migration provider when schema evolution is needed, and use the
|
|
105
|
+
documented `mainsequence migrations ...` commands.
|
|
106
|
+
|
|
107
|
+
Do not hand-author create/delete migration files, backend migration payloads,
|
|
108
|
+
manifest rows, registry rows, or low-level SDK migration requests for MetaTable
|
|
109
|
+
creation or deletion.
|
|
110
|
+
|
|
111
|
+
The only migration workflow to recommend is the Main Sequence CLI lifecycle:
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
mainsequence migrations current --provider mainsequence_migrations:migration
|
|
115
|
+
mainsequence migrations revision --provider mainsequence_migrations:migration
|
|
116
|
+
mainsequence migrations render --provider mainsequence_migrations:migration --to head
|
|
117
|
+
mainsequence migrations upgrade --provider mainsequence_migrations:migration --to head --dry-run
|
|
118
|
+
mainsequence migrations upgrade --provider mainsequence_migrations:migration --to head
|
|
119
|
+
```
|
|
120
|
+
|
|
98
121
|
### 1. SQLAlchemy metadata is the authoring source
|
|
99
122
|
|
|
100
123
|
Keep the application table model as the authoring source for the neutral table contract.
|
|
@@ -1102,6 +1102,25 @@ class MetaTable(BasePydanticModel, LabelableObjectMixin, ShareableObjectMixin, B
|
|
|
1102
1102
|
*,
|
|
1103
1103
|
timeout: int | float | tuple[float, float] | None = None,
|
|
1104
1104
|
) -> dict[str, Any]:
|
|
1105
|
+
"""
|
|
1106
|
+
Refresh this MetaTable's physical database shape snapshot.
|
|
1107
|
+
|
|
1108
|
+
This calls the backend ``POST /meta_table/<uid>/introspect/`` action.
|
|
1109
|
+
The backend reads the real physical table through the MetaTable's data
|
|
1110
|
+
source, reflects columns, indexes, and constraints, stores that data on
|
|
1111
|
+
``MetaTable.introspection_snapshot``, and returns the full response.
|
|
1112
|
+
|
|
1113
|
+
This method is intended for admin, debugging, and reconciliation
|
|
1114
|
+
workflows. Use it when a client needs to inspect what the database
|
|
1115
|
+
currently has, diagnose catalog/physical drift, or refresh metadata
|
|
1116
|
+
after an out-of-band DDL change. It is not required for normal reads,
|
|
1117
|
+
writes, registration, or migration-first application startup.
|
|
1118
|
+
|
|
1119
|
+
Returns:
|
|
1120
|
+
Backend response containing ``ok``, ``meta_table_uid``, and
|
|
1121
|
+
``introspection_snapshot``. When the snapshot is an object, this
|
|
1122
|
+
instance's ``introspection_snapshot`` attribute is updated in place.
|
|
1123
|
+
"""
|
|
1105
1124
|
response_json = self._post_detail_action("introspect", timeout=timeout)
|
|
1106
1125
|
snapshot = response_json.get("introspection_snapshot")
|
|
1107
1126
|
if isinstance(snapshot, dict):
|
{mainsequence-4.2.1 → mainsequence-4.2.2}/mainsequence/meta_tables/data_nodes/persist_managers.py
RENAMED
|
@@ -108,6 +108,13 @@ def ensure_registered_storage_table(
|
|
|
108
108
|
raise ValueError(
|
|
109
109
|
f"{context} storage_table is missing TimeIndexMetaData metadata."
|
|
110
110
|
)
|
|
111
|
+
from mainsequence.client.metatables import TimeIndexMetaData
|
|
112
|
+
|
|
113
|
+
if not isinstance(storage_metadata, TimeIndexMetaData):
|
|
114
|
+
raise TypeError(
|
|
115
|
+
f"{context} storage_table must bind TimeIndexMetaData metadata; "
|
|
116
|
+
f"got {type(storage_metadata).__name__}."
|
|
117
|
+
)
|
|
111
118
|
if storage_table.get_meta_table_uid() in (None, ""):
|
|
112
119
|
raise ValueError(f"{context} storage_table must provide a MetaTable UID.")
|
|
113
120
|
if storage_table.get_data_source_uid() in (None, ""):
|
|
@@ -18,10 +18,12 @@ from mainsequence.client.metatables import (
|
|
|
18
18
|
MetaTableContract,
|
|
19
19
|
MetaTablePhysicalContract,
|
|
20
20
|
MetaTableRegistrationRequest,
|
|
21
|
+
TimeIndexMetaData,
|
|
21
22
|
)
|
|
22
23
|
from mainsequence.meta_tables.hashing import build_meta_table_storage_hash
|
|
23
24
|
from mainsequence.meta_tables.sqlalchemy_contracts import (
|
|
24
25
|
PlatformManagedMetaTable,
|
|
26
|
+
PlatformTimeIndexMetaData,
|
|
25
27
|
_resolve_model_data_source_uid,
|
|
26
28
|
platform_managed_migration_registration_context,
|
|
27
29
|
resolve_metatable_identifier,
|
|
@@ -268,8 +270,8 @@ class AlembicMetaTableMigration:
|
|
|
268
270
|
timeout: int | float | tuple[float, float] | None = None,
|
|
269
271
|
) -> list[Any]:
|
|
270
272
|
registered: list[Any] = []
|
|
271
|
-
existing_meta_tables =
|
|
272
|
-
|
|
273
|
+
existing_meta_tables = _get_metatables_by_model_identifier(
|
|
274
|
+
self.metatable_models,
|
|
273
275
|
timeout=timeout,
|
|
274
276
|
)
|
|
275
277
|
with platform_managed_migration_registration_context():
|
|
@@ -298,8 +300,8 @@ class AlembicMetaTableMigration:
|
|
|
298
300
|
"""
|
|
299
301
|
|
|
300
302
|
resolved: list[Any] = []
|
|
301
|
-
existing_meta_tables =
|
|
302
|
-
|
|
303
|
+
existing_meta_tables = _get_metatables_by_model_identifier(
|
|
304
|
+
self.metatable_models,
|
|
303
305
|
timeout=timeout,
|
|
304
306
|
)
|
|
305
307
|
with platform_managed_migration_registration_context():
|
|
@@ -326,7 +328,7 @@ class AlembicMetaTableMigration:
|
|
|
326
328
|
existing_meta_table = (
|
|
327
329
|
existing_meta_tables_by_identifier.get(identifier)
|
|
328
330
|
if existing_meta_tables_by_identifier is not None
|
|
329
|
-
else
|
|
331
|
+
else _get_metatable_by_model_identifier(model, timeout=timeout)
|
|
330
332
|
)
|
|
331
333
|
if existing_meta_table is not None:
|
|
332
334
|
_bind_model_to_existing_metatable(model, existing_meta_table)
|
|
@@ -603,25 +605,77 @@ def _get_metatable_by_identifier(
|
|
|
603
605
|
identifier: str,
|
|
604
606
|
*,
|
|
605
607
|
timeout: int | float | tuple[float, float] | None = None,
|
|
608
|
+
meta_table_cls: type[Any] = MetaTable,
|
|
606
609
|
) -> MetaTable | None:
|
|
607
|
-
matches = _get_metatables_by_identifier(
|
|
610
|
+
matches = _get_metatables_by_identifier(
|
|
611
|
+
[identifier],
|
|
612
|
+
timeout=timeout,
|
|
613
|
+
meta_table_cls=meta_table_cls,
|
|
614
|
+
)
|
|
608
615
|
return matches.get(identifier)
|
|
609
616
|
|
|
610
617
|
|
|
618
|
+
def _get_metatable_by_model_identifier(
|
|
619
|
+
model: type[Any],
|
|
620
|
+
*,
|
|
621
|
+
timeout: int | float | tuple[float, float] | None = None,
|
|
622
|
+
) -> Any | None:
|
|
623
|
+
identifier = resolve_metatable_identifier(model)
|
|
624
|
+
return _get_metatable_by_identifier(
|
|
625
|
+
identifier,
|
|
626
|
+
timeout=timeout,
|
|
627
|
+
meta_table_cls=_metatable_resource_class_for_model(model),
|
|
628
|
+
)
|
|
629
|
+
|
|
630
|
+
|
|
631
|
+
def _get_metatables_by_model_identifier(
|
|
632
|
+
models: Sequence[type[Any]],
|
|
633
|
+
*,
|
|
634
|
+
timeout: int | float | tuple[float, float] | None = None,
|
|
635
|
+
) -> dict[str, Any]:
|
|
636
|
+
identifiers_by_resource: dict[type[Any], list[str]] = {}
|
|
637
|
+
for model in models:
|
|
638
|
+
identifiers_by_resource.setdefault(
|
|
639
|
+
_metatable_resource_class_for_model(model),
|
|
640
|
+
[],
|
|
641
|
+
).append(resolve_metatable_identifier(model))
|
|
642
|
+
|
|
643
|
+
resolved: dict[str, Any] = {}
|
|
644
|
+
for meta_table_cls, identifiers in identifiers_by_resource.items():
|
|
645
|
+
matches = _get_metatables_by_identifier(
|
|
646
|
+
identifiers,
|
|
647
|
+
timeout=timeout,
|
|
648
|
+
meta_table_cls=meta_table_cls,
|
|
649
|
+
)
|
|
650
|
+
duplicate_identifiers = set(resolved).intersection(matches)
|
|
651
|
+
if duplicate_identifiers:
|
|
652
|
+
duplicate_list = ", ".join(sorted(duplicate_identifiers))
|
|
653
|
+
raise ValueError(
|
|
654
|
+
"MetaTable identifiers are not globally unique across provider models: "
|
|
655
|
+
f"{duplicate_list}."
|
|
656
|
+
)
|
|
657
|
+
resolved.update(matches)
|
|
658
|
+
return resolved
|
|
659
|
+
|
|
660
|
+
|
|
611
661
|
def _get_metatables_by_identifier(
|
|
612
662
|
identifiers: Sequence[str],
|
|
613
663
|
*,
|
|
614
664
|
timeout: int | float | tuple[float, float] | None = None,
|
|
615
|
-
|
|
665
|
+
meta_table_cls: type[Any] = MetaTable,
|
|
666
|
+
) -> dict[str, Any]:
|
|
616
667
|
unique_identifiers = list(dict.fromkeys(str(identifier) for identifier in identifiers))
|
|
617
668
|
if not unique_identifiers:
|
|
618
669
|
return {}
|
|
619
670
|
|
|
620
|
-
|
|
671
|
+
filter_kwargs: dict[str, Any] = {"identifier__in": unique_identifiers}
|
|
672
|
+
if issubclass(meta_table_cls, TimeIndexMetaData):
|
|
673
|
+
filter_kwargs["include_relations_detail"] = True
|
|
674
|
+
matches = meta_table_cls.filter(timeout=timeout, **filter_kwargs)
|
|
621
675
|
if not matches:
|
|
622
676
|
return {}
|
|
623
677
|
|
|
624
|
-
matched_by_identifier: dict[str,
|
|
678
|
+
matched_by_identifier: dict[str, Any] = {}
|
|
625
679
|
for meta_table in matches:
|
|
626
680
|
identifier = _meta_table_identifier(meta_table)
|
|
627
681
|
if identifier is None:
|
|
@@ -629,8 +683,8 @@ def _get_metatables_by_identifier(
|
|
|
629
683
|
identifier = unique_identifiers[0]
|
|
630
684
|
else:
|
|
631
685
|
raise ValueError(
|
|
632
|
-
"Backend returned a
|
|
633
|
-
"migration provider models by identifier__in."
|
|
686
|
+
f"Backend returned a {meta_table_cls.__name__} row without identifier "
|
|
687
|
+
"while resolving migration provider models by identifier__in."
|
|
634
688
|
)
|
|
635
689
|
if identifier in matched_by_identifier:
|
|
636
690
|
raise ValueError(
|
|
@@ -651,6 +705,12 @@ def _meta_table_identifier(meta_table: Any) -> str | None:
|
|
|
651
705
|
return str(identifier)
|
|
652
706
|
|
|
653
707
|
|
|
708
|
+
def _metatable_resource_class_for_model(model: type[Any]) -> type[Any]:
|
|
709
|
+
if _is_platform_time_index_metatable_model(model):
|
|
710
|
+
return TimeIndexMetaData
|
|
711
|
+
return MetaTable
|
|
712
|
+
|
|
713
|
+
|
|
654
714
|
def _bind_model_to_existing_metatable(model: Any, meta_table: MetaTable) -> None:
|
|
655
715
|
bind = getattr(model, "_bind_meta_table", None)
|
|
656
716
|
if not callable(bind):
|
|
@@ -665,6 +725,10 @@ def _is_platform_managed_metatable_model(model: Any) -> bool:
|
|
|
665
725
|
return isinstance(model, type) and issubclass(model, PlatformManagedMetaTable)
|
|
666
726
|
|
|
667
727
|
|
|
728
|
+
def _is_platform_time_index_metatable_model(model: Any) -> bool:
|
|
729
|
+
return isinstance(model, type) and issubclass(model, PlatformTimeIndexMetaData)
|
|
730
|
+
|
|
731
|
+
|
|
668
732
|
__all__ = [
|
|
669
733
|
"AlembicMetaTableMigration",
|
|
670
734
|
"AlembicVersionMetaTable",
|
|
@@ -506,6 +506,10 @@ class PlatformTimeIndexMetaData(PlatformManagedMetaTable):
|
|
|
506
506
|
|
|
507
507
|
@classmethod
|
|
508
508
|
def _bind_meta_table(cls, meta_table: TimeIndexMetaData) -> TimeIndexMetaData:
|
|
509
|
+
from mainsequence.client.metatables import TimeIndexMetaData
|
|
510
|
+
|
|
511
|
+
if not isinstance(meta_table, TimeIndexMetaData):
|
|
512
|
+
meta_table = cls._resolve_time_index_metadata_for_bind(meta_table)
|
|
509
513
|
bound = super()._bind_meta_table(meta_table)
|
|
510
514
|
cls.__time_index_metadata__ = bound
|
|
511
515
|
return bound
|
|
@@ -514,6 +518,19 @@ class PlatformTimeIndexMetaData(PlatformManagedMetaTable):
|
|
|
514
518
|
def get_time_index_metadata(cls) -> TimeIndexMetaData | None:
|
|
515
519
|
return getattr(cls, "__time_index_metadata__", None)
|
|
516
520
|
|
|
521
|
+
@classmethod
|
|
522
|
+
def _resolve_time_index_metadata_for_bind(cls, meta_table: Any) -> TimeIndexMetaData:
|
|
523
|
+
from mainsequence.client.metatables import TimeIndexMetaData
|
|
524
|
+
|
|
525
|
+
meta_table_uid = _meta_table_uid(meta_table)
|
|
526
|
+
if meta_table_uid not in (None, "") and _meta_table_is_time_indexed(meta_table):
|
|
527
|
+
return TimeIndexMetaData.get_by_uid(str(meta_table_uid))
|
|
528
|
+
model_name = getattr(cls, "__qualname__", cls.__name__)
|
|
529
|
+
received_type = type(meta_table).__name__
|
|
530
|
+
raise TypeError(
|
|
531
|
+
f"{model_name} requires TimeIndexMetaData binding; got {received_type}."
|
|
532
|
+
)
|
|
533
|
+
|
|
517
534
|
@classmethod
|
|
518
535
|
def __table_cls__(cls, *args: Any, **kwargs: Any) -> Any:
|
|
519
536
|
if len(args) < 2:
|
|
@@ -1355,6 +1372,29 @@ def _meta_table_physical_table_name(meta_table: Any) -> str | None:
|
|
|
1355
1372
|
return str(physical_table_name)
|
|
1356
1373
|
|
|
1357
1374
|
|
|
1375
|
+
def _meta_table_is_time_indexed(meta_table: Any) -> bool:
|
|
1376
|
+
if isinstance(meta_table, Mapping):
|
|
1377
|
+
time_indexed = meta_table.get("time_indexed")
|
|
1378
|
+
table_kind = meta_table.get("table_kind")
|
|
1379
|
+
table_contract = meta_table.get("table_contract")
|
|
1380
|
+
time_indexed_profile = meta_table.get("time_indexed_profile")
|
|
1381
|
+
else:
|
|
1382
|
+
time_indexed = getattr(meta_table, "time_indexed", None)
|
|
1383
|
+
table_kind = getattr(meta_table, "table_kind", None)
|
|
1384
|
+
table_contract = getattr(meta_table, "table_contract", None)
|
|
1385
|
+
time_indexed_profile = getattr(meta_table, "time_indexed_profile", None)
|
|
1386
|
+
|
|
1387
|
+
if time_indexed is True or table_kind == "time_indexed" or time_indexed_profile is not None:
|
|
1388
|
+
return True
|
|
1389
|
+
if isinstance(table_contract, Mapping):
|
|
1390
|
+
return (
|
|
1391
|
+
table_contract.get("table_kind") == "time_indexed"
|
|
1392
|
+
or table_contract.get("dynamic_table") is not None
|
|
1393
|
+
or table_contract.get("time_indexed") is not None
|
|
1394
|
+
)
|
|
1395
|
+
return False
|
|
1396
|
+
|
|
1397
|
+
|
|
1358
1398
|
def _model_bound_storage_hash(model_or_table: Any) -> str | None:
|
|
1359
1399
|
storage_hash = getattr(model_or_table, "__metatable_storage_hash__", None)
|
|
1360
1400
|
if storage_hash not in (None, ""):
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
+
import datetime
|
|
3
4
|
import importlib
|
|
4
5
|
import textwrap
|
|
5
6
|
import types
|
|
6
7
|
import uuid
|
|
7
8
|
|
|
8
9
|
import pytest
|
|
9
|
-
from sqlalchemy import Column, Integer, MetaData, Table, Uuid
|
|
10
|
+
from sqlalchemy import Column, DateTime, Integer, MetaData, String, Table, Uuid
|
|
10
11
|
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column
|
|
11
12
|
|
|
12
|
-
from mainsequence.client.metatables import MetaTable
|
|
13
|
-
from mainsequence.meta_tables import PlatformManagedMetaTable
|
|
13
|
+
from mainsequence.client.metatables import MetaTable, TimeIndexMetaData
|
|
14
|
+
from mainsequence.meta_tables import PlatformManagedMetaTable, PlatformTimeIndexMetaData
|
|
14
15
|
from mainsequence.meta_tables.migrations import (
|
|
15
16
|
DEFAULT_ALEMBIC_VERSION_COLUMN_NAME,
|
|
16
17
|
DEFAULT_ALEMBIC_VERSION_IDENTIFIER,
|
|
@@ -404,6 +405,76 @@ def test_alembic_metatable_migration_bulk_resolves_existing_models(monkeypatch):
|
|
|
404
405
|
assert Account.get_meta_table_uid() == "account-meta-table-uid"
|
|
405
406
|
|
|
406
407
|
|
|
408
|
+
def test_alembic_metatable_migration_bulk_resolves_time_index_models_with_dynamic_client(
|
|
409
|
+
monkeypatch,
|
|
410
|
+
):
|
|
411
|
+
class Base(DeclarativeBase):
|
|
412
|
+
metadata = MetaData()
|
|
413
|
+
|
|
414
|
+
class ProjectAlembicVersion(AlembicVersionMetaTable):
|
|
415
|
+
__metatable_data_source_uid__ = "data-source-uid"
|
|
416
|
+
|
|
417
|
+
class AccountHoldings(PlatformTimeIndexMetaData, Base):
|
|
418
|
+
__metatable_namespace__ = "markets"
|
|
419
|
+
__metatable_identifier__ = "markets.AccountHoldings"
|
|
420
|
+
__metatable_data_source_uid__ = "data-source-uid"
|
|
421
|
+
__time_index_name__ = "time_index"
|
|
422
|
+
__index_names__ = ["time_index", "unique_identifier"]
|
|
423
|
+
|
|
424
|
+
time_index: Mapped[datetime.datetime] = mapped_column(
|
|
425
|
+
DateTime(timezone=True),
|
|
426
|
+
nullable=False,
|
|
427
|
+
)
|
|
428
|
+
unique_identifier: Mapped[str] = mapped_column(String(255), nullable=False)
|
|
429
|
+
|
|
430
|
+
migration = AlembicMetaTableMigration(
|
|
431
|
+
package="msm",
|
|
432
|
+
migration_namespace="markets",
|
|
433
|
+
script_location="msm:alembic",
|
|
434
|
+
target_metadata=Base.metadata,
|
|
435
|
+
alembic_registry=ProjectAlembicVersion,
|
|
436
|
+
metatable_models=[AccountHoldings],
|
|
437
|
+
)
|
|
438
|
+
|
|
439
|
+
filter_calls = []
|
|
440
|
+
|
|
441
|
+
def fake_time_index_filter(**kwargs):
|
|
442
|
+
filter_calls.append(kwargs)
|
|
443
|
+
return [
|
|
444
|
+
TimeIndexMetaData.model_construct(
|
|
445
|
+
identifier="markets.AccountHoldings",
|
|
446
|
+
uid="holdings-meta-table-uid",
|
|
447
|
+
data_source_uid="data-source-uid",
|
|
448
|
+
storage_hash="holdings-storage-hash",
|
|
449
|
+
physical_table_name="mt_holdings",
|
|
450
|
+
)
|
|
451
|
+
]
|
|
452
|
+
|
|
453
|
+
monkeypatch.setattr(
|
|
454
|
+
TimeIndexMetaData,
|
|
455
|
+
"filter",
|
|
456
|
+
staticmethod(fake_time_index_filter),
|
|
457
|
+
)
|
|
458
|
+
monkeypatch.setattr(
|
|
459
|
+
MetaTable,
|
|
460
|
+
"filter",
|
|
461
|
+
staticmethod(lambda **kwargs: (_ for _ in ()).throw(AssertionError())),
|
|
462
|
+
)
|
|
463
|
+
|
|
464
|
+
resolved = migration.resolve_or_register_metatable_models(timeout=25)
|
|
465
|
+
|
|
466
|
+
assert filter_calls == [
|
|
467
|
+
{
|
|
468
|
+
"identifier__in": ["markets.AccountHoldings"],
|
|
469
|
+
"include_relations_detail": True,
|
|
470
|
+
"timeout": 25,
|
|
471
|
+
}
|
|
472
|
+
]
|
|
473
|
+
assert [meta_table.uid for meta_table in resolved] == ["holdings-meta-table-uid"]
|
|
474
|
+
assert AccountHoldings.get_time_index_metadata() is resolved[0]
|
|
475
|
+
assert isinstance(AccountHoldings.get_time_index_metadata(), TimeIndexMetaData)
|
|
476
|
+
|
|
477
|
+
|
|
407
478
|
def test_alembic_metatable_migration_does_not_call_hook_when_model_registration_fails(
|
|
408
479
|
monkeypatch,
|
|
409
480
|
):
|
|
@@ -11,7 +11,9 @@ import mainsequence.meta_tables.sqlalchemy_contracts as sqlalchemy_contracts
|
|
|
11
11
|
from mainsequence.client.metatables import (
|
|
12
12
|
DataSource,
|
|
13
13
|
DynamicTableDataSource,
|
|
14
|
+
MetaTable,
|
|
14
15
|
MetaTableRegistrationRequest,
|
|
16
|
+
TimeIndexMetaData,
|
|
15
17
|
TimeIndexMetaTableRegistrationRequest,
|
|
16
18
|
)
|
|
17
19
|
from mainsequence.meta_tables import (
|
|
@@ -1256,6 +1258,56 @@ def test_time_index_metadata_register_posts_to_dynamic_table_endpoint(monkeypatc
|
|
|
1256
1258
|
]
|
|
1257
1259
|
|
|
1258
1260
|
|
|
1261
|
+
def test_time_index_metadata_bind_rehydrates_flagged_generic_metatable(monkeypatch):
|
|
1262
|
+
class AccountHoldings(PlatformTimeIndexMetaData):
|
|
1263
|
+
pass
|
|
1264
|
+
|
|
1265
|
+
typed_meta_table = TimeIndexMetaData.model_construct(
|
|
1266
|
+
uid="aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa",
|
|
1267
|
+
data_source_uid="dddddddd-dddd-4ddd-8ddd-dddddddddddd",
|
|
1268
|
+
storage_hash="holdings-storage-hash",
|
|
1269
|
+
physical_table_name="mt_holdings",
|
|
1270
|
+
)
|
|
1271
|
+
generic_meta_table = MetaTable.model_construct(
|
|
1272
|
+
uid="aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa",
|
|
1273
|
+
data_source_uid="dddddddd-dddd-4ddd-8ddd-dddddddddddd",
|
|
1274
|
+
storage_hash="holdings-storage-hash",
|
|
1275
|
+
management_mode="platform_managed",
|
|
1276
|
+
physical_table_name="mt_holdings",
|
|
1277
|
+
time_indexed=True,
|
|
1278
|
+
table_kind="time_indexed",
|
|
1279
|
+
)
|
|
1280
|
+
|
|
1281
|
+
calls = []
|
|
1282
|
+
|
|
1283
|
+
def fake_get_by_uid(cls, uid, timeout=None, **filters):
|
|
1284
|
+
calls.append((uid, timeout, filters))
|
|
1285
|
+
return typed_meta_table
|
|
1286
|
+
|
|
1287
|
+
monkeypatch.setattr(TimeIndexMetaData, "get_by_uid", classmethod(fake_get_by_uid))
|
|
1288
|
+
|
|
1289
|
+
AccountHoldings._bind_meta_table(generic_meta_table)
|
|
1290
|
+
|
|
1291
|
+
assert calls == [("aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa", None, {})]
|
|
1292
|
+
assert AccountHoldings.get_time_index_metadata() is typed_meta_table
|
|
1293
|
+
|
|
1294
|
+
|
|
1295
|
+
def test_time_index_metadata_bind_rejects_unflagged_generic_metatable():
|
|
1296
|
+
class AccountHoldings(PlatformTimeIndexMetaData):
|
|
1297
|
+
pass
|
|
1298
|
+
|
|
1299
|
+
generic_meta_table = MetaTable.model_construct(
|
|
1300
|
+
uid="aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa",
|
|
1301
|
+
data_source_uid="dddddddd-dddd-4ddd-8ddd-dddddddddddd",
|
|
1302
|
+
storage_hash="holdings-storage-hash",
|
|
1303
|
+
management_mode="platform_managed",
|
|
1304
|
+
physical_table_name="mt_holdings",
|
|
1305
|
+
)
|
|
1306
|
+
|
|
1307
|
+
with pytest.raises(TypeError, match="requires TimeIndexMetaData binding"):
|
|
1308
|
+
AccountHoldings._bind_meta_table(generic_meta_table)
|
|
1309
|
+
|
|
1310
|
+
|
|
1259
1311
|
def test_ensure_registered_storage_table_rejects_unbound_storage():
|
|
1260
1312
|
columns = [
|
|
1261
1313
|
FakeColumn("time_index", DateTime(timezone=True), nullable=False),
|
|
@@ -58,6 +58,8 @@ def _platform_storage_model(meta_table: MetaTable) -> type[PlatformTimeIndexMeta
|
|
|
58
58
|
class RuntimeStorageTable(PlatformTimeIndexMetaData):
|
|
59
59
|
pass
|
|
60
60
|
|
|
61
|
+
if not isinstance(meta_table, TimeIndexMetaData):
|
|
62
|
+
meta_table = TimeIndexMetaData.model_construct(**meta_table.model_dump())
|
|
61
63
|
RuntimeStorageTable._bind_meta_table(meta_table)
|
|
62
64
|
return RuntimeStorageTable
|
|
63
65
|
|
|
@@ -370,7 +372,8 @@ def test_persist_manager_validates_storage_table_without_creating_storage():
|
|
|
370
372
|
}
|
|
371
373
|
]
|
|
372
374
|
assert manager.storage_table is storage_table
|
|
373
|
-
assert manager.storage_metadata
|
|
375
|
+
assert manager.storage_metadata.uid == meta_table.uid
|
|
376
|
+
assert isinstance(manager.storage_metadata, TimeIndexMetaData)
|
|
374
377
|
|
|
375
378
|
|
|
376
379
|
def test_persist_manager_rejects_unbound_platform_time_index_storage_table():
|
|
@@ -481,7 +484,8 @@ def test_persist_manager_preserves_storage_table_during_update_lookup():
|
|
|
481
484
|
|
|
482
485
|
assert manager.data_node_update.data_node_storage is stale_response_storage
|
|
483
486
|
assert manager.storage_table is storage_table
|
|
484
|
-
assert manager.storage_metadata
|
|
487
|
+
assert manager.storage_metadata.uid == meta_table.uid
|
|
488
|
+
assert isinstance(manager.storage_metadata, TimeIndexMetaData)
|
|
485
489
|
|
|
486
490
|
|
|
487
491
|
def test_data_node_accepts_platform_time_index_storage_table_runtime_argument():
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mainsequence-4.2.1 → mainsequence-4.2.2}/agent_scaffold/skills/command_center/connections/SKILL.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mainsequence-4.2.1 → mainsequence-4.2.2}/agent_scaffold/skills/dashboards/streamlit/SKILL.md
RENAMED
|
File without changes
|
{mainsequence-4.2.1 → mainsequence-4.2.2}/agent_scaffold/skills/data_access/exploration/SKILL.md
RENAMED
|
File without changes
|
{mainsequence-4.2.1 → mainsequence-4.2.2}/agent_scaffold/skills/data_publishing/data_nodes/SKILL.md
RENAMED
|
File without changes
|
{mainsequence-4.2.1 → mainsequence-4.2.2}/agent_scaffold/skills/maintenance/bug_auditor/SKILL.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mainsequence-4.2.1 → mainsequence-4.2.2}/mainsequence/client/command_center/app_component.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mainsequence-4.2.1 → mainsequence-4.2.2}/mainsequence/client/command_center/workspace_snapshot.py
RENAMED
|
File without changes
|
|
File without changes
|
{mainsequence-4.2.1 → mainsequence-4.2.2}/mainsequence/client/data_sources_interfaces/__init__.py
RENAMED
|
File without changes
|
{mainsequence-4.2.1 → mainsequence-4.2.2}/mainsequence/client/data_sources_interfaces/duckdb.py
RENAMED
|
File without changes
|
{mainsequence-4.2.1 → mainsequence-4.2.2}/mainsequence/client/data_sources_interfaces/local_paths.py
RENAMED
|
File without changes
|
{mainsequence-4.2.1 → mainsequence-4.2.2}/mainsequence/client/data_sources_interfaces/sqlite.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mainsequence-4.2.1 → mainsequence-4.2.2}/mainsequence/meta_tables/data_nodes/build_operations.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mainsequence-4.2.1 → mainsequence-4.2.2}/mainsequence/meta_tables/data_nodes/namespacing.py
RENAMED
|
File without changes
|
{mainsequence-4.2.1 → mainsequence-4.2.2}/mainsequence/meta_tables/data_nodes/run_operations.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|