mainsequence 3.18.4__tar.gz → 3.18.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.
Files changed (179) hide show
  1. {mainsequence-3.18.4 → mainsequence-3.18.6}/PKG-INFO +1 -1
  2. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/cli/cli.py +7 -8
  3. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/cli/config.py +4 -2
  4. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/client/client.py +3 -1
  5. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/client/command_center/workspace_snapshot.py +3 -1
  6. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/client/models_simple_tables.py +7 -0
  7. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/client/models_tdag.py +7 -0
  8. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/client/models_user.py +2 -1
  9. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/client/utils.py +4 -3
  10. mainsequence-3.18.6/mainsequence/defaults.py +3 -0
  11. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/logconf.py +2 -1
  12. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence.egg-info/PKG-INFO +1 -1
  13. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence.egg-info/SOURCES.txt +1 -0
  14. {mainsequence-3.18.4 → mainsequence-3.18.6}/pyproject.toml +1 -1
  15. {mainsequence-3.18.4 → mainsequence-3.18.6}/tests/test_cli.py +78 -16
  16. {mainsequence-3.18.4 → mainsequence-3.18.6}/tests/test_run_configuration.py +71 -2
  17. {mainsequence-3.18.4 → mainsequence-3.18.6}/LICENSE +0 -0
  18. {mainsequence-3.18.4 → mainsequence-3.18.6}/README.md +0 -0
  19. {mainsequence-3.18.4 → mainsequence-3.18.6}/agent_scaffold/AGENTS.md +0 -0
  20. {mainsequence-3.18.4 → mainsequence-3.18.6}/agent_scaffold/skills/application_surfaces/api_surfaces/SKILL.md +0 -0
  21. {mainsequence-3.18.4 → mainsequence-3.18.6}/agent_scaffold/skills/command_center/api_mock_prototyping/SKILL.md +0 -0
  22. {mainsequence-3.18.4 → mainsequence-3.18.6}/agent_scaffold/skills/command_center/app_components/SKILL.md +0 -0
  23. {mainsequence-3.18.4 → mainsequence-3.18.6}/agent_scaffold/skills/command_center/workspace_analysis/SKILL.md +0 -0
  24. {mainsequence-3.18.4 → mainsequence-3.18.6}/agent_scaffold/skills/command_center/workspace_builder/SKILL.md +0 -0
  25. {mainsequence-3.18.4 → mainsequence-3.18.6}/agent_scaffold/skills/dashboards/streamlit/SKILL.md +0 -0
  26. {mainsequence-3.18.4 → mainsequence-3.18.6}/agent_scaffold/skills/data_access/exploration/SKILL.md +0 -0
  27. {mainsequence-3.18.4 → mainsequence-3.18.6}/agent_scaffold/skills/data_publishing/data_nodes/SKILL.md +0 -0
  28. {mainsequence-3.18.4 → mainsequence-3.18.6}/agent_scaffold/skills/data_publishing/simple_tables/SKILL.md +0 -0
  29. {mainsequence-3.18.4 → mainsequence-3.18.6}/agent_scaffold/skills/maintenance/bug_auditor/SKILL.md +0 -0
  30. {mainsequence-3.18.4 → mainsequence-3.18.6}/agent_scaffold/skills/maintenance/local_journal/SKILL.md +0 -0
  31. {mainsequence-3.18.4 → mainsequence-3.18.6}/agent_scaffold/skills/markets_platform/assets_and_translation/SKILL.md +0 -0
  32. {mainsequence-3.18.4 → mainsequence-3.18.6}/agent_scaffold/skills/markets_platform/instruments_and_pricing/SKILL.md +0 -0
  33. {mainsequence-3.18.4 → mainsequence-3.18.6}/agent_scaffold/skills/markets_platform/virtualfundbuilder/SKILL.md +0 -0
  34. {mainsequence-3.18.4 → mainsequence-3.18.6}/agent_scaffold/skills/platform_operations/access_control_and_sharing/SKILL.md +0 -0
  35. {mainsequence-3.18.4 → mainsequence-3.18.6}/agent_scaffold/skills/platform_operations/orchestration_and_releases/SKILL.md +0 -0
  36. {mainsequence-3.18.4 → mainsequence-3.18.6}/agent_scaffold/skills/project_builder/SKILL.md +0 -0
  37. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/__init__.py +0 -0
  38. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/__main__.py +0 -0
  39. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/bootstrap.py +0 -0
  40. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/cli/__init__.py +0 -0
  41. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/cli/api.py +0 -0
  42. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/cli/browser_auth.py +0 -0
  43. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/cli/docker_utils.py +0 -0
  44. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/cli/doctor.py +0 -0
  45. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/cli/local_ops.py +0 -0
  46. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/cli/model_filters.py +0 -0
  47. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/cli/project_status.py +0 -0
  48. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/cli/pydantic_cli.py +0 -0
  49. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/cli/sdk_utils.py +0 -0
  50. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/cli/ssh_utils.py +0 -0
  51. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/cli/ui.py +0 -0
  52. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/client/__init__.py +0 -0
  53. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/client/agent.py +0 -0
  54. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/client/agent_runtime_models.py +0 -0
  55. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/client/base.py +0 -0
  56. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/client/command_center/__init__.py +0 -0
  57. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/client/command_center/app_component.py +0 -0
  58. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/client/command_center/data_models.py +0 -0
  59. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/client/command_center/workspace.py +0 -0
  60. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/client/data_sources_interfaces/__init__.py +0 -0
  61. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/client/data_sources_interfaces/duckdb.py +0 -0
  62. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/client/data_sources_interfaces/timescale.py +0 -0
  63. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/client/exceptions.py +0 -0
  64. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/client/fastapi/__init__.py +0 -0
  65. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/client/fastapi/auth.py +0 -0
  66. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/client/models_helpers.py +0 -0
  67. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/client/models_vam.py +0 -0
  68. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/compute_validation.py +0 -0
  69. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/dashboards/__init__.py +0 -0
  70. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/dashboards/streamlit/__init__.py +0 -0
  71. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/dashboards/streamlit/assets/config.toml +0 -0
  72. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/dashboards/streamlit/assets/favicon.png +0 -0
  73. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/dashboards/streamlit/assets/image_1_base64.txt +0 -0
  74. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/dashboards/streamlit/assets/image_2_base64.txt +0 -0
  75. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/dashboards/streamlit/assets/image_3_base64.txt +0 -0
  76. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/dashboards/streamlit/assets/image_4_base64.txt +0 -0
  77. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/dashboards/streamlit/assets/image_5_base64.txt +0 -0
  78. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/dashboards/streamlit/assets/logo.png +0 -0
  79. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/dashboards/streamlit/components/__init__.py +0 -0
  80. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/dashboards/streamlit/components/asset_select.py +0 -0
  81. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/dashboards/streamlit/components/date_settings.py +0 -0
  82. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/dashboards/streamlit/components/logged_user.py +0 -0
  83. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/dashboards/streamlit/core/__init__.py +0 -0
  84. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/dashboards/streamlit/core/theme.py +0 -0
  85. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/dashboards/streamlit/instruments/__init__.py +0 -0
  86. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/dashboards/streamlit/instruments/streamlit_form_factory.py +0 -0
  87. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/dashboards/streamlit/pages/__init__.py +0 -0
  88. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/dashboards/streamlit/scaffold.py +0 -0
  89. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/instrumentation/__init__.py +0 -0
  90. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/instrumentation/utils.py +0 -0
  91. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/instruments/__init__.py +0 -0
  92. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/instruments/data_interface/__init__.py +0 -0
  93. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/instruments/data_interface/data_interface.py +0 -0
  94. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/instruments/instruments/__init__.py +0 -0
  95. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/instruments/instruments/base_instrument.py +0 -0
  96. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/instruments/instruments/bond.py +0 -0
  97. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/instruments/instruments/callability.py +0 -0
  98. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/instruments/instruments/interest_rate_swap.py +0 -0
  99. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/instruments/instruments/json_codec.py +0 -0
  100. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/instruments/instruments/position.py +0 -0
  101. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/instruments/instruments/ql_fields.py +0 -0
  102. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/instruments/interest_rates/__init__.py +0 -0
  103. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/instruments/interest_rates/etl/__init__.py +0 -0
  104. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/instruments/interest_rates/etl/curve_codec.py +0 -0
  105. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/instruments/interest_rates/etl/nodes.py +0 -0
  106. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/instruments/interest_rates/etl/registry.py +0 -0
  107. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/instruments/pricing_models/__init__.py +0 -0
  108. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/instruments/pricing_models/bond_pricer.py +0 -0
  109. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/instruments/pricing_models/indices.py +0 -0
  110. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/instruments/pricing_models/indices_builders.py +0 -0
  111. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/instruments/pricing_models/swap_pricer.py +0 -0
  112. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/instruments/settings.py +0 -0
  113. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/instruments/utils.py +0 -0
  114. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/runtime_flags.py +0 -0
  115. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/tdag/__init__.py +0 -0
  116. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/tdag/__main__.py +0 -0
  117. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/tdag/base_persist_managers.py +0 -0
  118. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/tdag/config.py +0 -0
  119. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/tdag/configuration_models.py +0 -0
  120. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/tdag/data_nodes/__init__.py +0 -0
  121. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/tdag/data_nodes/build_operations.py +0 -0
  122. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/tdag/data_nodes/data_nodes.py +0 -0
  123. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/tdag/data_nodes/filters.py +0 -0
  124. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/tdag/data_nodes/models.py +0 -0
  125. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/tdag/data_nodes/namespacing.py +0 -0
  126. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/tdag/data_nodes/persist_managers.py +0 -0
  127. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/tdag/data_nodes/run_operations.py +0 -0
  128. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/tdag/data_nodes/utils.py +0 -0
  129. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/tdag/filters.py +0 -0
  130. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/tdag/future_registry.py +0 -0
  131. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/tdag/pydantic_metadata.py +0 -0
  132. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/tdag/simple_tables/__init__.py +0 -0
  133. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/tdag/simple_tables/filters.py +0 -0
  134. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/tdag/simple_tables/models.py +0 -0
  135. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/tdag/simple_tables/persist_managers.py +0 -0
  136. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/tdag/simple_tables/schema.py +0 -0
  137. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/tdag/simple_tables/table_nodes.py +0 -0
  138. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/tdag/utils.py +0 -0
  139. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/virtualfundbuilder/__init__.py +0 -0
  140. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/virtualfundbuilder/contrib/__init__.py +0 -0
  141. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/virtualfundbuilder/contrib/data_nodes/__init__.py +0 -0
  142. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/virtualfundbuilder/contrib/data_nodes/external_weights.py +0 -0
  143. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/virtualfundbuilder/contrib/data_nodes/intraday_trend.py +0 -0
  144. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/virtualfundbuilder/contrib/data_nodes/market_cap.py +0 -0
  145. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/virtualfundbuilder/contrib/data_nodes/mock_signal.py +0 -0
  146. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/virtualfundbuilder/contrib/data_nodes/portfolio_replicator.py +0 -0
  147. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/virtualfundbuilder/contrib/prices/__init__.py +0 -0
  148. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/virtualfundbuilder/contrib/prices/data_nodes.py +0 -0
  149. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/virtualfundbuilder/contrib/prices/utils.py +0 -0
  150. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/virtualfundbuilder/contrib/rebalance_strategies/__init__.py +0 -0
  151. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/virtualfundbuilder/contrib/rebalance_strategies/rebalance_strategies.py +0 -0
  152. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/virtualfundbuilder/enums.py +0 -0
  153. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/virtualfundbuilder/models.py +0 -0
  154. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/virtualfundbuilder/portfolio_nodes.py +0 -0
  155. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/virtualfundbuilder/resource_factory/__init__.py +0 -0
  156. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/virtualfundbuilder/resource_factory/rebalance_factory.py +0 -0
  157. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/virtualfundbuilder/resource_factory/signal_factory.py +0 -0
  158. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence/virtualfundbuilder/utils.py +0 -0
  159. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence.egg-info/dependency_links.txt +0 -0
  160. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence.egg-info/entry_points.txt +0 -0
  161. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence.egg-info/requires.txt +0 -0
  162. {mainsequence-3.18.4 → mainsequence-3.18.6}/mainsequence.egg-info/top_level.txt +0 -0
  163. {mainsequence-3.18.4 → mainsequence-3.18.6}/setup.cfg +0 -0
  164. {mainsequence-3.18.4 → mainsequence-3.18.6}/tests/test_auth_precedence.py +0 -0
  165. {mainsequence-3.18.4 → mainsequence-3.18.6}/tests/test_build_operations_hashing.py +0 -0
  166. {mainsequence-3.18.4 → mainsequence-3.18.6}/tests/test_cli_browser_auth.py +0 -0
  167. {mainsequence-3.18.4 → mainsequence-3.18.6}/tests/test_client.py +0 -0
  168. {mainsequence-3.18.4 → mainsequence-3.18.6}/tests/test_command_center_app_component_models.py +0 -0
  169. {mainsequence-3.18.4 → mainsequence-3.18.6}/tests/test_command_center_models.py +0 -0
  170. {mainsequence-3.18.4 → mainsequence-3.18.6}/tests/test_dependency_extras.py +0 -0
  171. {mainsequence-3.18.4 → mainsequence-3.18.6}/tests/test_filter_normalization.py +0 -0
  172. {mainsequence-3.18.4 → mainsequence-3.18.6}/tests/test_instruments.py +0 -0
  173. {mainsequence-3.18.4 → mainsequence-3.18.6}/tests/test_logconf.py +0 -0
  174. {mainsequence-3.18.4 → mainsequence-3.18.6}/tests/test_logged_user_components.py +0 -0
  175. {mainsequence-3.18.4 → mainsequence-3.18.6}/tests/test_models_user_request_bound_auth.py +0 -0
  176. {mainsequence-3.18.4 → mainsequence-3.18.6}/tests/test_pod_project_resolution.py +0 -0
  177. {mainsequence-3.18.4 → mainsequence-3.18.6}/tests/test_project_batch_jobs_from_file.py +0 -0
  178. {mainsequence-3.18.4 → mainsequence-3.18.6}/tests/test_simple_tables_configuration_hashing.py +0 -0
  179. {mainsequence-3.18.4 → mainsequence-3.18.6}/tests/test_simple_tables_persistence.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mainsequence
