mainsequence 4.4.26__tar.gz → 4.4.27__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 (161) hide show
  1. {mainsequence-4.4.26 → mainsequence-4.4.27}/PKG-INFO +1 -1
  2. {mainsequence-4.4.26 → mainsequence-4.4.27}/mainsequence/client/models_user.py +55 -13
  3. {mainsequence-4.4.26 → mainsequence-4.4.27}/mainsequence.egg-info/PKG-INFO +1 -1
  4. {mainsequence-4.4.26 → mainsequence-4.4.27}/pyproject.toml +1 -1
  5. {mainsequence-4.4.26 → mainsequence-4.4.27}/tests/test_models_user_request_bound_auth.py +87 -0
  6. {mainsequence-4.4.26 → mainsequence-4.4.27}/LICENSE +0 -0
  7. {mainsequence-4.4.26 → mainsequence-4.4.27}/README.md +0 -0
  8. {mainsequence-4.4.26 → mainsequence-4.4.27}/agent_scaffold/AGENTS.md +0 -0
  9. {mainsequence-4.4.26 → mainsequence-4.4.27}/agent_scaffold/skills/a2a_communication/SKILL.md +0 -0
  10. {mainsequence-4.4.26 → mainsequence-4.4.27}/agent_scaffold/skills/application_surfaces/api_surfaces/SKILL.md +0 -0
  11. {mainsequence-4.4.26 → mainsequence-4.4.27}/agent_scaffold/skills/command_center/adapter_from_api/SKILL.md +0 -0
  12. {mainsequence-4.4.26 → mainsequence-4.4.27}/agent_scaffold/skills/command_center/api_mock_prototyping/SKILL.md +0 -0
  13. {mainsequence-4.4.26 → mainsequence-4.4.27}/agent_scaffold/skills/command_center/connections/SKILL.md +0 -0
  14. {mainsequence-4.4.26 → mainsequence-4.4.27}/agent_scaffold/skills/command_center/widgets/app_components/SKILL.md +0 -0
  15. {mainsequence-4.4.26 → mainsequence-4.4.27}/agent_scaffold/skills/command_center/widgets/tables/SKILL.md +0 -0
  16. {mainsequence-4.4.26 → mainsequence-4.4.27}/agent_scaffold/skills/command_center/widgets/tabular_transform/SKILL.md +0 -0
  17. {mainsequence-4.4.26 → mainsequence-4.4.27}/agent_scaffold/skills/command_center/workspace_analysis/SKILL.md +0 -0
  18. {mainsequence-4.4.26 → mainsequence-4.4.27}/agent_scaffold/skills/command_center/workspace_builder/SKILL.md +0 -0
  19. {mainsequence-4.4.26 → mainsequence-4.4.27}/agent_scaffold/skills/command_center/workspace_design/SKILL.md +0 -0
  20. {mainsequence-4.4.26 → mainsequence-4.4.27}/agent_scaffold/skills/dashboards/streamlit/SKILL.md +0 -0
  21. {mainsequence-4.4.26 → mainsequence-4.4.27}/agent_scaffold/skills/data_access/exploration/SKILL.md +0 -0
  22. {mainsequence-4.4.26 → mainsequence-4.4.27}/agent_scaffold/skills/data_publishing/data_nodes/SKILL.md +0 -0
  23. {mainsequence-4.4.26 → mainsequence-4.4.27}/agent_scaffold/skills/data_publishing/meta_table_migrations/SKILL.md +0 -0
  24. {mainsequence-4.4.26 → mainsequence-4.4.27}/agent_scaffold/skills/data_publishing/meta_tables/SKILL.md +0 -0
  25. {mainsequence-4.4.26 → mainsequence-4.4.27}/agent_scaffold/skills/maintenance/bug_auditor/SKILL.md +0 -0
  26. {mainsequence-4.4.26 → mainsequence-4.4.27}/agent_scaffold/skills/ms-markets/SKILL.md +0 -0
  27. {mainsequence-4.4.26 → mainsequence-4.4.27}/agent_scaffold/skills/platform_operations/access_control_and_sharing/SKILL.md +0 -0
  28. {mainsequence-4.4.26 → mainsequence-4.4.27}/agent_scaffold/skills/platform_operations/orchestration_and_releases/SKILL.md +0 -0
  29. {mainsequence-4.4.26 → mainsequence-4.4.27}/agent_scaffold/skills/project_builder/SKILL.md +0 -0
  30. {mainsequence-4.4.26 → mainsequence-4.4.27}/agent_scaffold/skills/project_to_agent/SKILL.md +0 -0
  31. {mainsequence-4.4.26 → mainsequence-4.4.27}/mainsequence/__init__.py +0 -0
  32. {mainsequence-4.4.26 → mainsequence-4.4.27}/mainsequence/__main__.py +0 -0
  33. {mainsequence-4.4.26 → mainsequence-4.4.27}/mainsequence/bootstrap.py +0 -0
  34. {mainsequence-4.4.26 → mainsequence-4.4.27}/mainsequence/cli/__init__.py +0 -0
  35. {mainsequence-4.4.26 → mainsequence-4.4.27}/mainsequence/cli/api.py +0 -0
  36. {mainsequence-4.4.26 → mainsequence-4.4.27}/mainsequence/cli/browser_auth.py +0 -0
  37. {mainsequence-4.4.26 → mainsequence-4.4.27}/mainsequence/cli/cli.py +0 -0
  38. {mainsequence-4.4.26 → mainsequence-4.4.27}/mainsequence/cli/config.py +0 -0
  39. {mainsequence-4.4.26 → mainsequence-4.4.27}/mainsequence/cli/docker_utils.py +0 -0
  40. {mainsequence-4.4.26 → mainsequence-4.4.27}/mainsequence/cli/doctor.py +0 -0
  41. {mainsequence-4.4.26 → mainsequence-4.4.27}/mainsequence/cli/local_ops.py +0 -0
  42. {mainsequence-4.4.26 → mainsequence-4.4.27}/mainsequence/cli/migrations.py +0 -0
  43. {mainsequence-4.4.26 → mainsequence-4.4.27}/mainsequence/cli/model_filters.py +0 -0
  44. {mainsequence-4.4.26 → mainsequence-4.4.27}/mainsequence/cli/project_status.py +0 -0
  45. {mainsequence-4.4.26 → mainsequence-4.4.27}/mainsequence/cli/pydantic_cli.py +0 -0
  46. {mainsequence-4.4.26 → mainsequence-4.4.27}/mainsequence/cli/sdk_utils.py +0 -0
  47. {mainsequence-4.4.26 → mainsequence-4.4.27}/mainsequence/cli/ssh_utils.py +0 -0
  48. {mainsequence-4.4.26 → mainsequence-4.4.27}/mainsequence/cli/ui.py +0 -0
  49. {mainsequence-4.4.26 → mainsequence-4.4.27}/mainsequence/client/__init__.py +0 -0
  50. {mainsequence-4.4.26 → mainsequence-4.4.27}/mainsequence/client/agent_runtime_models.py +0 -0
  51. {mainsequence-4.4.26 → mainsequence-4.4.27}/mainsequence/client/base.py +0 -0
  52. {mainsequence-4.4.26 → mainsequence-4.4.27}/mainsequence/client/client.py +0 -0
  53. {mainsequence-4.4.26 → mainsequence-4.4.27}/mainsequence/client/command_center/__init__.py +0 -0
  54. {mainsequence-4.4.26 → mainsequence-4.4.27}/mainsequence/client/command_center/app_component.py +0 -0
  55. {mainsequence-4.4.26 → mainsequence-4.4.27}/mainsequence/client/command_center/connections.py +0 -0
  56. {mainsequence-4.4.26 → mainsequence-4.4.27}/mainsequence/client/command_center/contracts/__init__.py +0 -0
  57. {mainsequence-4.4.26 → mainsequence-4.4.27}/mainsequence/client/command_center/contracts/adapter_from_api.py +0 -0
  58. {mainsequence-4.4.26 → mainsequence-4.4.27}/mainsequence/client/command_center/contracts/response_mapping.py +0 -0
  59. {mainsequence-4.4.26 → mainsequence-4.4.27}/mainsequence/client/command_center/contracts/table_visuals.py +0 -0
  60. {mainsequence-4.4.26 → mainsequence-4.4.27}/mainsequence/client/command_center/contracts/tabular.py +0 -0
  61. {mainsequence-4.4.26 → mainsequence-4.4.27}/mainsequence/client/command_center/contracts/ui.py +0 -0
  62. {mainsequence-4.4.26 → mainsequence-4.4.27}/mainsequence/client/command_center/data_models.py +0 -0
  63. {mainsequence-4.4.26 → mainsequence-4.4.27}/mainsequence/client/command_center/providers/__init__.py +0 -0
  64. {mainsequence-4.4.26 → mainsequence-4.4.27}/mainsequence/client/command_center/providers/adapter_from_api.py +0 -0
  65. {mainsequence-4.4.26 → mainsequence-4.4.27}/mainsequence/client/command_center/widgets/__init__.py +0 -0
  66. {mainsequence-4.4.26 → mainsequence-4.4.27}/mainsequence/client/command_center/widgets/bindings.py +0 -0
  67. {mainsequence-4.4.26 → mainsequence-4.4.27}/mainsequence/client/command_center/widgets/connection_query.py +0 -0
  68. {mainsequence-4.4.26 → mainsequence-4.4.27}/mainsequence/client/command_center/widgets/registry.py +0 -0
  69. {mainsequence-4.4.26 → mainsequence-4.4.27}/mainsequence/client/command_center/widgets/table.py +0 -0
  70. {mainsequence-4.4.26 → mainsequence-4.4.27}/mainsequence/client/command_center/widgets/tabular_transform.py +0 -0
  71. {mainsequence-4.4.26 → mainsequence-4.4.27}/mainsequence/client/command_center/workspace.py +0 -0
  72. {mainsequence-4.4.26 → mainsequence-4.4.27}/mainsequence/client/command_center/workspace_snapshot.py +0 -0
  73. {mainsequence-4.4.26 → mainsequence-4.4.27}/mainsequence/client/command_center/workspaces/__init__.py +0 -0
  74. {mainsequence-4.4.26 → mainsequence-4.4.27}/mainsequence/client/command_center/workspaces/documents.py +0 -0
  75. {mainsequence-4.4.26 → mainsequence-4.4.27}/mainsequence/client/command_center/workspaces/mounted_widgets.py +0 -0
  76. {mainsequence-4.4.26 → mainsequence-4.4.27}/mainsequence/client/compute_validation.py +0 -0
  77. {mainsequence-4.4.26 → mainsequence-4.4.27}/mainsequence/client/data_sources_interfaces/__init__.py +0 -0
  78. {mainsequence-4.4.26 → mainsequence-4.4.27}/mainsequence/client/data_sources_interfaces/duckdb.py +0 -0
  79. {mainsequence-4.4.26 → mainsequence-4.4.27}/mainsequence/client/data_sources_interfaces/local_paths.py +0 -0
  80. {mainsequence-4.4.26 → mainsequence-4.4.27}/mainsequence/client/data_sources_interfaces/sqlite.py +0 -0
  81. {mainsequence-4.4.26 → mainsequence-4.4.27}/mainsequence/client/dtype_codec.py +0 -0
  82. {mainsequence-4.4.26 → mainsequence-4.4.27}/mainsequence/client/exceptions.py +0 -0
  83. {mainsequence-4.4.26 → mainsequence-4.4.27}/mainsequence/client/fastapi/__init__.py +0 -0
  84. {mainsequence-4.4.26 → mainsequence-4.4.27}/mainsequence/client/fastapi/auth.py +0 -0
  85. {mainsequence-4.4.26 → mainsequence-4.4.27}/mainsequence/client/metatables/__init__.py +0 -0
  86. {mainsequence-4.4.26 → mainsequence-4.4.27}/mainsequence/client/metatables/core.py +0 -0
  87. {mainsequence-4.4.26 → mainsequence-4.4.27}/mainsequence/client/models_foundry.py +0 -0
  88. {mainsequence-4.4.26 → mainsequence-4.4.27}/mainsequence/client/models_helpers.py +0 -0
  89. {mainsequence-4.4.26 → mainsequence-4.4.27}/mainsequence/client/utils.py +0 -0
  90. {mainsequence-4.4.26 → mainsequence-4.4.27}/mainsequence/defaults.py +0 -0
  91. {mainsequence-4.4.26 → mainsequence-4.4.27}/mainsequence/instrumentation/__init__.py +0 -0
  92. {mainsequence-4.4.26 → mainsequence-4.4.27}/mainsequence/instrumentation/utils.py +0 -0
  93. {mainsequence-4.4.26 → mainsequence-4.4.27}/mainsequence/logconf.py +0 -0
  94. {mainsequence-4.4.26 → mainsequence-4.4.27}/mainsequence/meta_tables/__init__.py +0 -0
  95. {mainsequence-4.4.26 → mainsequence-4.4.27}/mainsequence/meta_tables/__main__.py +0 -0
  96. {mainsequence-4.4.26 → mainsequence-4.4.27}/mainsequence/meta_tables/compiled_sql/__init__.py +0 -0
  97. {mainsequence-4.4.26 → mainsequence-4.4.27}/mainsequence/meta_tables/compiled_sql/v1.py +0 -0
  98. {mainsequence-4.4.26 → mainsequence-4.4.27}/mainsequence/meta_tables/data_nodes/__init__.py +0 -0
  99. {mainsequence-4.4.26 → mainsequence-4.4.27}/mainsequence/meta_tables/data_nodes/build_operations.py +0 -0
  100. {mainsequence-4.4.26 → mainsequence-4.4.27}/mainsequence/meta_tables/data_nodes/data_nodes.py +0 -0
  101. {mainsequence-4.4.26 → mainsequence-4.4.27}/mainsequence/meta_tables/data_nodes/models.py +0 -0
  102. {mainsequence-4.4.26 → mainsequence-4.4.27}/mainsequence/meta_tables/data_nodes/namespacing.py +0 -0
  103. {mainsequence-4.4.26 → mainsequence-4.4.27}/mainsequence/meta_tables/data_nodes/persist_managers.py +0 -0
  104. {mainsequence-4.4.26 → mainsequence-4.4.27}/mainsequence/meta_tables/data_nodes/run_operations.py +0 -0
  105. {mainsequence-4.4.26 → mainsequence-4.4.27}/mainsequence/meta_tables/data_nodes/utils.py +0 -0
  106. {mainsequence-4.4.26 → mainsequence-4.4.27}/mainsequence/meta_tables/future_registry.py +0 -0
  107. {mainsequence-4.4.26 → mainsequence-4.4.27}/mainsequence/meta_tables/hashing.py +0 -0
  108. {mainsequence-4.4.26 → mainsequence-4.4.27}/mainsequence/meta_tables/migrations/__init__.py +0 -0
  109. {mainsequence-4.4.26 → mainsequence-4.4.27}/mainsequence/meta_tables/migrations/alembic.py +0 -0
  110. {mainsequence-4.4.26 → mainsequence-4.4.27}/mainsequence/meta_tables/migrations/env.py +0 -0
  111. {mainsequence-4.4.26 → mainsequence-4.4.27}/mainsequence/meta_tables/migrations/provider.py +0 -0
  112. {mainsequence-4.4.26 → mainsequence-4.4.27}/mainsequence/meta_tables/migrations/registry.py +0 -0
  113. {mainsequence-4.4.26 → mainsequence-4.4.27}/mainsequence/meta_tables/migrations/scaffold.py +0 -0
  114. {mainsequence-4.4.26 → mainsequence-4.4.27}/mainsequence/meta_tables/migrations/templates/__init__.py +0 -0
  115. {mainsequence-4.4.26 → mainsequence-4.4.27}/mainsequence/meta_tables/migrations/templates/env.py.mako +0 -0
  116. {mainsequence-4.4.26 → mainsequence-4.4.27}/mainsequence/meta_tables/migrations/templates/script.py.mako +0 -0
  117. {mainsequence-4.4.26 → mainsequence-4.4.27}/mainsequence/meta_tables/pydantic_metadata.py +0 -0
  118. {mainsequence-4.4.26 → mainsequence-4.4.27}/mainsequence/meta_tables/schema_names.py +0 -0
  119. {mainsequence-4.4.26 → mainsequence-4.4.27}/mainsequence/meta_tables/sqlalchemy_contracts.py +0 -0
  120. {mainsequence-4.4.26 → mainsequence-4.4.27}/mainsequence/runtime_flags.py +0 -0
  121. {mainsequence-4.4.26 → mainsequence-4.4.27}/mainsequence/scaffold_skills.py +0 -0
  122. {mainsequence-4.4.26 → mainsequence-4.4.27}/mainsequence.egg-info/SOURCES.txt +0 -0
  123. {mainsequence-4.4.26 → mainsequence-4.4.27}/mainsequence.egg-info/dependency_links.txt +0 -0
  124. {mainsequence-4.4.26 → mainsequence-4.4.27}/mainsequence.egg-info/entry_points.txt +0 -0
  125. {mainsequence-4.4.26 → mainsequence-4.4.27}/mainsequence.egg-info/requires.txt +0 -0
  126. {mainsequence-4.4.26 → mainsequence-4.4.27}/mainsequence.egg-info/top_level.txt +0 -0
  127. {mainsequence-4.4.26 → mainsequence-4.4.27}/setup.cfg +0 -0
  128. {mainsequence-4.4.26 → mainsequence-4.4.27}/tests/test_auth_precedence.py +0 -0
  129. {mainsequence-4.4.26 → mainsequence-4.4.27}/tests/test_build_operations_hashing.py +0 -0
  130. {mainsequence-4.4.26 → mainsequence-4.4.27}/tests/test_cli.py +0 -0
  131. {mainsequence-4.4.26 → mainsequence-4.4.27}/tests/test_cli_browser_auth.py +0 -0
  132. {mainsequence-4.4.26 → mainsequence-4.4.27}/tests/test_cli_migrations.py +0 -0
  133. {mainsequence-4.4.26 → mainsequence-4.4.27}/tests/test_client.py +0 -0
  134. {mainsequence-4.4.26 → mainsequence-4.4.27}/tests/test_command_center_app_component_models.py +0 -0
  135. {mainsequence-4.4.26 → mainsequence-4.4.27}/tests/test_command_center_data_models.py +0 -0
  136. {mainsequence-4.4.26 → mainsequence-4.4.27}/tests/test_command_center_models.py +0 -0
  137. {mainsequence-4.4.26 → mainsequence-4.4.27}/tests/test_command_center_table_contracts.py +0 -0
  138. {mainsequence-4.4.26 → mainsequence-4.4.27}/tests/test_command_center_tabular_transform.py +0 -0
  139. {mainsequence-4.4.26 → mainsequence-4.4.27}/tests/test_data_access_mixin_dimension_audit.py +0 -0
  140. {mainsequence-4.4.26 → mainsequence-4.4.27}/tests/test_data_node_storage_dimension_queries.py +0 -0
  141. {mainsequence-4.4.26 → mainsequence-4.4.27}/tests/test_data_node_update_flow.py +0 -0
  142. {mainsequence-4.4.26 → mainsequence-4.4.27}/tests/test_dependency_extras.py +0 -0
  143. {mainsequence-4.4.26 → mainsequence-4.4.27}/tests/test_duckdb_interface_dimensions.py +0 -0
  144. {mainsequence-4.4.26 → mainsequence-4.4.27}/tests/test_filter_normalization.py +0 -0
  145. {mainsequence-4.4.26 → mainsequence-4.4.27}/tests/test_instrumentation.py +0 -0
  146. {mainsequence-4.4.26 → mainsequence-4.4.27}/tests/test_logconf.py +0 -0
  147. {mainsequence-4.4.26 → mainsequence-4.4.27}/tests/test_meta_table_migrations.py +0 -0
  148. {mainsequence-4.4.26 → mainsequence-4.4.27}/tests/test_meta_tables_client_models.py +0 -0
  149. {mainsequence-4.4.26 → mainsequence-4.4.27}/tests/test_meta_tables_sqlalchemy_contracts.py +0 -0
  150. {mainsequence-4.4.26 → mainsequence-4.4.27}/tests/test_pod_project_resolution.py +0 -0
  151. {mainsequence-4.4.26 → mainsequence-4.4.27}/tests/test_project_batch_jobs_from_file.py +0 -0
  152. {mainsequence-4.4.26 → mainsequence-4.4.27}/tests/test_run_configuration.py +0 -0
  153. {mainsequence-4.4.26 → mainsequence-4.4.27}/tests/test_scaffold_skills.py +0 -0
  154. {mainsequence-4.4.26 → mainsequence-4.4.27}/tests/test_schema_names.py +0 -0
  155. {mainsequence-4.4.26 → mainsequence-4.4.27}/tests/test_secret_client_model.py +0 -0
  156. {mainsequence-4.4.26 → mainsequence-4.4.27}/tests/test_source_table_configuration.py +0 -0
  157. {mainsequence-4.4.26 → mainsequence-4.4.27}/tests/test_sqlite_interface_dimensions.py +0 -0
  158. {mainsequence-4.4.26 → mainsequence-4.4.27}/tests/test_update_runner_uid_runtime.py +0 -0
  159. {mainsequence-4.4.26 → mainsequence-4.4.27}/tests/test_update_statistics.py +0 -0
  160. {mainsequence-4.4.26 → mainsequence-4.4.27}/tests/test_update_uid_guards.py +0 -0
  161. {mainsequence-4.4.26 → mainsequence-4.4.27}/tests/test_workspace_snapshot.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mainsequence
