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.
- {mainsequence-8.0.4/mainsequence.egg-info → mainsequence-8.0.6}/PKG-INFO +1 -1
- {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/cli/api.py +4 -10
- {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/cli/cli.py +20 -62
- {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/client/models_foundry.py +9 -22
- {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/client/models_helpers.py +24 -20
- {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/client/observability.py +3 -1
- {mainsequence-8.0.4 → mainsequence-8.0.6/mainsequence.egg-info}/PKG-INFO +1 -1
- {mainsequence-8.0.4 → mainsequence-8.0.6}/pyproject.toml +1 -1
- {mainsequence-8.0.4 → mainsequence-8.0.6}/tests/test_cli.py +9 -20
- {mainsequence-8.0.4 → mainsequence-8.0.6}/tests/test_code_repository_branch_contract.py +3 -4
- {mainsequence-8.0.4 → mainsequence-8.0.6}/tests/test_filter_normalization.py +22 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/tests/test_observability_client.py +47 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/LICENSE +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/MANIFEST.in +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/README.md +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/agent_scaffold/AGENTS.md +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/agent_scaffold/skills/a2a_sdk_execution/SKILL.md +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/agent_scaffold/skills/application_surfaces/api_surfaces/SKILL.md +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/agent_scaffold/skills/data_access/exploration/SKILL.md +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/agent_scaffold/skills/data_publishing/meta_table_migrations/SKILL.md +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/agent_scaffold/skills/data_publishing/meta_tables/SKILL.md +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/agent_scaffold/skills/data_publishing/time_index_table_updates/SKILL.md +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/agent_scaffold/skills/maintenance/bug_auditor/SKILL.md +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/agent_scaffold/skills/maintenance/code_repository_maintenance/SKILL.md +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/agent_scaffold/skills/platform_operations/access_control_and_sharing/SKILL.md +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/agent_scaffold/skills/platform_operations/orchestration_and_releases/SKILL.md +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/agent_scaffold/skills/sdk_code_repository_execution/SKILL.md +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/__init__.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/__main__.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/bootstrap.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/cli/__init__.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/cli/browser_auth.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/cli/code_repository_status.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/cli/config.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/cli/docker_utils.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/cli/doctor.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/cli/local_ops.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/cli/migrations.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/cli/model_filters.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/cli/pydantic_cli.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/cli/sdk_utils.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/cli/ssh_utils.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/cli/ui.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/client/__init__.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/client/agent_runtime_models.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/client/base.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/client/client.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/client/compute_validation.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/client/data_sources_interfaces/__init__.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/client/data_sources_interfaces/duckdb.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/client/data_sources_interfaces/local_paths.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/client/data_sources_interfaces/sqlite.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/client/dtype_codec.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/client/exceptions.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/client/metatables/__init__.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/client/metatables/core.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/client/models_user.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/client/utils.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/code_repository_context.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/code_repository_skills.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/defaults.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/instrumentation/__init__.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/instrumentation/utils.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/logconf.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/meta_tables/__init__.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/meta_tables/__main__.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/meta_tables/compiled_sql/__init__.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/meta_tables/compiled_sql/v1.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/meta_tables/future_registry.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/meta_tables/hashing.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/meta_tables/migrations/__init__.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/meta_tables/migrations/alembic.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/meta_tables/migrations/env.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/meta_tables/migrations/provider.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/meta_tables/migrations/registry.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/meta_tables/migrations/scaffold.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/meta_tables/migrations/templates/__init__.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/meta_tables/migrations/templates/env.py.mako +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/meta_tables/migrations/templates/script.py.mako +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/meta_tables/pydantic_metadata.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/meta_tables/schema_names.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/meta_tables/sqlalchemy_contracts.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/meta_tables/time_index_table_refs.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/meta_tables/time_index_table_updates/__init__.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/meta_tables/time_index_table_updates/configuration.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/meta_tables/time_index_table_updates/dependencies.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/meta_tables/time_index_table_updates/managers.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/meta_tables/time_index_table_updates/namespacing.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/meta_tables/time_index_table_updates/runner.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/meta_tables/time_index_table_updates/updaters.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/meta_tables/time_index_table_updates/utils.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/repository_identity_security.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/runtime_flags.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence/scaffold_skills.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence.egg-info/SOURCES.txt +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence.egg-info/dependency_links.txt +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence.egg-info/entry_points.txt +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence.egg-info/requires.txt +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/mainsequence.egg-info/top_level.txt +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/setup.cfg +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/tests/fixtures/time_index_table_update_hash_v2_golden.json +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/tests/test_auth_precedence.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/tests/test_canonical_api_route_contract.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/tests/test_cli_browser_auth.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/tests/test_cli_migrations.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/tests/test_client.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/tests/test_code_repository_batch_jobs_from_file.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/tests/test_code_repository_documentation_contract.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/tests/test_code_repository_runtime_context.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/tests/test_code_repository_skills.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/tests/test_dependency_extras.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/tests/test_duckdb_interface_dimensions.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/tests/test_environment_resource_context.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/tests/test_environment_response_contracts.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/tests/test_instrumentation.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/tests/test_local_ops.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/tests/test_logconf.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/tests/test_meta_table_migrations.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/tests/test_meta_tables_client_models.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/tests/test_meta_tables_sqlalchemy_contracts.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/tests/test_models_user_request_bound_auth.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/tests/test_notification_uid_contract.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/tests/test_pod_project_resolution.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/tests/test_scaffold_skills.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/tests/test_scheduler_client_model.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/tests/test_schema_names.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/tests/test_secret_client_model.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/tests/test_source_table_configuration.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/tests/test_sqlite_interface_dimensions.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/tests/test_ssh_utils.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/tests/test_time_index_table_access_dimension_audit.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/tests/test_time_index_table_dimension_queries.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/tests/test_time_index_table_update_configuration.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/tests/test_time_index_table_update_configuration_client.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/tests/test_time_index_table_update_flow.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/tests/test_time_index_table_update_hard_cut.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/tests/test_update_runner_uid_runtime.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/tests/test_update_statistics.py +0 -0
- {mainsequence-8.0.4 → mainsequence-8.0.6}/tests/test_update_uid_guards.py +0 -0
|
@@ -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
|
-
|
|
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
|
|
5244
|
-
payload["
|
|
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": {
|
|
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
|
-
|
|
7430
|
+
bootstrap_organization_environment_uid: uuid.UUID | None = typer.Option(
|
|
7431
7431
|
None,
|
|
7432
|
-
"--
|
|
7433
|
-
|
|
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
|
-
|
|
7453
|
-
Environment
|
|
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 --
|
|
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
|
-
|
|
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
|
-
"
|
|
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
|
|
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
|
|
9477
|
+
if execution_path is None:
|
|
9506
9478
|
execution_path = (
|
|
9507
9479
|
typer.prompt(
|
|
9508
|
-
pydantic_prompt_text(JOB_MODEL_REF, "execution_path"
|
|
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
|
|
9523
|
-
error("
|
|
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
|
-
|
|
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
|
-
-
|
|
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
|
-
|
|
313
|
-
|
|
314
|
-
|
|
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": {
|
|
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", ".
|
|
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
|
|
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"
|
|
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
|
|
379
|
-
raise ValueError("
|
|
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
|
-
|
|
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
|
)
|