mainsequence 4.3.18__tar.gz → 4.3.19__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.
Files changed (138) hide show
  1. {mainsequence-4.3.18/mainsequence.egg-info → mainsequence-4.3.19}/PKG-INFO +1 -1
  2. {mainsequence-4.3.18 → mainsequence-4.3.19}/mainsequence/client/metatables/core.py +52 -1
  3. {mainsequence-4.3.18 → mainsequence-4.3.19/mainsequence.egg-info}/PKG-INFO +1 -1
  4. {mainsequence-4.3.18 → mainsequence-4.3.19}/pyproject.toml +1 -1
  5. {mainsequence-4.3.18 → mainsequence-4.3.19}/tests/test_data_node_storage_dimension_queries.py +75 -0
  6. {mainsequence-4.3.18 → mainsequence-4.3.19}/LICENSE +0 -0
  7. {mainsequence-4.3.18 → mainsequence-4.3.19}/README.md +0 -0
  8. {mainsequence-4.3.18 → mainsequence-4.3.19}/agent_scaffold/AGENTS.md +0 -0
  9. {mainsequence-4.3.18 → mainsequence-4.3.19}/agent_scaffold/skills/a2a_communication/SKILL.md +0 -0
  10. {mainsequence-4.3.18 → mainsequence-4.3.19}/agent_scaffold/skills/application_surfaces/api_surfaces/SKILL.md +0 -0
  11. {mainsequence-4.3.18 → mainsequence-4.3.19}/agent_scaffold/skills/command_center/adapter_from_api/SKILL.md +0 -0
  12. {mainsequence-4.3.18 → mainsequence-4.3.19}/agent_scaffold/skills/command_center/api_mock_prototyping/SKILL.md +0 -0
  13. {mainsequence-4.3.18 → mainsequence-4.3.19}/agent_scaffold/skills/command_center/app_components/SKILL.md +0 -0
  14. {mainsequence-4.3.18 → mainsequence-4.3.19}/agent_scaffold/skills/command_center/connections/SKILL.md +0 -0
  15. {mainsequence-4.3.18 → mainsequence-4.3.19}/agent_scaffold/skills/command_center/workspace_analysis/SKILL.md +0 -0
  16. {mainsequence-4.3.18 → mainsequence-4.3.19}/agent_scaffold/skills/command_center/workspace_builder/SKILL.md +0 -0
  17. {mainsequence-4.3.18 → mainsequence-4.3.19}/agent_scaffold/skills/command_center/workspace_design/SKILL.md +0 -0
  18. {mainsequence-4.3.18 → mainsequence-4.3.19}/agent_scaffold/skills/dashboards/streamlit/SKILL.md +0 -0
  19. {mainsequence-4.3.18 → mainsequence-4.3.19}/agent_scaffold/skills/data_access/exploration/SKILL.md +0 -0
  20. {mainsequence-4.3.18 → mainsequence-4.3.19}/agent_scaffold/skills/data_publishing/data_nodes/SKILL.md +0 -0
  21. {mainsequence-4.3.18 → mainsequence-4.3.19}/agent_scaffold/skills/data_publishing/meta_table_migrations/SKILL.md +0 -0
  22. {mainsequence-4.3.18 → mainsequence-4.3.19}/agent_scaffold/skills/data_publishing/meta_tables/SKILL.md +0 -0
  23. {mainsequence-4.3.18 → mainsequence-4.3.19}/agent_scaffold/skills/maintenance/bug_auditor/SKILL.md +0 -0
  24. {mainsequence-4.3.18 → mainsequence-4.3.19}/agent_scaffold/skills/ms-markets/SKILL.md +0 -0
  25. {mainsequence-4.3.18 → mainsequence-4.3.19}/agent_scaffold/skills/platform_operations/access_control_and_sharing/SKILL.md +0 -0
  26. {mainsequence-4.3.18 → mainsequence-4.3.19}/agent_scaffold/skills/platform_operations/orchestration_and_releases/SKILL.md +0 -0
  27. {mainsequence-4.3.18 → mainsequence-4.3.19}/agent_scaffold/skills/project_builder/SKILL.md +0 -0
  28. {mainsequence-4.3.18 → mainsequence-4.3.19}/agent_scaffold/skills/project_to_agent/SKILL.md +0 -0
  29. {mainsequence-4.3.18 → mainsequence-4.3.19}/mainsequence/__init__.py +0 -0
  30. {mainsequence-4.3.18 → mainsequence-4.3.19}/mainsequence/__main__.py +0 -0
  31. {mainsequence-4.3.18 → mainsequence-4.3.19}/mainsequence/bootstrap.py +0 -0
  32. {mainsequence-4.3.18 → mainsequence-4.3.19}/mainsequence/cli/__init__.py +0 -0
  33. {mainsequence-4.3.18 → mainsequence-4.3.19}/mainsequence/cli/api.py +0 -0
  34. {mainsequence-4.3.18 → mainsequence-4.3.19}/mainsequence/cli/browser_auth.py +0 -0
  35. {mainsequence-4.3.18 → mainsequence-4.3.19}/mainsequence/cli/cli.py +0 -0
  36. {mainsequence-4.3.18 → mainsequence-4.3.19}/mainsequence/cli/config.py +0 -0
  37. {mainsequence-4.3.18 → mainsequence-4.3.19}/mainsequence/cli/docker_utils.py +0 -0
  38. {mainsequence-4.3.18 → mainsequence-4.3.19}/mainsequence/cli/doctor.py +0 -0
  39. {mainsequence-4.3.18 → mainsequence-4.3.19}/mainsequence/cli/local_ops.py +0 -0
  40. {mainsequence-4.3.18 → mainsequence-4.3.19}/mainsequence/cli/migrations.py +0 -0
  41. {mainsequence-4.3.18 → mainsequence-4.3.19}/mainsequence/cli/model_filters.py +0 -0
  42. {mainsequence-4.3.18 → mainsequence-4.3.19}/mainsequence/cli/project_status.py +0 -0
  43. {mainsequence-4.3.18 → mainsequence-4.3.19}/mainsequence/cli/pydantic_cli.py +0 -0
  44. {mainsequence-4.3.18 → mainsequence-4.3.19}/mainsequence/cli/sdk_utils.py +0 -0
  45. {mainsequence-4.3.18 → mainsequence-4.3.19}/mainsequence/cli/ssh_utils.py +0 -0
  46. {mainsequence-4.3.18 → mainsequence-4.3.19}/mainsequence/cli/ui.py +0 -0
  47. {mainsequence-4.3.18 → mainsequence-4.3.19}/mainsequence/client/__init__.py +0 -0
  48. {mainsequence-4.3.18 → mainsequence-4.3.19}/mainsequence/client/agent_runtime_models.py +0 -0
  49. {mainsequence-4.3.18 → mainsequence-4.3.19}/mainsequence/client/base.py +0 -0
  50. {mainsequence-4.3.18 → mainsequence-4.3.19}/mainsequence/client/client.py +0 -0
  51. {mainsequence-4.3.18 → mainsequence-4.3.19}/mainsequence/client/command_center/__init__.py +0 -0
  52. {mainsequence-4.3.18 → mainsequence-4.3.19}/mainsequence/client/command_center/app_component.py +0 -0
  53. {mainsequence-4.3.18 → mainsequence-4.3.19}/mainsequence/client/command_center/connections.py +0 -0
  54. {mainsequence-4.3.18 → mainsequence-4.3.19}/mainsequence/client/command_center/data_models.py +0 -0
  55. {mainsequence-4.3.18 → mainsequence-4.3.19}/mainsequence/client/command_center/workspace.py +0 -0
  56. {mainsequence-4.3.18 → mainsequence-4.3.19}/mainsequence/client/command_center/workspace_snapshot.py +0 -0
  57. {mainsequence-4.3.18 → mainsequence-4.3.19}/mainsequence/client/compute_validation.py +0 -0
  58. {mainsequence-4.3.18 → mainsequence-4.3.19}/mainsequence/client/data_sources_interfaces/__init__.py +0 -0
  59. {mainsequence-4.3.18 → mainsequence-4.3.19}/mainsequence/client/data_sources_interfaces/duckdb.py +0 -0
  60. {mainsequence-4.3.18 → mainsequence-4.3.19}/mainsequence/client/data_sources_interfaces/local_paths.py +0 -0
  61. {mainsequence-4.3.18 → mainsequence-4.3.19}/mainsequence/client/data_sources_interfaces/sqlite.py +0 -0
  62. {mainsequence-4.3.18 → mainsequence-4.3.19}/mainsequence/client/dtype_codec.py +0 -0
  63. {mainsequence-4.3.18 → mainsequence-4.3.19}/mainsequence/client/exceptions.py +0 -0
  64. {mainsequence-4.3.18 → mainsequence-4.3.19}/mainsequence/client/fastapi/__init__.py +0 -0
  65. {mainsequence-4.3.18 → mainsequence-4.3.19}/mainsequence/client/fastapi/auth.py +0 -0
  66. {mainsequence-4.3.18 → mainsequence-4.3.19}/mainsequence/client/metatables/__init__.py +0 -0
  67. {mainsequence-4.3.18 → mainsequence-4.3.19}/mainsequence/client/models_foundry.py +0 -0
  68. {mainsequence-4.3.18 → mainsequence-4.3.19}/mainsequence/client/models_helpers.py +0 -0
  69. {mainsequence-4.3.18 → mainsequence-4.3.19}/mainsequence/client/models_user.py +0 -0
  70. {mainsequence-4.3.18 → mainsequence-4.3.19}/mainsequence/client/utils.py +0 -0
  71. {mainsequence-4.3.18 → mainsequence-4.3.19}/mainsequence/defaults.py +0 -0
  72. {mainsequence-4.3.18 → mainsequence-4.3.19}/mainsequence/instrumentation/__init__.py +0 -0
  73. {mainsequence-4.3.18 → mainsequence-4.3.19}/mainsequence/instrumentation/utils.py +0 -0
  74. {mainsequence-4.3.18 → mainsequence-4.3.19}/mainsequence/logconf.py +0 -0
  75. {mainsequence-4.3.18 → mainsequence-4.3.19}/mainsequence/meta_tables/__init__.py +0 -0
  76. {mainsequence-4.3.18 → mainsequence-4.3.19}/mainsequence/meta_tables/__main__.py +0 -0
  77. {mainsequence-4.3.18 → mainsequence-4.3.19}/mainsequence/meta_tables/compiled_sql/__init__.py +0 -0
  78. {mainsequence-4.3.18 → mainsequence-4.3.19}/mainsequence/meta_tables/compiled_sql/v1.py +0 -0
  79. {mainsequence-4.3.18 → mainsequence-4.3.19}/mainsequence/meta_tables/data_nodes/__init__.py +0 -0
  80. {mainsequence-4.3.18 → mainsequence-4.3.19}/mainsequence/meta_tables/data_nodes/build_operations.py +0 -0
  81. {mainsequence-4.3.18 → mainsequence-4.3.19}/mainsequence/meta_tables/data_nodes/data_nodes.py +0 -0
  82. {mainsequence-4.3.18 → mainsequence-4.3.19}/mainsequence/meta_tables/data_nodes/models.py +0 -0
  83. {mainsequence-4.3.18 → mainsequence-4.3.19}/mainsequence/meta_tables/data_nodes/namespacing.py +0 -0
  84. {mainsequence-4.3.18 → mainsequence-4.3.19}/mainsequence/meta_tables/data_nodes/persist_managers.py +0 -0
  85. {mainsequence-4.3.18 → mainsequence-4.3.19}/mainsequence/meta_tables/data_nodes/run_operations.py +0 -0
  86. {mainsequence-4.3.18 → mainsequence-4.3.19}/mainsequence/meta_tables/data_nodes/utils.py +0 -0
  87. {mainsequence-4.3.18 → mainsequence-4.3.19}/mainsequence/meta_tables/future_registry.py +0 -0
  88. {mainsequence-4.3.18 → mainsequence-4.3.19}/mainsequence/meta_tables/hashing.py +0 -0
  89. {mainsequence-4.3.18 → mainsequence-4.3.19}/mainsequence/meta_tables/migrations/__init__.py +0 -0
  90. {mainsequence-4.3.18 → mainsequence-4.3.19}/mainsequence/meta_tables/migrations/alembic.py +0 -0
  91. {mainsequence-4.3.18 → mainsequence-4.3.19}/mainsequence/meta_tables/migrations/env.py +0 -0
  92. {mainsequence-4.3.18 → mainsequence-4.3.19}/mainsequence/meta_tables/migrations/provider.py +0 -0
  93. {mainsequence-4.3.18 → mainsequence-4.3.19}/mainsequence/meta_tables/migrations/registry.py +0 -0
  94. {mainsequence-4.3.18 → mainsequence-4.3.19}/mainsequence/meta_tables/migrations/scaffold.py +0 -0
  95. {mainsequence-4.3.18 → mainsequence-4.3.19}/mainsequence/meta_tables/migrations/templates/__init__.py +0 -0
  96. {mainsequence-4.3.18 → mainsequence-4.3.19}/mainsequence/meta_tables/migrations/templates/env.py.mako +0 -0
  97. {mainsequence-4.3.18 → mainsequence-4.3.19}/mainsequence/meta_tables/migrations/templates/script.py.mako +0 -0
  98. {mainsequence-4.3.18 → mainsequence-4.3.19}/mainsequence/meta_tables/pydantic_metadata.py +0 -0
  99. {mainsequence-4.3.18 → mainsequence-4.3.19}/mainsequence/meta_tables/schema_names.py +0 -0
  100. {mainsequence-4.3.18 → mainsequence-4.3.19}/mainsequence/meta_tables/sqlalchemy_contracts.py +0 -0
  101. {mainsequence-4.3.18 → mainsequence-4.3.19}/mainsequence/runtime_flags.py +0 -0
  102. {mainsequence-4.3.18 → mainsequence-4.3.19}/mainsequence.egg-info/SOURCES.txt +0 -0
  103. {mainsequence-4.3.18 → mainsequence-4.3.19}/mainsequence.egg-info/dependency_links.txt +0 -0
  104. {mainsequence-4.3.18 → mainsequence-4.3.19}/mainsequence.egg-info/entry_points.txt +0 -0
  105. {mainsequence-4.3.18 → mainsequence-4.3.19}/mainsequence.egg-info/requires.txt +0 -0
  106. {mainsequence-4.3.18 → mainsequence-4.3.19}/mainsequence.egg-info/top_level.txt +0 -0
  107. {mainsequence-4.3.18 → mainsequence-4.3.19}/setup.cfg +0 -0
  108. {mainsequence-4.3.18 → mainsequence-4.3.19}/tests/test_auth_precedence.py +0 -0
  109. {mainsequence-4.3.18 → mainsequence-4.3.19}/tests/test_build_operations_hashing.py +0 -0
  110. {mainsequence-4.3.18 → mainsequence-4.3.19}/tests/test_cli.py +0 -0
  111. {mainsequence-4.3.18 → mainsequence-4.3.19}/tests/test_cli_browser_auth.py +0 -0
  112. {mainsequence-4.3.18 → mainsequence-4.3.19}/tests/test_cli_migrations.py +0 -0
  113. {mainsequence-4.3.18 → mainsequence-4.3.19}/tests/test_client.py +0 -0
  114. {mainsequence-4.3.18 → mainsequence-4.3.19}/tests/test_command_center_app_component_models.py +0 -0
  115. {mainsequence-4.3.18 → mainsequence-4.3.19}/tests/test_command_center_data_models.py +0 -0
  116. {mainsequence-4.3.18 → mainsequence-4.3.19}/tests/test_command_center_models.py +0 -0
  117. {mainsequence-4.3.18 → mainsequence-4.3.19}/tests/test_data_access_mixin_dimension_audit.py +0 -0
  118. {mainsequence-4.3.18 → mainsequence-4.3.19}/tests/test_data_node_update_flow.py +0 -0
  119. {mainsequence-4.3.18 → mainsequence-4.3.19}/tests/test_dependency_extras.py +0 -0
  120. {mainsequence-4.3.18 → mainsequence-4.3.19}/tests/test_duckdb_interface_dimensions.py +0 -0
  121. {mainsequence-4.3.18 → mainsequence-4.3.19}/tests/test_filter_normalization.py +0 -0
  122. {mainsequence-4.3.18 → mainsequence-4.3.19}/tests/test_instrumentation.py +0 -0
  123. {mainsequence-4.3.18 → mainsequence-4.3.19}/tests/test_logconf.py +0 -0
  124. {mainsequence-4.3.18 → mainsequence-4.3.19}/tests/test_meta_table_migrations.py +0 -0
  125. {mainsequence-4.3.18 → mainsequence-4.3.19}/tests/test_meta_tables_client_models.py +0 -0
  126. {mainsequence-4.3.18 → mainsequence-4.3.19}/tests/test_meta_tables_sqlalchemy_contracts.py +0 -0
  127. {mainsequence-4.3.18 → mainsequence-4.3.19}/tests/test_models_user_request_bound_auth.py +0 -0
  128. {mainsequence-4.3.18 → mainsequence-4.3.19}/tests/test_pod_project_resolution.py +0 -0
  129. {mainsequence-4.3.18 → mainsequence-4.3.19}/tests/test_project_batch_jobs_from_file.py +0 -0
  130. {mainsequence-4.3.18 → mainsequence-4.3.19}/tests/test_run_configuration.py +0 -0
  131. {mainsequence-4.3.18 → mainsequence-4.3.19}/tests/test_schema_names.py +0 -0
  132. {mainsequence-4.3.18 → mainsequence-4.3.19}/tests/test_secret_client_model.py +0 -0
  133. {mainsequence-4.3.18 → mainsequence-4.3.19}/tests/test_source_table_configuration.py +0 -0
  134. {mainsequence-4.3.18 → mainsequence-4.3.19}/tests/test_sqlite_interface_dimensions.py +0 -0
  135. {mainsequence-4.3.18 → mainsequence-4.3.19}/tests/test_update_runner_uid_runtime.py +0 -0
  136. {mainsequence-4.3.18 → mainsequence-4.3.19}/tests/test_update_statistics.py +0 -0
  137. {mainsequence-4.3.18 → mainsequence-4.3.19}/tests/test_update_uid_guards.py +0 -0
  138. {mainsequence-4.3.18 → mainsequence-4.3.19}/tests/test_workspace_snapshot.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mainsequence