3
- Version: 4.4.26
3
+ Version: 4.4.27
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
@@ -6,7 +6,7 @@ from collections.abc import Mapping
6
6
  from contextvars import ContextVar
7
7
  from typing import Any, ClassVar, Literal
8
8
 
9
- from pydantic import Field
9
+ from pydantic import ConfigDict, Field, field_validator
10
10
 
11
11
  from mainsequence.defaults import STANDARD_BACKEND_URL
12
12
  from mainsequence.logconf import logger
@@ -175,12 +175,8 @@ class Organization(UserApiBaseObjectOrm, BasePydanticModel):
175
175
 
176
176
 
177
177
  class Group(BasePydanticModel):
178
- id: int = Field(
179
- ...,
180
- title="Group ID",
181
- description="Unique identifier of the permission group.",
182
- examples=[3],
183
- )
178
+ model_config = ConfigDict(extra="ignore")
179
+
184
180
  name: str = Field(
185
181
  ...,
186
182
  title="Group Name",
@@ -188,8 +184,12 @@ class Group(BasePydanticModel):
188
184
  examples=["Data Managers"],
189
185
  )
190
186
 
191
- normalized_name:str = Field()
192
-
187
+ normalized_name: str = Field(
188
+ ...,
189
+ title="Normalized Group Name",
190
+ description="Stable normalized permission group name returned by the user details API.",
191
+ examples=["data_managers"],
192
+ )
193
193
 