3
- Version: 3.18.4
3
+ Version: 3.18.6
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
@@ -226,7 +226,6 @@ from .ssh_utils import (
226
226
  from .ui import error, info, print_kv, print_table, status, success, warn
227
227
 
228
228
  JSON_OUTPUT_CONTEXT_KEY = "json_output"
229
- LOGIN_DEFAULT_BACKEND_URL = "https://api.main-sequence.io"
230
229
 
231
230
 
232
231
  class MainSequenceGroup(typer.core.TyperGroup):
@@ -2057,7 +2056,7 @@ def login(
2057
2056
  Persists auth tokens in the active CLI auth store so subsequent
2058
2057
  CLI invocations can run without re-authentication. Backend/base-folder
2059
2058
  overrides passed to `login` are scoped to the current terminal session.
2060
- When no backend is provided, login defaults to `https://api.main-sequence.io`.
2059
+ When no backend is provided, login defaults to the standard production backend.
2061
2060
 
2062
2061
  Interactive login uses browser-based authentication and finishes with
2063
2062
  standard JWT access/refresh tokens persisted by the CLI.
@@ -2122,7 +2121,7 @@ def login(
2122
2121
  error("Pass backend either positionally or with --backend, not both.")
2123
2122
  raise typer.Exit(1)
2124
2123
  explicit_backend_input = backend_option if backend_option is not None else backend
2125
- effective_backend_input = explicit_backend_input if explicit_backend_input is not None else LOGIN_DEFAULT_BACKEND_URL
2124
+ effective_backend_input = explicit_backend_input if explicit_backend_input is not None else cfg.STANDARD_BACKEND_URL
2126
2125
 
2127
2126
  if projects_base and projects_base_option:
2128
2127
  if cfg.normalize_mainsequence_path(projects_base) != cfg.normalize_mainsequence_path(projects_base_option):
@@ -2873,7 +2872,7 @@ def settings_set_base(path: str = typer.Argument(..., help="New projects base fo
2873
2872
 
2874
2873
  @settings.command("set-backend")
2875
2874
  def settings_set_backend(
2876
- url: str = typer.Argument(..., help="Backend base URL, e.g. https://api.main-sequence.io")
2875
+ url: str = typer.Argument(..., help=f"Backend base URL, e.g. {cfg.STANDARD_BACKEND_URL}")
2877
2876
  ):
2878
2877
  """
2879
2878
  Set backend base URL used by CLI API calls.
@@ -2881,12 +2880,12 @@ def settings_set_backend(
2881
2880
  Parameters
2882
2881
  ----------
2883
2882
  url:
2884
- Backend base URL (for example `https://api.main-sequence.io`).
2883
+ Backend base URL.
2885
2884
 
2886
2885
  Examples
2887
2886
  --------
2888
2887
  ```bash
2889
- mainsequence settings set-backend https://api.main-sequence.io
2888
+ mainsequence settings set-backend <backend-url>
2890
2889
  ```
2891
2890
  """
2892
2891
  out = cfg.set_backend_url(url)
@@ -2899,7 +2898,7 @@ def _settings_reset_impl() -> dict:
2899
2898
  """
2900
2899
  Reset persistent CLI settings to standard defaults and clear session overrides.
2901
2900
  """
2902
- standard_backend = cfg.normalize_backend_url(LOGIN_DEFAULT_BACKEND_URL)
2901
+ standard_backend = cfg.normalize_backend_url(cfg.STANDARD_BACKEND_URL)
2903
2902
  standard_base = cfg.normalize_mainsequence_path(cfg.DEFAULTS.get("mainsequence_path"))
2904
2903
  pathlib.Path(standard_base).mkdir(parents=True, exist_ok=True)
2905
2904
  out = cfg.set_config(
@@ -2917,7 +2916,7 @@ def settings_reset():
2917
2916
  """
2918
2917
  Reset CLI settings to standard defaults.
2919
2918
 
2920
- Resets backend URL to `https://api.main-sequence.io`, base folder to the
2919
+ Resets backend URL to the standard production backend, base folder to the
2921
2920
  default `~/mainsequence`, and clears current terminal session overrides.
2922
2921
 
2923
2922
  Examples
@@ -21,6 +21,8 @@ import subprocess
21
21
  import sys
22
22
  import time
23
23
 
24
+ from mainsequence.defaults import STANDARD_BACKEND_URL
25
+
24
26
  APP_NAME = "MainSequenceCLI"
25
27
 
26
28
 
@@ -62,7 +64,7 @@ KEYCHAIN_SERVICE = "MainSequenceCLI.auth"
62
64
  KEYCHAIN_ACCOUNT = "default"
63
65
 
64
66
  DEFAULTS = {
65
- "backend_url": os.environ.get("MAIN_SEQUENCE_BACKEND_URL", "https://api.main-sequence.io/"),
67
+ "backend_url": os.environ.get("MAIN_SEQUENCE_BACKEND_URL", f"{STANDARD_BACKEND_URL}/"),
66
68
  "mainsequence_path": str(pathlib.Path.home() / "mainsequence"),
67
69
  "version": 1,
68
70
  }
@@ -212,7 +214,7 @@ def set_backend_url(url: str) -> dict:
212
214
  Convenience helper to set backend_url in config.json.
213
215
 
214
216
  Args:
215
- url: Backend base URL (e.g. https://api.main-sequence.io)
217
+ url: Backend base URL.
216
218
 
217
219
  Returns:
218
220
  dict: updated config
@@ -7,6 +7,8 @@ from typing import Any
7
7
 
8
8
  import requests
9
9
 
10
+ from mainsequence.defaults import STANDARD_BACKEND_URL
11
+
10
12
  from .exceptions import raise_for_response
11
13
  from .utils import AuthLoaders, build_session
12
14
  from .utils import loaders as _global_loaders
@@ -19,7 +21,7 @@ class MainSequenceClientConfig:
19
21
  endpoint: str = (
20
22
  os.getenv("MAINSEQUENCE_ENDPOINT")
21
23
  or os.getenv("TDAG_ENDPOINT")
22
- or "https://api.main-sequence.app"
24
+ or STANDARD_BACKEND_URL
23
25
  )
24
26
  api_prefix: str = "/orm/api"
25
27
  # (connect, read) — align with your utils DEFAULT_TIMEOUT behavior
@@ -7,6 +7,8 @@ from pathlib import Path
7
7
  from typing import Any
8
8
  from urllib.parse import urlparse
9
9
 
10
+ from mainsequence.defaults import STANDARD_BACKEND_URL
11
+
10
12
  from ..client import MainSequenceClientConfig
11
13
  from ..utils import AuthLoaders
12
14
 
@@ -78,7 +80,7 @@ def _infer_command_center_url_from_endpoint(endpoint: str) -> str:
78
80
  if host in {"localhost", "127.0.0.1"}:
79
81
  return f"{scheme}://localhost:5173"
80
82
 
81
- if host == "api.main-sequence.app":
83
+ if host == (urlparse(STANDARD_BACKEND_URL).hostname or ""):
82
84
  return f"{scheme}://main-sequence.app"
83
85
 
84
86
  if host.startswith("api."):
@@ -649,6 +649,13 @@ class SimpleTableUpdate(TableUpdateNode, BaseObjectOrm):
649
649
  description="Simple table storage referenced by this update.",
650
650
  )
651
651
  tags: list[str] | None = Field(default=[], description="List of tags")
652
+ labels: list[str] = Field(
653
+ default_factory=list,
654
+ description=(
655
+ "Organizational labels attached to the simple table update. "
656
+ "These are helpers for grouping and discovery only and do not change runtime behavior or functionality."
657
+ ),
658
+ )
652
659
  description: str | None = Field(None, description="Optional HTML description")
653
660
  update_details: SimpleTableUpdateDetails | int | None = None
654
661
  run_configuration: SimpleTableRunConfiguration | None = None
@@ -275,6 +275,13 @@ class DataNodeUpdate(TableUpdateNode, BaseObjectOrm):
275
275
 
276
276
  data_node_storage: int | DataNodeStorage
277
277
  tags: list[str] | None = Field(default=[], description="List of tags")
278
+ labels: list[str] = Field(
279
+ default_factory=list,
280
+ description=(
281
+ "Organizational labels attached to the local time series update. "
282
+ "These are helpers for grouping and discovery only and do not change runtime behavior or functionality."
283
+ ),
284
+ )
278
285
  description: str | None = Field(None, description="Optional HTML description")
279
286
  update_details: DataNodeUpdateDetails | int | None = None
280
287
  run_configuration: RunConfiguration | None = None
@@ -8,6 +8,7 @@ from typing import Any, ClassVar, Literal
8
8
 
9
9
  from pydantic import Field
10
10
 
11
+ from mainsequence.defaults import STANDARD_BACKEND_URL
11
12
  from mainsequence.logconf import logger
12
13
 
13
14
  from .base import (
@@ -141,7 +142,7 @@ class Organization(BasePydanticModel):
141
142
  None,
142
143
  title="Organization URL",
143
144
  description="Optional public or internal URL for the organization.",
144
- examples=["https://api.main-sequence.app"],
145
+ examples=[STANDARD_BACKEND_URL],
145
146
  )
146
147
  organization_domain: str = Field(
147
148
  ...,
@@ -21,13 +21,14 @@ from requests.adapters import HTTPAdapter
21
21
  from requests.structures import CaseInsensitiveDict
22
22
  from urllib3.util.retry import Retry
23
23
 
24
+ from mainsequence.defaults import STANDARD_BACKEND_URL
24
25
  from mainsequence.logconf import logger
25
26
 
26
27
  # ---- Backend defaults (single source of truth) ----
27
28
  TDAG_ENDPOINT = (
28
29
  os.environ.get("TDAG_ENDPOINT")
29
30
  or os.environ.get("MAINSEQUENCE_ENDPOINT")
30
- or "https://api.main-sequence.app"
31
+ or STANDARD_BACKEND_URL
31
32
  )
32
33
  API_ENDPOINT = f"{TDAG_ENDPOINT}/orm/api"
33
34
  AUTH_ENDPOINT = TDAG_ENDPOINT.rstrip("/")
@@ -72,8 +73,8 @@ class AuthError(Exception):
72
73
  def _jwt_reauth_hint() -> str:
73
74
  return (
74
75
  " Refresh your credentials with `mainsequence logout` and "
75
- "`mainsequence login <email>`. If this code runs in a separate shell or IDE, "
76
- "use `mainsequence login <email> --export` and load the exported env vars there."
76
+ "`mainsequence login`. If this code runs in a separate shell or IDE, "
77
+ "use `mainsequence login --export` and load the exported env vars there."
77
78
  )
78
79
 
79
80
 
@@ -0,0 +1,3 @@
1
+ from __future__ import annotations
2
+
3
+ STANDARD_BACKEND_URL = "https://api.main-sequence.app"
@@ -17,6 +17,7 @@ from structlog.contextvars import bind_contextvars, unbind_contextvars
17
17
  from structlog.dev import ConsoleRenderer
18
18
  from structlog.stdlib import BoundLogger
19
19
 
20
+ from .defaults import STANDARD_BACKEND_URL
20
21
  from .instrumentation import OTelJSONRenderer
21
22
  from .runtime_flags import is_running_in_pod
22
23
 
@@ -70,7 +71,7 @@ def _request_job_startup_state(*, timeout_s: float = 10.0) -> dict[str, Any]:
70
71
  return (
71
72
  os.getenv("TDAG_ENDPOINT")
72
73
  or os.getenv("MAINSEQUENCE_ENDPOINT")
73
- or "https://api.main-sequence.app"
74
+ or STANDARD_BACKEND_URL
74
75
  ).rstrip("/")
75
76
 
76
77
  def _auth_headers() -> tuple[CaseInsensitiveDict, bool]:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mainsequence
3
- Version: 3.18.4
3
+ Version: 3.18.6
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
@@ -23,6 +23,7 @@ mainsequence/__init__.py
23
23
  mainsequence/__main__.py
24
24
  mainsequence/bootstrap.py
25
25
  mainsequence/compute_validation.py
26
+ mainsequence/defaults.py
26
27
  mainsequence/logconf.py
27
28
  mainsequence/runtime_flags.py
28
29
  mainsequence.egg-info/PKG-INFO
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "mainsequence"
7
- version = "3.18.4"
7
+ version = "3.18.6"
8
8
  description = "Main Sequence SDK "
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
@@ -1540,6 +1540,46 @@ def test_settings_set_backend_json(cli_mod, runner, monkeypatch):
1540
1540
  assert payload["backend_url"] == "https://example.test"
1541
1541
 
1542
1542
 
1543
+ def test_settings_reset(cli_mod, runner, monkeypatch):
1544
+ captured = {}
1545
+ monkeypatch.setattr(
1546
+ cli_mod.cfg,
1547
+ "DEFAULTS",
1548
+ {"backend_url": f"{cli_mod.cfg.STANDARD_BACKEND_URL}/", "mainsequence_path": "/tmp/mainsequence", "version": 1},
1549
+ )
1550
+ monkeypatch.setattr(
1551
+ cli_mod.cfg,
1552
+ "set_config",
1553
+ lambda updates: captured.update(updates) or updates | {"updated_at": "2026-04-20T00:00:00Z"},
1554
+ )
1555
+ monkeypatch.setattr(cli_mod.cfg, "clear_session_overrides", lambda: captured.update(cleared=True))
1556
+
1557
+ result = runner.invoke(cli_mod.app, ["settings", "reset"])
1558
+ assert result.exit_code == 0
1559
+ assert captured["backend_url"] == cli_mod.cfg.STANDARD_BACKEND_URL
1560
+ assert captured["mainsequence_path"].endswith("/tmp/mainsequence")
1561
+ assert captured["cleared"] is True
1562
+ assert "Settings reset to standard defaults" in result.output
1563
+
1564
+
1565
+ def test_settings_refresh_alias(cli_mod, runner, monkeypatch):
1566
+ monkeypatch.setattr(
1567
+ cli_mod.cfg,
1568
+ "DEFAULTS",
1569
+ {"backend_url": f"{cli_mod.cfg.STANDARD_BACKEND_URL}/", "mainsequence_path": "/tmp/mainsequence", "version": 1},
1570
+ )
1571
+ monkeypatch.setattr(
1572
+ cli_mod.cfg,
1573
+ "set_config",
1574
+ lambda updates: updates | {"updated_at": "2026-04-20T00:00:00Z"},
1575
+ )
1576
+ monkeypatch.setattr(cli_mod.cfg, "clear_session_overrides", lambda: None)
1577
+
1578
+ result = runner.invoke(cli_mod.app, ["settings", "refresh"])
1579
+ assert result.exit_code == 0
1580
+ assert "Settings reset to standard defaults" in result.output
1581
+
1582
+
1543
1583
  def test_config_normalize_backend_url(cli_mod):
1544
1584
  assert cli_mod.cfg.normalize_backend_url("127.0.0.1:800") == "http://127.0.0.1:800"
1545
1585
  assert cli_mod.cfg.normalize_backend_url("localhost:8000") == "http://localhost:8000"
@@ -1582,7 +1622,7 @@ def test_config_session_overrides_do_not_persist(cli_mod, monkeypatch, tmp_path)
1582
1622
 
1583
1623
 
1584
1624
  def test_login_mocked(cli_mod, runner, monkeypatch):
1585
- cleared = {"called": False}
1625
+ session_override = {}
1586
1626
  monkeypatch.setattr(
1587
1627
  cli_mod,
1588
1628
  "login_via_browser",
@@ -1600,7 +1640,11 @@ def test_login_mocked(cli_mod, runner, monkeypatch):
1600
1640
  lambda: {"mainsequence_path": "/tmp/mainsequence"},
1601
1641
  )
1602
1642
  monkeypatch.setattr(cli_mod.cfg, "auth_persistence_label", lambda: "secure OS storage")
1603
- monkeypatch.setattr(cli_mod.cfg, "clear_session_overrides", lambda: cleared.update(called=True))
1643
+ monkeypatch.setattr(
1644
+ cli_mod.cfg,
1645
+ "set_session_overrides",
1646
+ lambda **kwargs: session_override.update(kwargs) or kwargs,
1647
+ )
1604
1648
  monkeypatch.setattr(
1605
1649
  cli_mod,
1606
1650
  "get_projects",
@@ -1616,7 +1660,11 @@ def test_login_mocked(cli_mod, runner, monkeypatch):
1616
1660
  assert "__ __" in result.output
1617
1661
  assert "Signed in as user@example.com" in result.output
1618
1662
  assert "Auth tokens are persisted in secure OS storage" in result.output
1619
- assert cleared["called"] is True
1663
+ assert cli_mod.cfg.STANDARD_BACKEND_URL in result.output
1664
+ assert session_override == {
1665
+ "backend_url": cli_mod.cfg.STANDARD_BACKEND_URL,
1666
+ "mainsequence_path": None,
1667
+ }
1620
1668
 
1621
1669
 
1622
1670
  def test_login_with_backend_override(cli_mod, runner, monkeypatch):
@@ -1736,7 +1784,7 @@ def test_login_export_env(cli_mod, runner, monkeypatch):
1736
1784
  "get_config",
1737
1785
  lambda: {"mainsequence_path": "/tmp/mainsequence"},
1738
1786
  )
1739
- monkeypatch.setattr(cli_mod.cfg, "clear_session_overrides", lambda: None)
1787
+ monkeypatch.setattr(cli_mod.cfg, "set_session_overrides", lambda **kwargs: kwargs)
1740
1788
  monkeypatch.setattr(
1741
1789
  cli_mod,
1742
1790
  "get_projects",
@@ -1755,7 +1803,7 @@ def test_login_export_env(cli_mod, runner, monkeypatch):
1755
1803
 
1756
1804
  def test_login_with_jwt_tokens(cli_mod, runner, monkeypatch):
1757
1805
  saved = {}
1758
- cleared = {"called": False}
1806
+ session_override = {}
1759
1807
 
1760
1808
  monkeypatch.setattr(
1761
1809
  cli_mod.cfg,
@@ -1770,7 +1818,11 @@ def test_login_with_jwt_tokens(cli_mod, runner, monkeypatch):
1770
1818
  lambda: {"mainsequence_path": "/tmp/mainsequence"},
1771
1819
  )
1772
1820
  monkeypatch.setattr(cli_mod.cfg, "auth_persistence_label", lambda: "local CLI auth storage")
1773
- monkeypatch.setattr(cli_mod.cfg, "clear_session_overrides", lambda: cleared.update(called=True))
1821
+ monkeypatch.setattr(
1822
+ cli_mod.cfg,
1823
+ "set_session_overrides",
1824
+ lambda **kwargs: session_override.update(kwargs) or kwargs,
1825
+ )
1774
1826
  monkeypatch.setattr(
1775
1827
  cli_mod,
1776
1828
  "get_projects",
@@ -1792,11 +1844,14 @@ def test_login_with_jwt_tokens(cli_mod, runner, monkeypatch):
1792
1844
  assert saved == {"username": "", "access": "acc-123", "refresh": "ref-456"}
1793
1845
  assert "Signed in with JWT tokens" in result.output
1794
1846
  assert "Auth tokens are persisted in local CLI auth storage" in result.output
1795
- assert cleared["called"] is True
1847
+ assert session_override == {
1848
+ "backend_url": cli_mod.cfg.STANDARD_BACKEND_URL,
1849
+ "mainsequence_path": None,
1850
+ }
1796
1851
 
1797
1852
 
1798
1853
  def test_login_runtime_credential_exchanges_token(cli_mod, runner, monkeypatch):
1799
- cleared = {"called": False}
1854
+ session_override = {}
1800
1855
  exchange = {"called": False}
1801
1856
  saved = {}
1802
1857
 
@@ -1825,7 +1880,11 @@ def test_login_runtime_credential_exchanges_token(cli_mod, runner, monkeypatch):
1825
1880
  lambda: {"mainsequence_path": "/tmp/mainsequence"},
1826
1881
  )
1827
1882
  monkeypatch.setattr(cli_mod.cfg, "auth_persistence_label", lambda: "local CLI auth storage")
1828
- monkeypatch.setattr(cli_mod.cfg, "clear_session_overrides", lambda: cleared.update(called=True))
1883
+ monkeypatch.setattr(
1884
+ cli_mod.cfg,
1885
+ "set_session_overrides",
1886
+ lambda **kwargs: session_override.update(kwargs) or kwargs,
1887
+ )
1829
1888
 
1830
1889
  result = runner.invoke(cli_mod.app, ["login"])
1831
1890
 
@@ -1837,7 +1896,10 @@ def test_login_runtime_credential_exchanges_token(cli_mod, runner, monkeypatch):
1837
1896
  assert "Signed in with runtime credential" in result.output
1838
1897
  assert "no CLI JWT refresh token exists" in result.output
1839
1898
  assert "re-exchange the runtime credential automatically" in result.output
1840
- assert cleared["called"] is True
1899
+ assert session_override == {
1900
+ "backend_url": cli_mod.cfg.STANDARD_BACKEND_URL,
1901
+ "mainsequence_path": None,
1902
+ }
1841
1903
 
1842
1904
 
1843
1905
  def test_login_runtime_credential_export(monkeypatch, cli_mod, runner):
@@ -1852,7 +1914,7 @@ def test_login_runtime_credential_export(monkeypatch, cli_mod, runner):
1852
1914
  "get_config",
1853
1915
  lambda: {"mainsequence_path": "/tmp/mainsequence"},
1854
1916
  )
1855
- monkeypatch.setattr(cli_mod.cfg, "clear_session_overrides", lambda: None)
1917
+ monkeypatch.setattr(cli_mod.cfg, "set_session_overrides", lambda **kwargs: kwargs)
1856
1918
 
1857
1919
  result = runner.invoke(cli_mod.app, ["login", "--export"])
1858
1920
 
@@ -2040,7 +2102,7 @@ def test_login_export_env_with_jwt_tokens_omits_username(cli_mod, runner, monkey
2040
2102
  "get_config",
2041
2103
  lambda: {"mainsequence_path": "/tmp/mainsequence"},
2042
2104
  )
2043
- monkeypatch.setattr(cli_mod.cfg, "clear_session_overrides", lambda: None)
2105
+ monkeypatch.setattr(cli_mod.cfg, "set_session_overrides", lambda **kwargs: kwargs)
2044
2106
 
2045
2107
  result = runner.invoke(
2046
2108
  cli_mod.app,
@@ -2078,7 +2140,7 @@ def test_login_warns_when_secure_persist_fails(cli_mod, runner, monkeypatch):
2078
2140
  )
2079
2141
  monkeypatch.setattr(cli_mod.cfg, "save_tokens", lambda username, access, refresh: False)
2080
2142
  monkeypatch.setattr(cli_mod.cfg, "auth_persistence_label", lambda: "secure OS storage")
2081
- monkeypatch.setattr(cli_mod.cfg, "clear_session_overrides", lambda: None)
2143
+ monkeypatch.setattr(cli_mod.cfg, "set_session_overrides", lambda **kwargs: kwargs)
2082
2144
  monkeypatch.setattr(
2083
2145
  cli_mod,
2084
2146
  "get_projects",
@@ -2111,7 +2173,7 @@ def test_login_does_not_fetch_projects_after_success(cli_mod, runner, monkeypatc
2111
2173
  lambda: {"mainsequence_path": "/tmp/mainsequence"},
2112
2174
  )
2113
2175
  monkeypatch.setattr(cli_mod.cfg, "auth_persistence_label", lambda: "local CLI auth storage")
2114
- monkeypatch.setattr(cli_mod.cfg, "clear_session_overrides", lambda: None)
2176
+ monkeypatch.setattr(cli_mod.cfg, "set_session_overrides", lambda **kwargs: kwargs)
2115
2177
  monkeypatch.setattr(
2116
2178
  cli_mod,
2117
2179
  "get_projects",
@@ -2135,7 +2197,7 @@ def test_jwt_login_does_not_fetch_projects_after_success(cli_mod, runner, monkey
2135
2197
  lambda: {"mainsequence_path": "/tmp/mainsequence"},
2136
2198
  )
2137
2199
  monkeypatch.setattr(cli_mod.cfg, "auth_persistence_label", lambda: "local CLI auth storage")
2138
- monkeypatch.setattr(cli_mod.cfg, "clear_session_overrides", lambda: None)
2200
+ monkeypatch.setattr(cli_mod.cfg, "set_session_overrides", lambda **kwargs: kwargs)
2139
2201
  monkeypatch.setattr(
2140
2202
  cli_mod,
2141
2203
  "get_projects",
@@ -2193,7 +2255,7 @@ def test_login_no_open_prints_authorize_url(cli_mod, runner, monkeypatch):
2193
2255
  lambda: {"mainsequence_path": "/tmp/mainsequence"},
2194
2256
  )
2195
2257
  monkeypatch.setattr(cli_mod.cfg, "auth_persistence_label", lambda: "local CLI auth storage")
2196
- monkeypatch.setattr(cli_mod.cfg, "clear_session_overrides", lambda: None)
2258
+ monkeypatch.setattr(cli_mod.cfg, "set_session_overrides", lambda **kwargs: kwargs)
2197
2259
  monkeypatch.setattr(cli_mod.cfg, "save_tokens", lambda username, access, refresh: True)
2198
2260
  monkeypatch.setattr(cli_mod, "get_current_user_profile", lambda: {"username": "user@example.com"})
2199
2261
 
@@ -7,8 +7,14 @@ import pandas as pd
7
7
  import pytest
8
8
  from pydantic import ValidationError
9
9
 
10
- from mainsequence.client.models_simple_tables import SimpleTableStorage
11
- from mainsequence.client.models_tdag import DataNodeStorage, DataNodeUpdate, DataNodeUpdateDetails
10
+ from mainsequence.client.command_center import Workspace
11
+ from mainsequence.client.models_simple_tables import SimpleTableStorage, SimpleTableUpdate
12
+ from mainsequence.client.models_tdag import (
13
+ DataNodeStorage,
14
+ DataNodeUpdate,
15
+ DataNodeUpdateDetails,
16
+ Project,
17
+ )
12
18
  from mainsequence.tdag import DataNode
13
19
  from mainsequence.tdag.data_nodes.models import RecordDefinition
14
20
  from mainsequence.tdag.data_nodes.run_operations import UpdateRunner
@@ -55,6 +61,18 @@ def test_data_node_storage_accepts_namespace():
55
61
  assert storage.namespace == "pytest_case_123"
56
62
 
57
63
 
64
+ def test_data_node_update_accepts_labels():
65
+ update = DataNodeUpdate(
66
+ id=44,
67
+ update_hash="issue-44-update-hash",
68
+ data_node_storage=1,
69
+ build_configuration={},
70
+ labels=["pricing", "daily"],
71
+ )
72
+
73
+ assert update.labels == ["pricing", "daily"]
74
+
75
+
58
76
  def test_simple_table_storage_accepts_namespace():
59
77
  storage = SimpleTableStorage(
60
78
  id=15,
@@ -68,6 +86,57 @@ def test_simple_table_storage_accepts_namespace():
68
86
  assert storage.namespace == "pytest_case_456"
69
87
 
70
88
 
89
+ def test_simple_table_update_accepts_labels():
90
+ update = SimpleTableUpdate(
91
+ id=44,
92
+ update_hash="simple-table-update-hash",
93
+ remote_table=1,
94
+ build_configuration={},
95
+ labels=["reference", "daily"],
96
+ )
97
+
98
+ assert update.labels == ["reference", "daily"]
99
+
100
+
101
+ def test_label_fields_exist_on_workspace_project_and_storage_models():
102
+ workspace = Workspace(
103
+ id=1,
104
+ title="Workspace",
105
+ schemaVersion=1,
106
+ layoutKind="custom",
107
+ createdAt="2026-04-20T00:00:00Z",
108
+ updatedAt="2026-04-20T00:00:00Z",
109
+ labels=["desk"],
110
+ )
111
+ project = Project(
112
+ id=1,
113
+ project_name="Project",
114
+ is_initialized=True,
115
+ labels=["research"],
116
+ )
117
+ data_node_storage = DataNodeStorage(
118
+ id=12,
119
+ storage_hash="prices_storage_hash",
120
+ data_source=1,
121
+ source_class_name="PricesNode",
122
+ creation_date="2026-04-13T00:00:00Z",
123
+ labels=["market-data"],
124
+ )
125
+ simple_table_storage = SimpleTableStorage(
126
+ id=15,
127
+ storage_hash="orders_storage_hash",
128
+ data_source={"id": 1},
129
+ schema={"model": "tests.OrderRow", "fields": []},
130
+ source_class_name="OrderUpdater",
131
+ labels=["reference-data"],
132
+ )
133
+
134
+ assert workspace.labels == ["desk"]
135
+ assert project.labels == ["research"]
136
+ assert data_node_storage.labels == ["market-data"]
137
+ assert simple_table_storage.labels == ["reference-data"]
138
+
139
+
71
140
  def test_record_definition_rejects_column_names_longer_than_63_characters():
72
141
  with pytest.raises(ValidationError, match="at most 63 characters"):
73
142
  RecordDefinition(
File without changes
File without changes