3
- Version: 4.3.18
3
+ Version: 4.3.19
4
4
  Summary: Main Sequence SDK
5
5
  Author-email: Main Sequence GmbH <dev@main-sequence.io>
6
6
  License: MainSequence GmbH SDK License Agreement
@@ -3027,6 +3027,56 @@ class TimeIndexMetaTable(MetaTable):
3027
3027
  descriptor[key] = cls._date_for_payload(descriptor[key])
3028
3028
  return normalized
3029
3029
 
3030
+ def _identity_dimensions_from_time_indexed_profile(self) -> list[str]:
3031
+ profile = self.time_indexed_profile
3032
+ if profile is None:
3033
+ raise ValueError(
3034
+ "Cannot validate dimension_range_map because TimeIndexMetaTable "
3035
+ "is missing time_indexed_profile."
3036
+ )
3037
+
3038
+ time_index_name = str(profile.time_index_name)
3039
+ index_names = [str(name) for name in profile.index_names]
3040
+ if not time_index_name or not index_names:
3041
+ raise ValueError(
3042
+ "Cannot validate dimension_range_map because TimeIndexMetaTable "
3043
+ "time_indexed_profile is missing time_index_name or index_names."
3044
+ )
3045
+ return [name for name in index_names if name != time_index_name]
3046
+
3047
+ def _validate_dimension_range_map_coordinates(
3048
+ self,
3049
+ dimension_range_map: list[dict[str, Any]] | None,
3050
+ ) -> None:
3051
+ if not dimension_range_map:
3052
+ return
3053
+
3054
+ expected_dimensions = self._identity_dimensions_from_time_indexed_profile()
3055
+ if not expected_dimensions:
3056
+ return
3057
+
3058
+ for position, descriptor in enumerate(dimension_range_map):
3059
+ coordinate = descriptor.get("coordinate") if isinstance(descriptor, Mapping) else None
3060
+ provided_dimensions = (
3061
+ [str(name) for name in coordinate.keys()]
3062
+ if isinstance(coordinate, Mapping)
3063
+ else []
3064
+ )
3065
+ provided_set = set(provided_dimensions)
3066
+ missing_dimensions = [
3067
+ dimension
3068
+ for dimension in expected_dimensions
3069
+ if dimension not in provided_set
3070
+ ]
3071
+ if missing_dimensions:
3072
+ raise ValueError(
3073
+ "dimension_range_map coordinate is incomplete for "
3074
+ "TimeIndexMetaTable read. "
3075
+ f"Entry {position} expected identity dimensions "
3076
+ f"{expected_dimensions!r}; provided {provided_dimensions!r}; "
3077
+ f"missing {missing_dimensions!r}."
3078
+ )
3079
+
3030
3080
  def _build_dimension_payload(
3031
3081
  self,
3032
3082
  *,
@@ -3040,6 +3090,7 @@ class TimeIndexMetaTable(MetaTable):
3040
3090
  if index_coordinates is not None:
3041
3091
  payload["index_coordinates"] = index_coordinates
3042
3092
  if dimension_range_map is not None:
3093
+ self._validate_dimension_range_map_coordinates(dimension_range_map)
3043
3094
  payload["dimension_range_map"] = self._normalize_dimension_range_map(
3044
3095
  dimension_range_map
3045
3096
  )
@@ -3326,7 +3377,7 @@ class TimeIndexMetaTable(MetaTable):
3326
3377
  )