194
194
 
195
195
  class UserSummary(BasePydanticModel):
@@ -272,6 +272,23 @@ class ShareableTeamSummary(BasePydanticModel):
272
272
  )
273
273
 
274
274
 
275
+ class UserTeamSummary(BasePydanticModel):
276
+ model_config = ConfigDict(extra="ignore")
277
+
278
+ uid: str = Field(
279
+ ...,
280
+ title="Organization Team UID",
281
+ description="Stable public unique identifier of the organization team.",
282
+ examples=["3f1cc452-43ec-49cb-b2ba-87dbac164d29"],
283
+ )
284
+ name: str | None = Field(
285
+ None,
286
+ title="Team Name",
287
+ description="Human-readable organization team name when returned by the user details API.",
288
+ examples=["Research"],
289
+ )
290
+
291
+
275
292
  class TeamMembershipUpdateResult(BasePydanticModel):
276
293
  team_id: int | None = Field(
277
294
  None,
@@ -1050,21 +1067,46 @@ class User(UserApiBaseObjectOrm, BasePydanticModel):
1050
1067
  )
1051
1068
  user_permissions: list[int] = Field(
1052
1069
  default_factory=list,
1070
+ exclude=True,
1053
1071
  title="User Permissions",
1054
- description="Direct permission ids assigned to the user.",
1072
+ description="Legacy internal permission ids accepted only for older auth payloads.",
1055
1073
  examples=[[101, 202]],
1056
1074
  )
