mainsequence 8.0.4__tar.gz → 8.0.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 (139) hide show
  1. {mainsequence-8.0.4/mainsequence.egg-info → mainsequence-8.0.6}/PKG-INFO +1 -1
  2. {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/cli/api.py +4 -10
  3. {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/cli/cli.py +20 -62
  4. {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/client/models_foundry.py +9 -22
  5. {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/client/models_helpers.py +24 -20
  6. {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/client/observability.py +3 -1
  7. {mainsequence-8.0.4 → mainsequence-8.0.6/mainsequence.egg-info}/PKG-INFO +1 -1
  8. {mainsequence-8.0.4 → mainsequence-8.0.6}/pyproject.toml +1 -1
  9. {mainsequence-8.0.4 → mainsequence-8.0.6}/tests/test_cli.py +9 -20
  10. {mainsequence-8.0.4 → mainsequence-8.0.6}/tests/test_code_repository_branch_contract.py +3 -4
  11. {mainsequence-8.0.4 → mainsequence-8.0.6}/tests/test_filter_normalization.py +22 -0
  12. {mainsequence-8.0.4 → mainsequence-8.0.6}/tests/test_observability_client.py +47 -0
  13. {mainsequence-8.0.4 → mainsequence-8.0.6}/LICENSE +0 -0
  14. {mainsequence-8.0.4 → mainsequence-8.0.6}/MANIFEST.in +0 -0
  15. {mainsequence-8.0.4 → mainsequence-8.0.6}/README.md +0 -0
  16. {mainsequence-8.0.4 → mainsequence-8.0.6}/agent_scaffold/AGENTS.md +0 -0
  17. {mainsequence-8.0.4 → mainsequence-8.0.6}/agent_scaffold/skills/a2a_sdk_execution/SKILL.md +0 -0
  18. {mainsequence-8.0.4 → mainsequence-8.0.6}/agent_scaffold/skills/application_surfaces/api_surfaces/SKILL.md +0 -0
  19. {mainsequence-8.0.4 → mainsequence-8.0.6}/agent_scaffold/skills/data_access/exploration/SKILL.md +0 -0
  20. {mainsequence-8.0.4 → mainsequence-8.0.6}/agent_scaffold/skills/data_publishing/meta_table_migrations/SKILL.md +0 -0
  21. {mainsequence-8.0.4 → mainsequence-8.0.6}/agent_scaffold/skills/data_publishing/meta_tables/SKILL.md +0 -0
  22. {mainsequence-8.0.4 → mainsequence-8.0.6}/agent_scaffold/skills/data_publishing/time_index_table_updates/SKILL.md +0 -0
  23. {mainsequence-8.0.4 → mainsequence-8.0.6}/agent_scaffold/skills/maintenance/bug_auditor/SKILL.md +0 -0
  24. {mainsequence-8.0.4 → mainsequence-8.0.6}/agent_scaffold/skills/maintenance/code_repository_maintenance/SKILL.md +0 -0
  25. {mainsequence-8.0.4 → mainsequence-8.0.6}/agent_scaffold/skills/platform_operations/access_control_and_sharing/SKILL.md +0 -0
  26. {mainsequence-8.0.4 → mainsequence-8.0.6}/agent_scaffold/skills/platform_operations/orchestration_and_releases/SKILL.md +0 -0
  27. {mainsequence-8.0.4 → mainsequence-8.0.6}/agent_scaffold/skills/sdk_code_repository_execution/SKILL.md +0 -0
  28. {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/__init__.py +0 -0
  29. {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/__main__.py +0 -0
  30. {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/bootstrap.py +0 -0
  31. {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/cli/__init__.py +0 -0
  32. {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/cli/browser_auth.py +0 -0
  33. {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/cli/code_repository_status.py +0 -0
  34. {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/cli/config.py +0 -0
  35. {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/cli/docker_utils.py +0 -0
  36. {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/cli/doctor.py +0 -0
  37. {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/cli/local_ops.py +0 -0
  38. {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/cli/migrations.py +0 -0
  39. {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/cli/model_filters.py +0 -0
  40. {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/cli/pydantic_cli.py +0 -0
  41. {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/cli/sdk_utils.py +0 -0
  42. {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/cli/ssh_utils.py +0 -0
  43. {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/cli/ui.py +0 -0
  44. {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/client/__init__.py +0 -0
  45. {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/client/agent_runtime_models.py +0 -0
  46. {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/client/base.py +0 -0
  47. {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/client/client.py +0 -0
  48. {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/client/compute_validation.py +0 -0
  49. {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/client/data_sources_interfaces/__init__.py +0 -0
  50. {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/client/data_sources_interfaces/duckdb.py +0 -0
  51. {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/client/data_sources_interfaces/local_paths.py +0 -0
  52. {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/client/data_sources_interfaces/sqlite.py +0 -0
  53. {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/client/dtype_codec.py +0 -0
  54. {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/client/exceptions.py +0 -0
  55. {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/client/metatables/__init__.py +0 -0
  56. {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/client/metatables/core.py +0 -0
  57. {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/client/models_user.py +0 -0
  58. {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/client/utils.py +0 -0
  59. {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/code_repository_context.py +0 -0
  60. {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/code_repository_skills.py +0 -0
  61. {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/defaults.py +0 -0
  62. {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/instrumentation/__init__.py +0 -0
  63. {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/instrumentation/utils.py +0 -0
  64. {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/logconf.py +0 -0
  65. {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/meta_tables/__init__.py +0 -0
  66. {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/meta_tables/__main__.py +0 -0
  67. {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/meta_tables/compiled_sql/__init__.py +0 -0
  68. {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/meta_tables/compiled_sql/v1.py +0 -0
  69. {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/meta_tables/future_registry.py +0 -0
  70. {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/meta_tables/hashing.py +0 -0
  71. {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/meta_tables/migrations/__init__.py +0 -0
  72. {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/meta_tables/migrations/alembic.py +0 -0
  73. {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/meta_tables/migrations/env.py +0 -0
  74. {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/meta_tables/migrations/provider.py +0 -0
  75. {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/meta_tables/migrations/registry.py +0 -0
  76. {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/meta_tables/migrations/scaffold.py +0 -0
  77. {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/meta_tables/migrations/templates/__init__.py +0 -0
  78. {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/meta_tables/migrations/templates/env.py.mako +0 -0
  79. {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/meta_tables/migrations/templates/script.py.mako +0 -0
  80. {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/meta_tables/pydantic_metadata.py +0 -0
  81. {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/meta_tables/schema_names.py +0 -0
  82. {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/meta_tables/sqlalchemy_contracts.py +0 -0
  83. {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/meta_tables/time_index_table_refs.py +0 -0
  84. {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/meta_tables/time_index_table_updates/__init__.py +0 -0
  85. {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/meta_tables/time_index_table_updates/configuration.py +0 -0
  86. {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/meta_tables/time_index_table_updates/dependencies.py +0 -0
  87. {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/meta_tables/time_index_table_updates/managers.py +0 -0
  88. {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/meta_tables/time_index_table_updates/namespacing.py +0 -0
  89. {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/meta_tables/time_index_table_updates/runner.py +0 -0
  90. {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/meta_tables/time_index_table_updates/updaters.py +0 -0
  91. {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/meta_tables/time_index_table_updates/utils.py +0 -0
  92. {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/repository_identity_security.py +0 -0
  93. {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/runtime_flags.py +0 -0
  94. {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/scaffold_skills.py +0 -0
  95. {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence.egg-info/SOURCES.txt +0 -0
  96. {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence.egg-info/dependency_links.txt +0 -0
  97. {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence.egg-info/entry_points.txt +0 -0
  98. {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence.egg-info/requires.txt +0 -0
  99. {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence.egg-info/top_level.txt +0 -0
  100. {mainsequence-8.0.4 → mainsequence-8.0.6}/setup.cfg +0 -0
  101. {mainsequence-8.0.4 → mainsequence-8.0.6}/tests/fixtures/time_index_table_update_hash_v2_golden.json +0 -0
  102. {mainsequence-8.0.4 → mainsequence-8.0.6}/tests/test_auth_precedence.py +0 -0
  103. {mainsequence-8.0.4 → mainsequence-8.0.6}/tests/test_canonical_api_route_contract.py +0 -0
  104. {mainsequence-8.0.4 → mainsequence-8.0.6}/tests/test_cli_browser_auth.py +0 -0
  105. {mainsequence-8.0.4 → mainsequence-8.0.6}/tests/test_cli_migrations.py +0 -0
  106. {mainsequence-8.0.4 → mainsequence-8.0.6}/tests/test_client.py +0 -0
  107. {mainsequence-8.0.4 → mainsequence-8.0.6}/tests/test_code_repository_batch_jobs_from_file.py +0 -0
  108. {mainsequence-8.0.4 → mainsequence-8.0.6}/tests/test_code_repository_documentation_contract.py +0 -0
  109. {mainsequence-8.0.4 → mainsequence-8.0.6}/tests/test_code_repository_runtime_context.py +0 -0
  110. {mainsequence-8.0.4 → mainsequence-8.0.6}/tests/test_code_repository_skills.py +0 -0
  111. {mainsequence-8.0.4 → mainsequence-8.0.6}/tests/test_dependency_extras.py +0 -0
  112. {mainsequence-8.0.4 → mainsequence-8.0.6}/tests/test_duckdb_interface_dimensions.py +0 -0
  113. {mainsequence-8.0.4 → mainsequence-8.0.6}/tests/test_environment_resource_context.py +0 -0
  114. {mainsequence-8.0.4 → mainsequence-8.0.6}/tests/test_environment_response_contracts.py +0 -0
  115. {mainsequence-8.0.4 → mainsequence-8.0.6}/tests/test_instrumentation.py +0 -0
  116. {mainsequence-8.0.4 → mainsequence-8.0.6}/tests/test_local_ops.py +0 -0
  117. {mainsequence-8.0.4 → mainsequence-8.0.6}/tests/test_logconf.py +0 -0
  118. {mainsequence-8.0.4 → mainsequence-8.0.6}/tests/test_meta_table_migrations.py +0 -0
  119. {mainsequence-8.0.4 → mainsequence-8.0.6}/tests/test_meta_tables_client_models.py +0 -0
  120. {mainsequence-8.0.4 → mainsequence-8.0.6}/tests/test_meta_tables_sqlalchemy_contracts.py +0 -0
  121. {mainsequence-8.0.4 → mainsequence-8.0.6}/tests/test_models_user_request_bound_auth.py +0 -0
  122. {mainsequence-8.0.4 → mainsequence-8.0.6}/tests/test_notification_uid_contract.py +0 -0
  123. {mainsequence-8.0.4 → mainsequence-8.0.6}/tests/test_pod_project_resolution.py +0 -0
  124. {mainsequence-8.0.4 → mainsequence-8.0.6}/tests/test_scaffold_skills.py +0 -0
  125. {mainsequence-8.0.4 → mainsequence-8.0.6}/tests/test_scheduler_client_model.py +0 -0
  126. {mainsequence-8.0.4 → mainsequence-8.0.6}/tests/test_schema_names.py +0 -0
  127. {mainsequence-8.0.4 → mainsequence-8.0.6}/tests/test_secret_client_model.py +0 -0
  128. {mainsequence-8.0.4 → mainsequence-8.0.6}/tests/test_source_table_configuration.py +0 -0
  129. {mainsequence-8.0.4 → mainsequence-8.0.6}/tests/test_sqlite_interface_dimensions.py +0 -0
  130. {mainsequence-8.0.4 → mainsequence-8.0.6}/tests/test_ssh_utils.py +0 -0
  131. {mainsequence-8.0.4 → mainsequence-8.0.6}/tests/test_time_index_table_access_dimension_audit.py +0 -0
  132. {mainsequence-8.0.4 → mainsequence-8.0.6}/tests/test_time_index_table_dimension_queries.py +0 -0
  133. {mainsequence-8.0.4 → mainsequence-8.0.6}/tests/test_time_index_table_update_configuration.py +0 -0
  134. {mainsequence-8.0.4 → mainsequence-8.0.6}/tests/test_time_index_table_update_configuration_client.py +0 -0
  135. {mainsequence-8.0.4 → mainsequence-8.0.6}/tests/test_time_index_table_update_flow.py +0 -0
  136. {mainsequence-8.0.4 → mainsequence-8.0.6}/tests/test_time_index_table_update_hard_cut.py +0 -0
  137. {mainsequence-8.0.4 → mainsequence-8.0.6}/tests/test_update_runner_uid_runtime.py +0 -0
  138. {mainsequence-8.0.4 → mainsequence-8.0.6}/tests/test_update_statistics.py +0 -0
  139. {mainsequence-8.0.4 → mainsequence-8.0.6}/tests/test_update_uid_guards.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mainsequence
3
- Version: 8.0.4
3
+ Version: 8.0.6
4
4
  Summary: Main Sequence SDK
5
5
  Author-email: Main Sequence GmbH <dev@main-sequence.io>
6
6
  License-Expression: LicenseRef-MainSequence-Proprietary
@@ -4532,7 +4532,6 @@ def create_code_repository_job(
4532
4532
  name: str,
4533
4533
  code_repository_branch_uid: str,
4534
4534
  execution_path: str | None = None,
4535
- app_name: str | None = None,
4536
4535
  task_schedule: dict[str, Any] | str | None = None,
4537
4536
  cpu_request: str | int | float | None = None,
4538
4537
  memory_request: str | int | float | None = None,
@@ -4601,7 +4600,6 @@ def create_code_repository_job(
4601
4600
  name=name,
4602
4601
  code_repository_branch_uid=resolved_branch_uid,
4603
4602
  execution_path=execution_path,
4604
- app_name=app_name,
4605
4603
  task_schedule=task_schedule,
4606
4604
  cpu_request=cpu_request,
4607
4605
  memory_request=memory_request,
@@ -4742,11 +4740,8 @@ def run_code_repository_job(
4742
4740
  payload = job.run_job(timeout=timeout, command_args=command_args)
4743
4741
  effective_tokens: list[str] = []
4744
4742
  execution_path = str(getattr(job, "execution_path", "") or "").strip()
4745
- app_name = str(getattr(job, "app_name", "") or "").strip()
4746
4743
  if execution_path:
4747
4744
  effective_tokens.append(execution_path)
4748
- elif app_name:
4749
- effective_tokens.append(f"app:{app_name}")
4750
4745
  if command_args:
4751
4746
  effective_tokens.extend(str(arg) for arg in command_args)
4752
4747
  effective_run = shlex.join(effective_tokens) if effective_tokens else None
@@ -5225,7 +5220,7 @@ def create_code_repository(
5225
5220
  code_repository_type: str = "python",
5226
5221
  default_base_image_uid: str | None = None,
5227
5222
  github_org_uid: str | None = None,
5228
- env_vars: dict[str, str] | None = None,
5223
+ bootstrap_organization_environment_uid: str | None = None,
5229
5224
  labels: list[str] | None = None,
5230
5225
  ) -> dict:
5231
5226
  """
@@ -5240,8 +5235,8 @@ def create_code_repository(
5240
5235
  payload["default_base_image_uid"] = str(default_base_image_uid)
5241
5236
  if github_org_uid not in (None, ""):
5242
5237
  payload["github_org_uid"] = str(github_org_uid)
5243
- if env_vars:
5244
- payload["env_vars"] = [{"name": k, "value": str(v)} for k, v in env_vars.items()]
5238
+ if bootstrap_organization_environment_uid not in (None, ""):
5239
+ payload["bootstrap_organization_environment_uid"] = str(bootstrap_organization_environment_uid)
5245
5240
  if labels is not None:
5246
5241
  payload["labels"] = list(labels)
5247
5242
 
@@ -5298,11 +5293,10 @@ def delete_code_repository(code_repository_uid: str) -> dict[str, Any] | None:
5298
5293
  def bulk_delete_code_repositories(
5299
5294
  *,
5300
5295
  uids: list[str],
5301
- delete_repositories: bool = False,
5302
5296
  ) -> dict[str, Any]:
5303
5297
  payload = {
5304
5298
  "selection": {"mode": "explicit", "uids": list(uids)},
5305
- "options": {"delete_repositories": delete_repositories},
5299
+ "options": {},
5306
5300
  }
5307
5301
  r = authed("POST", "/api/v1/code-repositories/bulk-delete/", payload)
5308
5302
  if not r.ok:
@@ -7427,10 +7427,11 @@ def code_repository_create_cmd(
7427
7427
  github_org_uid: str | None = typer.Option(
7428
7428
  None, "--github-org-uid", "--organization-uid", help="GitHub organization UID"
7429
7429
  ),
7430
- env: list[str] | None = typer.Option(
7430
+ bootstrap_organization_environment_uid: uuid.UUID | None = typer.Option(
7431
7431
  None,
7432
- "--env",
7433
- help="Environment variable entry in KEY=VALUE form. Repeatable or comma-separated.",
7432
+ "--bootstrap-organization-environment-uid",
7433
+ "--environment-uid",
7434
+ help="Active Organization Environment UID used for initial branch bootstrap.",
7434
7435
  ),
7435
7436
  ):
7436
7437
  """
@@ -7449,8 +7450,8 @@ def code_repository_create_cmd(
7449
7450
  Default base image UID.
7450
7451
  github_org_uid:
7451
7452
  GitHub organization UID.
7452
- env:
7453
- Environment variable entries in `KEY=VALUE` format.
7453
+ bootstrap_organization_environment_uid:
7454
+ Optional active Organization Environment UID. The backend derives its required branch.
7454
7455
 
7455
7456
  Examples
7456
7457
  --------
@@ -7458,7 +7459,7 @@ def code_repository_create_cmd(
7458
7459
  mainsequence code-repository create
7459
7460
  mainsequence code-repository create tutorial-repository
7460
7461
  mainsequence code-repository create tutorial-repository --default-base-image-uid <base_image_uid> --github-org-uid <github_org_uid>
7461
- mainsequence code-repository create tutorial-repository --env FOO=bar --env BAZ=qux
7462
+ mainsequence code-repository create tutorial-repository --environment-uid <environment_uid>
7462
7463
  ```
7463
7464
  """
7464
7465
  _require_login()
@@ -7535,29 +7536,16 @@ def code_repository_create_cmd(
7535
7536
  "No GitHub organizations available. CodeRepository will be created without github_org_uid."
7536
7537
  )
7537
7538
 
7538
- env_entries = list(env or [])
7539
- if not env_entries:
7540
- env_line = typer.prompt(
7541
- "Environment variables (KEY=VALUE, comma-separated, optional)",
7542
- default="",
7543
- ).strip()
7544
- if env_line:
7545
- env_entries = [env_line]
7546
-
7547
- env_vars: dict[str, str] | None = None
7548
- if env_entries:
7549
- try:
7550
- env_vars = _parse_env_var_entries(env_entries)
7551
- except ValueError as e:
7552
- error(str(e))
7553
- raise typer.Exit(1) from e
7554
-
7555
7539
  created = create_code_repository(
7556
7540
  code_repository_name=code_repository_name,
7557
7541
  code_repository_type=code_repository_type,
7558
7542
  default_base_image_uid=default_base_image_uid,
7559
7543
  github_org_uid=github_org_uid,
7560
- env_vars=env_vars,
7544
+ bootstrap_organization_environment_uid=(
7545
+ str(bootstrap_organization_environment_uid)
7546
+ if bootstrap_organization_environment_uid is not None
7547
+ else None
7548
+ ),
7561
7549
  )
7562
7550
  except ApiError as e:
7563
7551
  error(f"CodeRepository creation failed: {e}")
@@ -7594,11 +7582,6 @@ def code_repository_create_cmd(
7594
7582
  @code_repository.command("delete")
7595
7583
  def code_repository_delete_remote_cmd(
7596
7584
  code_repository_id: str = typer.Argument(..., help="CodeRepository UID"),
7597
- delete_repositories: bool = typer.Option(
7598
- False,
7599
- "--delete-repositories/--no-delete-repositories",
7600
- help="Also delete linked repositories in the backend workflow.",
7601
- ),
7602
7585
  yes: bool = typer.Option(False, "--yes", "-y", help="Do not prompt for confirmation"),
7603
7586
  ):
7604
7587
  """
@@ -7610,8 +7593,6 @@ def code_repository_delete_remote_cmd(
7610
7593
  ----------
7611
7594
  code_repository_id:
7612
7595
  Platform CodeRepository UID.
7613
- delete_repositories:
7614
- Also delete linked repositories on backend workflow.
7615
7596
  yes:
7616
7597
  Skip interactive confirmation.
7617
7598
 
@@ -7620,7 +7601,6 @@ def code_repository_delete_remote_cmd(
7620
7601
  ```bash
7621
7602
  mainsequence code-repository delete code-repository-uid-123
7622
7603
  mainsequence code-repository delete code-repository-uid-123 --yes
7623
- mainsequence code-repository delete code-repository-uid-123 --delete-repositories --yes
7624
7604
  ```
7625
7605
  """
7626
7606
  _require_login()
@@ -7640,10 +7620,10 @@ def code_repository_delete_remote_cmd(
7640
7620
  warning = (
7641
7621
  f"This will permanently delete CodeRepository '{code_repository_name}' "
7642
7622
  f"(uid={code_repository_uid}) from the platform.\n"
7643
- "This action cannot be undone."
7623
+ "Its branch workspaces and cascading Main Sequence descendants are removed. "
7624
+ "The provider repository and Git branches are preserved.\n"
7625
+ "This platform action cannot be undone."
7644
7626
  )
7645
- if delete_repositories:
7646
- warning += "\nLinked repositories will also be deleted."
7647
7627
  if not typer.confirm(f"{warning}\n\nContinue?", default=False):
7648
7628
  info("Cancelled.")
7649
7629
  raise typer.Exit(0)
@@ -7651,7 +7631,6 @@ def code_repository_delete_remote_cmd(
7651
7631
  try:
7652
7632
  resp = bulk_delete_code_repositories(
7653
7633
  uids=[code_repository_uid],
7654
- delete_repositories=delete_repositories,
7655
7634
  )
7656
7635
  except NotLoggedIn as e:
7657
7636
  error("Not logged in. Run: mainsequence login")
@@ -8940,7 +8919,6 @@ def _code_repository_jobs_list_impl(
8940
8919
  str(job.get("name") or "-"),
8941
8920
  str(job.get("code_repository_commit_hash") or "-"),
8942
8921
  str(job.get("execution_path") or "-"),
8943
- str(job.get("app_name") or "-"),
8944
8922
  _format_job_schedule_summary(job.get("task_schedule")),
8945
8923
  _format_related_image_label(job.get("related_image")),
8946
8924
  ]
@@ -8954,7 +8932,6 @@ def _code_repository_jobs_list_impl(
8954
8932
  "Name",
8955
8933
  "Repo Hash",
8956
8934
  "Execution Path",
8957
- "App Name",
8958
8935
  "Schedule",
8959
8936
  "Related Image",
8960
8937
  ],
@@ -9139,7 +9116,7 @@ def code_repository_jobs_run_cmd(
9139
9116
  command_args: list[str] | None = typer.Option(
9140
9117
  None,
9141
9118
  "--arg",
9142
- help="Append one per-run arg to the saved job entrypoint. Repeatable. Does not replace the saved execution_path or app_name.",
9119
+ help="Append one per-run arg to the saved job entrypoint. Repeatable. Does not replace the saved execution_path.",
9143
9120
  ),
9144
9121
  timeout: int | None = typer.Option(None, "--timeout", help="Request timeout in seconds"),
9145
9122
  ):
@@ -9171,10 +9148,6 @@ def code_repository_jobs_run_cmd(
9171
9148
  raise typer.Exit(1) from e
9172
9149
 
9173
9150
  entrypoint = str(job_payload.get("execution_path") or "").strip()
9174
- if not entrypoint:
9175
- app_name = str(job_payload.get("app_name") or "").strip()
9176
- if app_name:
9177
- entrypoint = f"app:{app_name}"
9178
9151
 
9179
9152
  if entrypoint:
9180
9153
  effective_tokens = [entrypoint, *merged_command_args]
@@ -9425,7 +9398,6 @@ def _code_repository_jobs_create_impl(
9425
9398
  name: str | None,
9426
9399
  path: str | None,
9427
9400
  execution_path: str | None,
9428
- app_name: str | None,
9429
9401
  related_image_uid: str | None,
9430
9402
  schedule_type: str | None,
9431
9403
  schedule_every: int | None,
@@ -9502,25 +9474,16 @@ def _code_repository_jobs_create_impl(
9502
9474
  error("related_image_uid is required when automatic deployment is disabled.")
9503
9475
  raise typer.Exit(1)
9504
9476
 
9505
- if execution_path is None and app_name is None:
9477
+ if execution_path is None:
9506
9478
  execution_path = (
9507
9479
  typer.prompt(
9508
- pydantic_prompt_text(JOB_MODEL_REF, "execution_path", optional=True),
9509
- default="",
9480
+ pydantic_prompt_text(JOB_MODEL_REF, "execution_path"),
9510
9481
  ).strip()
9511
9482
  or None
9512
9483
  )
9513
- if execution_path is None:
9514
- app_name = (
9515
- typer.prompt(
9516
- pydantic_prompt_text(JOB_MODEL_REF, "app_name", optional=True),
9517
- default="",
9518
- ).strip()
9519
- or None
9520
- )
9521
9484
 
9522
- if execution_path is None and app_name is None:
9523
- error("One of execution_path or app_name is required.")
9485
+ if execution_path is None:
9486
+ error("execution_path is required.")
9524
9487
  raise typer.Exit(1)
9525
9488
 
9526
9489
  try:
@@ -9567,7 +9530,6 @@ def _code_repository_jobs_create_impl(
9567
9530
  name=name,
9568
9531
  code_repository_branch_uid=code_repository_branch_uid,
9569
9532
  execution_path=execution_path,
9570
- app_name=app_name,
9571
9533
  task_schedule=task_schedule,
9572
9534
  cpu_request=cpu_request,
9573
9535
  memory_request=memory_request,
@@ -9598,7 +9560,6 @@ def _code_repository_jobs_create_impl(
9598
9560
  ("Name", str(created.get("name") or name)),
9599
9561
  ("CodeRepository UID", str(code_repository_id)),
9600
9562
  ("Execution Path", str(created.get("execution_path") or execution_path or "-")),
9601
- ("App Name", str(created.get("app_name") or app_name or "-")),
9602
9563
  (
9603
9564
  "Related Image",
9604
9565
  _format_related_image_label(created.get("related_image") or related_image_uid),
@@ -9646,7 +9607,6 @@ def code_repository_jobs_create_cmd(
9646
9607
  None,
9647
9608
  "--execution-path",
9648
9609
  ),
9649
- app_name: str | None = pydantic_option(JOB_MODEL_REF, "app_name", None, "--app-name"),
9650
9610
  related_image_uid: str | None = pydantic_option(
9651
9611
  JOB_MODEL_REF,
9652
9612
  "related_image_uid",
@@ -9760,7 +9720,6 @@ def code_repository_jobs_create_cmd(
9760
9720
  ```bash
9761
9721
  mainsequence code-repository jobs create
9762
9722
  mainsequence code-repository jobs create code-repository-uid-123 --name daily-run --execution-path scripts/test.py --related-image-uid <uid>
9763
- mainsequence code-repository jobs create code-repository-uid-123 --name dashboard --app-name dashboard-api --related-image-uid <uid>
9764
9723
  ```
9765
9724
  """
9766
9725
  _code_repository_jobs_create_impl(
@@ -9768,7 +9727,6 @@ def code_repository_jobs_create_cmd(
9768
9727
  name=name,
9769
9728
  path=path,
9770
9729
  execution_path=execution_path,
9771
- app_name=app_name,
9772
9730
  related_image_uid=related_image_uid,
9773
9731
  schedule_type=schedule_type,
9774
9732
  schedule_every=schedule_every,
@@ -234,21 +234,6 @@ class CodeRepository(LabelableObjectMixin, ShareableObjectMixin, BasePydanticMod
234
234
 
235
235
  branches: list[CodeRepositoryBranchLight] = Field(default_factory=list)
236
236
 
237
- @staticmethod
238
- def _normalize_env_vars(
239
- env_vars: dict[str, str] | list[dict[str, str]] | None,
240
- ) -> list[dict[str, str]] | None:
241
- """
242
- Serializer expects: [{"name": "...", "value": "..."}, ...]
243
- Allow passing a dict for convenience.
244
- """
245
- if env_vars is None:
246
- return None
247
- if isinstance(env_vars, dict):
248
- return [{"name": k, "value": v} for k, v in env_vars.items()]
249
- # assume already list-of-dicts shape
250
- return env_vars
251
-
252
237
  @staticmethod
253
238
  def _coerce_uid(obj: Any, *, field_name: str) -> str | None:
254
239
  """
@@ -283,7 +268,7 @@ class CodeRepository(LabelableObjectMixin, ShareableObjectMixin, BasePydanticMod
283
268
  code_repository_type: str = "python",
284
269
  default_base_image_uid: str | CodeRepositoryBaseImage | dict[str, Any] | None = None,
285
270
  github_org_uid: str | GitHubOrganization | dict[str, Any] | None = None,
286
- env_vars: dict[str, str] | list[dict[str, str]] | None = None,
271
+ bootstrap_organization_environment_uid: str | UUID | dict[str, Any] | BasePydanticModel | None = None,
287
272
  labels: list[str] | None = None,
288
273
  timeout: int | None = None,
289
274
  ) -> CodeRepository:
@@ -295,7 +280,7 @@ class CodeRepository(LabelableObjectMixin, ShareableObjectMixin, BasePydanticMod
295
280
  - code_repository_type
296
281
  - default_base_image_uid (optional)
297
282
  - github_org_uid (optional)
298
- - env_vars (optional list of {name,value})
283
+ - bootstrap_organization_environment_uid (optional active Environment UID)
299
284
  """
300
285
  url = cls.get_object_url() + "/"
301
286
 
@@ -309,9 +294,12 @@ class CodeRepository(LabelableObjectMixin, ShareableObjectMixin, BasePydanticMod
309
294
  if org_uid is not None:
310
295
  payload["github_org_uid"] = org_uid
311
296
 
312
- env_list = cls._normalize_env_vars(env_vars)
313
- if env_list is not None:
314
- payload["env_vars"] = env_list
297
+ bootstrap_environment_uid = cls._coerce_uid(
298
+ bootstrap_organization_environment_uid,
299
+ field_name="bootstrap_organization_environment_uid",
300
+ )
301
+ if bootstrap_environment_uid is not None:
302
+ payload["bootstrap_organization_environment_uid"] = bootstrap_environment_uid
315
303
  if labels is not None:
316
304
  payload["labels"] = list(labels)
317
305
 
@@ -441,7 +429,6 @@ class CodeRepository(LabelableObjectMixin, ShareableObjectMixin, BasePydanticMod
441
429
  *,
442
430
  uids: list[str] | None = None,
443
431
  selection: dict[str, Any] | None = None,
444
- delete_repositories: bool = False,
445
432
  timeout: int | None = None,
446
433
  ) -> CodeRepositoryBulkDeleteResponse:
447
434
  if (uids is None) == (selection is None):
@@ -455,7 +442,7 @@ class CodeRepository(LabelableObjectMixin, ShareableObjectMixin, BasePydanticMod
455
442
  payload={
456
443
  "json": {
457
444
  "selection": resolved_selection,
458
- "options": {"delete_repositories": delete_repositories},
445
+ "options": {},
459
446
  }
460
447
  },
461
448
  time_out=timeout,
@@ -154,7 +154,7 @@ class Job(CurrentCodeRepositoryBranchCollectionMixin, BaseObjectOrm, BasePydanti
154
154
  GPU_MIN: ClassVar[int] = 1
155
155
  GPU_MAX: ClassVar[int] = 8
156
156
  DEFAULT_ALLOWED_EXECUTION_EXTENSIONS: ClassVar[frozenset[str]] = frozenset(
157
- {".py", ".ipynb", ".yaml"}
157
+ {".py", ".yaml"}
158
158
  )
159
159
 
160
160
  uid: str | None = Field(
@@ -170,6 +170,15 @@ class Job(CurrentCodeRepositoryBranchCollectionMixin, BaseObjectOrm, BasePydanti
170
170
  examples=["Daily feature build"],
171
171
  )
172
172
 
173
+ description: str = Field(
174
+ default="",
175
+ description=(
176
+ "Optional human-readable purpose or context for the Job. "
177
+ "It does not affect execution behavior."
178
+ ),
179
+ examples=["Refresh the daily prices dataset."],
180
+ )
181
+
173
182
  code_repository_branch_uid: str | None = Field(
174
183
  default=None,
175
184
  description="Public UID of the owning CodeRepositoryBranch.",
@@ -197,15 +206,9 @@ class Job(CurrentCodeRepositoryBranchCollectionMixin, BaseObjectOrm, BasePydanti
197
206
  execution_path: str | None = Field(
198
207
  default=None,
199
208
  description=(
200
- "Repository-relative file path from the content root. Allowed extensions are .py, .ipynb, and .yaml."
209
+ "Repository-relative file path from the content root. Allowed extensions are .py and .yaml."
201
210
  ),
202
- examples=["scripts/test.py", "jobs/train_model.py", "notebooks/eda.ipynb"],
203
- )
204
-
205
- app_name: str | None = Field(
206
- default=None,
207
- description="Application name to run instead of a file-based execution path.",
208
- examples=["data-monitor"],
211
+ examples=["scripts/test.py", "jobs/train_model.py"],
209
212
  )
210
213
 
211
214
  task_schedule: PeriodicTask | None = Field(
@@ -369,14 +372,12 @@ class Job(CurrentCodeRepositoryBranchCollectionMixin, BaseObjectOrm, BasePydanti
369
372
  cls,
370
373
  *,
371
374
  execution_path: str | None = None,
372
- app_name: str | None = None,
373
375
  allowed_execution_extensions: Collection[str] | str | None = None,
374
376
  ) -> dict[str, Any]:
375
377
  execution_path = cls._normalize_str(execution_path)
376
- app_name = cls._normalize_str(app_name)
377
378
 
378
- if bool(execution_path) == bool(app_name):
379
- raise ValueError("Pass exactly one of execution_path or app_name.")
379
+ if execution_path is None:
380
+ raise ValueError("execution_path is required.")
380
381
 
381
382
  payload: dict[str, Any] = {}
382
383
 
@@ -402,9 +403,6 @@ class Job(CurrentCodeRepositoryBranchCollectionMixin, BaseObjectOrm, BasePydanti
402
403
 
403
404
  payload["execution_path"] = execution_path
404
405
 
405
- if app_name is not None:
406
- payload["app_name"] = app_name
407
-
408
406
  return payload
409
407
 
410
408
  @classmethod
@@ -524,9 +522,9 @@ class Job(CurrentCodeRepositoryBranchCollectionMixin, BaseObjectOrm, BasePydanti
524
522
  cls,
525
523
  *,
526
524
  name: str,
525
+ description: str | None = None,
527
526
  code_repository_branch_uid: str | CodeRepositoryBranch | dict[str, Any] | None = None,
528
527
  execution_path: str | None = None,
529
- app_name: str | None = None,
530
528
  task_schedule: PeriodicTask | Schedule | dict[str, Any] | str | None = None,
531
529
  task_schedule_id: int | None = None,
532
530
  cpu_request: str | int | float | Decimal | None = None,
@@ -550,11 +548,14 @@ class Job(CurrentCodeRepositoryBranchCollectionMixin, BaseObjectOrm, BasePydanti
550
548
  code_repository_branch_uid=code_repository_branch_uid
551
549
  ),
552
550
  }
551
+ if description is not None:
552
+ if not isinstance(description, str):
553
+ raise TypeError("description must be a string or None.")
554
+ payload["description"] = description.strip()
553
555
 
554
556
  payload.update(
555
557
  cls._build_target_payload(
556
558
  execution_path=execution_path,
557
- app_name=app_name,
558
559
  allowed_execution_extensions=allowed_execution_extensions,
559
560
  )
560
561
  )
@@ -625,9 +626,9 @@ class Job(CurrentCodeRepositoryBranchCollectionMixin, BaseObjectOrm, BasePydanti
625
626
  cls,
626
627
  *,
627
628
  name: str,
629
+ description: str | None = None,
628
630
  code_repository_branch_uid: str | CodeRepositoryBranch | dict[str, Any] | None = None,
629
631
  execution_path: str | None = None,
630
- app_name: str | None = None,
631
632
  task_schedule: PeriodicTask | Schedule | dict[str, Any] | str | None = None,
632
633
  task_schedule_id: int | None = None,
633
634
  cpu_request: str | int | float | Decimal | None = None,
@@ -644,9 +645,9 @@ class Job(CurrentCodeRepositoryBranchCollectionMixin, BaseObjectOrm, BasePydanti
644
645
  ) -> Job:
645
646
  payload = cls._build_create_payload(
646
647
  name=name,
648
+ description=description,
647
649
  code_repository_branch_uid=code_repository_branch_uid,
648
650
  execution_path=execution_path,
649
- app_name=app_name,
650
651
  task_schedule=task_schedule,
651
652
  task_schedule_id=task_schedule_id,
652
653
  cpu_request=cpu_request,
@@ -715,6 +716,9 @@ class JobRun(
715
716
  BaseObjectOrm,
716
717
  BasePydanticModel,
717
718
  ):
719
+ _OBSERVABILITY_ENVIRONMENT_OPTIONAL_FIELDS: ClassVar[frozenset[str]] = frozenset(
720
+ {"application_logs_url"}
721
+ )
718
722
  PUBLIC_LOOKUP_FIELD: ClassVar[str] = "uid"
719
723
  FILTERSET_FIELDS: ClassVar[dict[str, list[str]]] = {
720
724
  "job__uid": ["in", "exact"],
@@ -106,6 +106,7 @@ class ResourceUsagePage(BasePydanticModel):
106
106
 
107
107
  class _OwnerObservabilityTransportMixin:
108
108
  _OBSERVABILITY_ENVIRONMENT_QUERY: ClassVar[str] = "organization_environment_uid"
109
+ _OBSERVABILITY_ENVIRONMENT_OPTIONAL_FIELDS: ClassVar[frozenset[str]] = frozenset()
109
110
 
110
111
  def _observability_capability_url(self, field_name: str) -> str:
111
112
  links = getattr(self, "observability", None)
@@ -157,7 +158,8 @@ class _OwnerObservabilityTransportMixin:
157
158
  raise ApiError("The backend returned a duplicate observability query parameter.")
158
159
  query[key] = value
159
160
  environment_uid = str(query.get(self._OBSERVABILITY_ENVIRONMENT_QUERY) or "").strip()
160
- if not environment_uid:
161
+ environment_optional_fields = type(self)._OBSERVABILITY_ENVIRONMENT_OPTIONAL_FIELDS
162
+ if not environment_uid and field_name not in environment_optional_fields:
161
163
  raise ApiError(
162
164
  "The backend observability capability is missing organization_environment_uid."
163
165
  )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mainsequence
3
- Version: 8.0.4
3
+ Version: 8.0.6
4
4
  Summary: Main Sequence SDK
5
5
  Author-email: Main Sequence GmbH <dev@main-sequence.io>
6
6
  License-Expression: LicenseRef-MainSequence-Proprietary
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "mainsequence"
7
- version = "8.0.4"
7
+ version = "8.0.6"
8
8
  description = "Main Sequence SDK "
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.13"