3327
3378
  if r.status_code != 200:
3328
3379
  logger.warning(f"Error in request: {r.text}")
3329
- return [], None
3380
+ raise_for_response(r, payload=payload)
3330
3381
 
3331
3382
  response_data = r.json()
3332
3383
  # Accumulate results
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mainsequence
3
- Version: 4.3.18
3
+ Version: 4.3.19
4
4
  Summary: Main Sequence SDK
5
5
  Author-email: Main Sequence GmbH <dev@main-sequence.io>
6
6
  License: MainSequence GmbH SDK License Agreement
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "mainsequence"
7
- version = "4.3.18"
7
+ version = "4.3.19"
8
8
  description = "Main Sequence SDK "
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
@@ -1,8 +1,10 @@
1
1
  import datetime
2
2
 
3
3
  import pandas as pd
4
+ import pytest
4
5
 
5
6
  from mainsequence.client import metatables as models_metatables
7
+ from mainsequence.client.exceptions import BadRequestError
6
8
 
7
9
 
8
10
  def _source_config(index_names: list[str]) -> models_metatables.TimeIndexedProfile:
@@ -173,6 +175,79 @@ def test_get_data_between_dates_from_api_sends_dimension_range_map(monkeypatch):
173
175
  ]
174
176
 
175
177
 