1057
- organization_teams: list[int | Team | dict[str, Any]] = Field(
1075
+ organization_teams: list[UserTeamSummary | Team | str] = Field(
1058
1076
  default_factory=list,
1059
1077
  title="Organization Teams",
1060
- description="Organization team identifiers or fully-expanded team objects for the user.",
1061
- examples=[[9, 12]],
1078
+ description="Organization team UIDs or nested team summaries for the user.",
1079
+ examples=[[{"uid": "3f1cc452-43ec-49cb-b2ba-87dbac164d29", "name": "Research"}]],
1062
1080
  )
1063
1081
 
1064
1082
  @property
1065
1083
  def effective_plan(self) -> Any | None:
1066
1084
  return self.plan if self.plan is not None else self.active_plan_type
1067
1085
 
1086
+ @field_validator("user_permissions", mode="before")
1087
+ @classmethod
1088
+ def _normalize_legacy_user_permissions(cls, value):
1089
+ if value is None:
1090
+ return []
1091
+ return value
1092
+
1093
+ @field_validator("organization_teams", mode="before")
1094
+ @classmethod
1095
+ def _normalize_organization_team_references(cls, value):
1096
+ if value is None:
1097
+ return []
1098
+ if not isinstance(value, list):
1099
+ return value
1100
+
1101
+ normalized = []
1102
+ for item in value:
1103
+ if isinstance(item, int):
1104
+ continue
1105
+ if isinstance(item, dict):
1106
+ item = {key: val for key, val in item.items() if key != "id"}
1107
+ normalized.append(item)
1108
+ return normalized
1109
+
1068
1110
  @classmethod
1069
1111
  def _build_request_bound_identity_user(
1070
1112
  cls,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mainsequence
3
- Version: 4.4.26
3
+ Version: 4.4.27
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.4.26"
7
+ version = "4.4.27"
8
8
  description = "Main Sequence SDK "
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
@@ -12,6 +12,93 @@ class _FakeResponse:
12
12
  return self._payload
13
13
 
14
14
 
15
+ def test_get_authenticated_user_details_accepts_user_details_summary_contract(monkeypatch):
16
+ captured: dict[str, object] = {}
17
+
18
+ def _fake_make_request(**kwargs):
19
+ captured.update(kwargs)
20
+ return _FakeResponse(
21
+ {
22
+ "uid": "user-uid-4",
23
+ "username": "jose",
24
+ "email": "jose@main-sequence.io",
25
+ "date_joined": "2026-01-01T00:00:00Z",
26
+ "is_active": True,
27
+ "api_request_limit": 10000,
28
+ "mfa_enabled": False,
29
+ "groups": [
30
+ {
31
+ "name": "Organization Admin",
32
+ "normalized_name": "org_admin",
33
+ }
34
+ ],
35
+ "organization_teams": [
36
+ {
37
+ "uid": "team-uid-1",
38
+ "name": "Research",
39
+ }
40
+ ],
41
+ }
42
+ )
43
+
44
+ monkeypatch.setattr(models_user_mod, "make_request", _fake_make_request)
45
+
46
+ user = models_user_mod.User.get_authenticated_user_details()
47
+
48
+ assert str(captured["url"]).endswith("/user/api/user/get_user_details/")
49
+ assert user.groups[0].name == "Organization Admin"
50
+ assert user.groups[0].normalized_name == "org_admin"
51
+ assert not hasattr(user.groups[0], "id")
52
+ assert user.user_permissions == []
53
+ assert user.organization_teams[0].uid == "team-uid-1"
54
+
55
+ dumped = user.model_dump()
56
+ assert "user_permissions" not in dumped
57
+ assert "id" not in dumped["groups"][0]
58
+ assert dumped["organization_teams"][0]["uid"] == "team-uid-1"
59
+ assert "id" not in dumped["organization_teams"][0]
60
+
61
+
62
+ def test_user_details_dump_omits_legacy_internal_ids():
63
+ user = models_user_mod.User.model_validate(
64
+ {
65
+ "id": 4,
66
+ "uid": "user-uid-4",
67
+ "username": "jose",
68
+ "email": "jose@main-sequence.io",
69
+ "date_joined": "2026-01-01T00:00:00Z",
70
+ "is_active": True,
71
+ "api_request_limit": 10000,
72
+ "mfa_enabled": False,
73
+ "groups": [
74
+ {
75
+ "id": 3,
76
+ "name": "Organization Admin",
77
+ "normalized_name": "org_admin",
78
+ }
79
+ ],
80
+ "user_permissions": [101, 202],
81
+ "organization_teams": [
82
+ {
83
+ "id": 9,
84
+ "uid": "team-uid-1",
85
+ "name": "Research",
86
+ }
87
+ ],
88
+ }
89
+ )
90
+
91
+ dumped = user.model_dump()
92
+
93
+ assert user.id == 4
94
+ assert user.user_permissions == [101, 202]
95
+ assert "id" not in dumped
96
+ assert "user_permissions" not in dumped
97
+ assert "id" not in dumped["groups"][0]
98
+ assert dumped["organization_teams"][0]["uid"] == "team-uid-1"
99
+ assert "id" not in dumped["organization_teams"][0]
100
+
101
+
15
102
  def test_get_logged_user_uses_request_bound_headers_for_user_lookup(monkeypatch):
16
103
  monkeypatch.delenv("MAINSEQUENCE_ACCESS_TOKEN", raising=False)
17
104
  monkeypatch.delenv("MAINSEQUENCE_REFRESH_TOKEN", raising=False)
File without changes
File without changes
File without changes