178
+ def test_get_data_between_dates_rejects_incomplete_dimension_range_map(monkeypatch):
179
+ def _fake_make_request(**_kwargs):
180
+ raise AssertionError("request should not be sent with an incomplete coordinate")
181
+
182
+ monkeypatch.setattr(models_metatables, "make_request", _fake_make_request)
183
+
184
+ start = datetime.datetime(2026, 5, 1, 0, tzinfo=datetime.UTC)
185
+
186
+ with pytest.raises(ValueError) as exc:
187
+ _storage(
188
+ ["time_index", "account_uid", "asset_identifier"]
189
+ ).get_data_between_dates_from_api(
190
+ start_date=start,
191
+ dimension_range_map=[
192
+ {
193
+ "coordinate": {"account_uid": "account-a"},
194
+ "start_date": start,
195
+ }
196
+ ],
197
+ )
198
+
199
+ message = str(exc.value)
200
+ assert "dimension_range_map coordinate is incomplete" in message
201
+ assert "asset_identifier" in message
202
+ assert "account_uid" in message
203
+
204
+
205
+ def test_get_data_between_dates_raises_backend_error(monkeypatch):
206
+ class FakeResponse:
207
+ status_code = 400
208
+ text = '{"error": {"dimension_range_map": ["Index coordinate missing dimension(s): asset_identifier"]}}'
209
+
210
+ @staticmethod
211
+ def json():
212
+ return {
213
+ "error": {
214
+ "dimension_range_map": [
215
+ "Index coordinate missing dimension(s): asset_identifier"
216
+ ]
217
+ }
218
+ }
219
+
220
+ def _fake_make_request(*, s, loaders, payload, r_type, url):
221
+ return FakeResponse()
222
+
223
+ monkeypatch.setattr(models_metatables, "make_request", _fake_make_request)
224
+ monkeypatch.setattr(
225
+ models_metatables.TimeIndexMetaTable,
226
+ "build_session",
227
+ classmethod(lambda cls: object()),
228
+ )
229
+
230
+ start = datetime.datetime(2026, 5, 1, 0, tzinfo=datetime.UTC)
231
+
232
+ with pytest.raises(BadRequestError) as exc:
233
+ _storage(
234
+ ["time_index", "account_uid", "asset_identifier"]
235
+ ).get_data_between_dates_from_api(
236
+ start_date=start,
237
+ dimension_range_map=[
238
+ {
239
+ "coordinate": {
240
+ "account_uid": "account-a",
241
+ "asset_identifier": "BTC",
242
+ },
243
+ "start_date": start,
244
+ }
245
+ ],
246
+ )
247
+
248
+ assert "asset_identifier" in str(exc.value)
249
+
250
+
176
251
  def test_get_data_between_dates_from_node_identifier_sends_canonical_dimensions(monkeypatch):
177
252
  captured = {}
178
253
 
File without changes
File without changes
File without changes