zenml-nightly 0.75.0.dev20250313__py3-none-any.whl → 0.75.0.dev20250315__py3-none-any.whl

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 (145) hide show
  1. zenml/VERSION +1 -1
  2. zenml/analytics/context.py +4 -4
  3. zenml/analytics/enums.py +2 -2
  4. zenml/artifacts/utils.py +2 -2
  5. zenml/cli/__init__.py +8 -9
  6. zenml/cli/base.py +2 -2
  7. zenml/cli/code_repository.py +1 -1
  8. zenml/cli/login.py +21 -18
  9. zenml/cli/pipeline.py +3 -3
  10. zenml/cli/project.py +172 -0
  11. zenml/cli/server.py +5 -5
  12. zenml/cli/service_accounts.py +0 -1
  13. zenml/cli/service_connectors.py +15 -16
  14. zenml/cli/stack.py +0 -2
  15. zenml/cli/stack_components.py +2 -2
  16. zenml/cli/utils.py +3 -3
  17. zenml/client.py +352 -341
  18. zenml/config/global_config.py +41 -43
  19. zenml/config/server_config.py +9 -9
  20. zenml/constants.py +5 -3
  21. zenml/event_hub/event_hub.py +1 -1
  22. zenml/integrations/gcp/__init__.py +1 -0
  23. zenml/integrations/gcp/flavors/vertex_orchestrator_flavor.py +5 -0
  24. zenml/integrations/gcp/flavors/vertex_step_operator_flavor.py +5 -28
  25. zenml/integrations/gcp/orchestrators/vertex_orchestrator.py +125 -78
  26. zenml/integrations/gcp/service_connectors/gcp_service_connector.py +7 -6
  27. zenml/integrations/gcp/vertex_custom_job_parameters.py +50 -0
  28. zenml/integrations/mlflow/steps/mlflow_registry.py +3 -3
  29. zenml/integrations/wandb/__init__.py +1 -1
  30. zenml/integrations/wandb/experiment_trackers/wandb_experiment_tracker.py +29 -9
  31. zenml/integrations/wandb/flavors/wandb_experiment_tracker_flavor.py +2 -0
  32. zenml/login/credentials.py +26 -27
  33. zenml/login/credentials_store.py +5 -5
  34. zenml/login/pro/client.py +9 -9
  35. zenml/login/pro/utils.py +8 -8
  36. zenml/login/pro/{tenant → workspace}/__init__.py +1 -1
  37. zenml/login/pro/{tenant → workspace}/client.py +25 -25
  38. zenml/login/pro/{tenant → workspace}/models.py +27 -28
  39. zenml/model/model.py +2 -2
  40. zenml/model_registries/base_model_registry.py +1 -1
  41. zenml/models/__init__.py +29 -29
  42. zenml/models/v2/base/filter.py +1 -1
  43. zenml/models/v2/base/scoped.py +49 -53
  44. zenml/models/v2/core/action.py +12 -12
  45. zenml/models/v2/core/artifact.py +15 -15
  46. zenml/models/v2/core/artifact_version.py +15 -15
  47. zenml/models/v2/core/code_repository.py +12 -12
  48. zenml/models/v2/core/event_source.py +12 -12
  49. zenml/models/v2/core/model.py +26 -18
  50. zenml/models/v2/core/model_version.py +15 -15
  51. zenml/models/v2/core/pipeline.py +15 -15
  52. zenml/models/v2/core/pipeline_build.py +14 -14
  53. zenml/models/v2/core/pipeline_deployment.py +12 -14
  54. zenml/models/v2/core/pipeline_run.py +16 -16
  55. zenml/models/v2/core/project.py +203 -0
  56. zenml/models/v2/core/run_metadata.py +2 -2
  57. zenml/models/v2/core/run_template.py +15 -15
  58. zenml/models/v2/core/schedule.py +12 -12
  59. zenml/models/v2/core/secret.py +1 -1
  60. zenml/models/v2/core/service.py +14 -14
  61. zenml/models/v2/core/step_run.py +13 -13
  62. zenml/models/v2/core/tag.py +96 -3
  63. zenml/models/v2/core/trigger.py +13 -13
  64. zenml/models/v2/core/trigger_execution.py +2 -2
  65. zenml/models/v2/core/user.py +0 -17
  66. zenml/models/v2/misc/server_models.py +6 -6
  67. zenml/models/v2/misc/statistics.py +4 -4
  68. zenml/orchestrators/cache_utils.py +7 -7
  69. zenml/orchestrators/input_utils.py +1 -1
  70. zenml/orchestrators/step_launcher.py +1 -1
  71. zenml/orchestrators/step_run_utils.py +3 -3
  72. zenml/orchestrators/utils.py +4 -4
  73. zenml/pipelines/build_utils.py +2 -2
  74. zenml/pipelines/pipeline_definition.py +5 -5
  75. zenml/pipelines/run_utils.py +1 -1
  76. zenml/service_connectors/service_connector.py +0 -3
  77. zenml/service_connectors/service_connector_utils.py +0 -1
  78. zenml/stack/stack.py +0 -1
  79. zenml/steps/base_step.py +10 -2
  80. zenml/utils/dashboard_utils.py +1 -1
  81. zenml/utils/tag_utils.py +0 -12
  82. zenml/zen_server/cloud_utils.py +3 -3
  83. zenml/zen_server/feature_gate/endpoint_utils.py +1 -1
  84. zenml/zen_server/feature_gate/zenml_cloud_feature_gate.py +1 -1
  85. zenml/zen_server/rbac/endpoint_utils.py +17 -17
  86. zenml/zen_server/rbac/models.py +47 -22
  87. zenml/zen_server/rbac/rbac_sql_zen_store.py +3 -3
  88. zenml/zen_server/rbac/utils.py +23 -25
  89. zenml/zen_server/rbac/zenml_cloud_rbac.py +7 -74
  90. zenml/zen_server/routers/artifact_version_endpoints.py +10 -10
  91. zenml/zen_server/routers/auth_endpoints.py +6 -6
  92. zenml/zen_server/routers/code_repositories_endpoints.py +12 -14
  93. zenml/zen_server/routers/model_versions_endpoints.py +13 -15
  94. zenml/zen_server/routers/models_endpoints.py +7 -9
  95. zenml/zen_server/routers/pipeline_builds_endpoints.py +14 -16
  96. zenml/zen_server/routers/pipeline_deployments_endpoints.py +13 -15
  97. zenml/zen_server/routers/pipelines_endpoints.py +16 -18
  98. zenml/zen_server/routers/{workspaces_endpoints.py → projects_endpoints.py} +111 -68
  99. zenml/zen_server/routers/run_metadata_endpoints.py +7 -9
  100. zenml/zen_server/routers/run_templates_endpoints.py +15 -17
  101. zenml/zen_server/routers/runs_endpoints.py +12 -14
  102. zenml/zen_server/routers/schedule_endpoints.py +12 -14
  103. zenml/zen_server/routers/secrets_endpoints.py +1 -3
  104. zenml/zen_server/routers/server_endpoints.py +7 -7
  105. zenml/zen_server/routers/service_connectors_endpoints.py +11 -13
  106. zenml/zen_server/routers/service_endpoints.py +7 -9
  107. zenml/zen_server/routers/stack_components_endpoints.py +9 -11
  108. zenml/zen_server/routers/stacks_endpoints.py +9 -11
  109. zenml/zen_server/routers/steps_endpoints.py +6 -6
  110. zenml/zen_server/routers/users_endpoints.py +5 -43
  111. zenml/zen_server/template_execution/utils.py +4 -4
  112. zenml/zen_server/utils.py +10 -10
  113. zenml/zen_server/zen_server_api.py +6 -5
  114. zenml/zen_stores/base_zen_store.py +38 -42
  115. zenml/zen_stores/migrations/versions/12eff0206201_rename_workspace_to_project.py +768 -0
  116. zenml/zen_stores/migrations/versions/41b28cae31ce_make_artifacts_workspace_scoped.py +3 -3
  117. zenml/zen_stores/migrations/versions/cbc6acd71f92_add_workspace_display_name.py +58 -0
  118. zenml/zen_stores/rest_zen_store.py +55 -63
  119. zenml/zen_stores/schemas/__init__.py +2 -2
  120. zenml/zen_stores/schemas/action_schemas.py +9 -9
  121. zenml/zen_stores/schemas/artifact_schemas.py +15 -17
  122. zenml/zen_stores/schemas/code_repository_schemas.py +16 -18
  123. zenml/zen_stores/schemas/event_source_schemas.py +9 -9
  124. zenml/zen_stores/schemas/model_schemas.py +15 -17
  125. zenml/zen_stores/schemas/pipeline_build_schemas.py +7 -7
  126. zenml/zen_stores/schemas/pipeline_deployment_schemas.py +7 -7
  127. zenml/zen_stores/schemas/pipeline_run_schemas.py +9 -9
  128. zenml/zen_stores/schemas/pipeline_schemas.py +9 -9
  129. zenml/zen_stores/schemas/{workspace_schemas.py → project_schemas.py} +47 -41
  130. zenml/zen_stores/schemas/run_metadata_schemas.py +5 -5
  131. zenml/zen_stores/schemas/run_template_schemas.py +9 -9
  132. zenml/zen_stores/schemas/schedule_schema.py +9 -9
  133. zenml/zen_stores/schemas/service_schemas.py +7 -7
  134. zenml/zen_stores/schemas/step_run_schemas.py +7 -7
  135. zenml/zen_stores/schemas/trigger_schemas.py +9 -9
  136. zenml/zen_stores/schemas/user_schemas.py +0 -12
  137. zenml/zen_stores/sql_zen_store.py +318 -275
  138. zenml/zen_stores/zen_store_interface.py +56 -70
  139. {zenml_nightly-0.75.0.dev20250313.dist-info → zenml_nightly-0.75.0.dev20250315.dist-info}/METADATA +1 -1
  140. {zenml_nightly-0.75.0.dev20250313.dist-info → zenml_nightly-0.75.0.dev20250315.dist-info}/RECORD +143 -140
  141. zenml/cli/workspace.py +0 -160
  142. zenml/models/v2/core/workspace.py +0 -131
  143. {zenml_nightly-0.75.0.dev20250313.dist-info → zenml_nightly-0.75.0.dev20250315.dist-info}/LICENSE +0 -0
  144. {zenml_nightly-0.75.0.dev20250313.dist-info → zenml_nightly-0.75.0.dev20250315.dist-info}/WHEEL +0 -0
  145. {zenml_nightly-0.75.0.dev20250313.dist-info → zenml_nightly-0.75.0.dev20250315.dist-info}/entry_points.txt +0 -0
zenml/VERSION CHANGED
@@ -1 +1 @@
1
- 0.75.0.dev20250313
1
+ 0.75.0.dev20250315
@@ -118,7 +118,7 @@ class AnalyticsContext:
118
118
  self.external_user_id = auth_context.user.external_user_id
119
119
 
120
120
  self.external_server_id = server_config().external_server_id
121
- self.workspace_id = None
121
+ self.project_id = None
122
122
  else:
123
123
  from zenml.client import Client
124
124
 
@@ -129,7 +129,7 @@ class AnalyticsContext:
129
129
  active_user.is_service_account
130
130
  )
131
131
  self.external_user_id = active_user.external_user_id
132
- self.workspace_id = Client().active_workspace.id
132
+ self.project_id = Client().active_project.id
133
133
 
134
134
  # Fetch the `client_id`
135
135
  if self.in_server:
@@ -308,8 +308,8 @@ class AnalyticsContext:
308
308
  if self.server_metadata:
309
309
  properties.update(self.server_metadata)
310
310
 
311
- if self.workspace_id:
312
- properties.setdefault("workspace_id", str(self.workspace_id))
311
+ if self.project_id:
312
+ properties.setdefault("project_id", str(self.project_id))
313
313
 
314
314
  for k, v in properties.items():
315
315
  if isinstance(v, UUID):
zenml/analytics/enums.py CHANGED
@@ -65,8 +65,8 @@ class AnalyticsEvent(str, Enum):
65
65
  # Examples
66
66
  RUN_ZENML_GO = "ZenML go"
67
67
 
68
- # Workspaces
69
- CREATED_WORKSPACE = "Workspace created"
68
+ # Projects
69
+ CREATED_PROJECT = "Project created"
70
70
 
71
71
  # Flavor
72
72
  CREATED_FLAVOR = "Flavor created"
zenml/artifacts/utils.py CHANGED
@@ -182,7 +182,7 @@ def _store_artifact_data_and_prepare_request(
182
182
  uri=materializer.uri,
183
183
  materializer=source_utils.resolve(materializer.__class__),
184
184
  data_type=source_utils.resolve(data_type),
185
- workspace=Client().active_workspace.id,
185
+ project=Client().active_project.id,
186
186
  artifact_store_id=artifact_store.id,
187
187
  visualizations=visualizations,
188
188
  has_custom_name=has_custom_name,
@@ -349,7 +349,7 @@ def register_artifact(
349
349
  uri=folder_or_file_uri,
350
350
  materializer=source_utils.resolve(PreexistingDataMaterializer),
351
351
  data_type=source_utils.resolve(Path),
352
- workspace=Client().active_workspace.id,
352
+ project=Client().active_project.id,
353
353
  artifact_store_id=artifact_store.id,
354
354
  has_custom_name=has_custom_name,
355
355
  metadata=validate_metadata(artifact_metadata)
zenml/cli/__init__.py CHANGED
@@ -106,7 +106,7 @@ zenml go
106
106
  Cleaning up
107
107
  -----------
108
108
 
109
- If you wish to delete all data relating to your workspace from the
109
+ If you wish to delete all data relating to your project from the
110
110
  directory, use the ``zenml clean`` command. This will:
111
111
 
112
112
  - delete all pipelines, pipeline runs and associated metadata
@@ -367,8 +367,7 @@ information regarding a specific flavor, you can utilize the command:
367
367
  zenml orchestrator flavor describe FLAVOR_NAME
368
368
  ```
369
369
 
370
- If you wish to list the orchestrators that have already been registered
371
- within your ZenML workspace / repository, type:
370
+ If you wish to list the orchestrators that have already been registered, type:
372
371
 
373
372
  ```bash
374
373
  zenml orchestrator list
@@ -1446,8 +1445,7 @@ simply pass along the `--set` flag.
1446
1445
  zenml stack register STACK_NAME ... --set
1447
1446
  ```
1448
1447
 
1449
- To list the stacks that you have registered within your current ZenML
1450
- workspace, type:
1448
+ To list the stacks that you have registered, type:
1451
1449
 
1452
1450
  ```bash
1453
1451
  zenml stack list
@@ -2070,9 +2068,10 @@ Finally, to delete a secret, use the `delete` command:
2070
2068
  zenml secret delete SECRET_NAME
2071
2069
  ```
2072
2070
 
2073
- Secrets can be scoped to a workspace or a user. By default, secrets
2074
- are scoped to the current workspace. To scope a secret to a user, use the
2075
- `--scope user` argument in the `register` command.
2071
+ Secrets can be either private or public. Private secrets are only accessible
2072
+ to the current user. Public secrets are accessible to all other users. By
2073
+ default, secrets are public. To make a secret private, use the `--private` flag
2074
+ in the `create` or `update` commands.
2076
2075
 
2077
2076
  Auth management
2078
2077
  ---------------
@@ -2525,5 +2524,5 @@ from zenml.cli.service_connectors import * # noqa
2525
2524
  from zenml.cli.stack import * # noqa
2526
2525
  from zenml.cli.stack_components import * # noqa
2527
2526
  from zenml.cli.user_management import * # noqa
2528
- from zenml.cli.workspace import * # noqa
2527
+ from zenml.cli.project import * # noqa
2529
2528
  from zenml.cli.tag import * # noqa
zenml/cli/base.py CHANGED
@@ -622,7 +622,7 @@ def info(
622
622
  "python_version": environment.python_version(),
623
623
  "environment": get_environment(),
624
624
  "system_info": environment.get_system_info(),
625
- "active_workspace": client.active_workspace.name,
625
+ "active_project": client.active_project.name,
626
626
  "active_stack": client.active_stack_model.name,
627
627
  "active_user": client.active_user.name,
628
628
  "telemetry_status": "enabled" if gc.analytics_opt_in else "disabled",
@@ -674,7 +674,7 @@ def info(
674
674
  "--skip_default_registrations",
675
675
  is_flag=True,
676
676
  default=False,
677
- help="Skip registering default workspace, user and stack.",
677
+ help="Skip registering default project, user and stack.",
678
678
  type=bool,
679
679
  )
680
680
  def migrate_database(skip_default_registrations: bool = False) -> None:
@@ -205,7 +205,7 @@ def list_code_repositories(**kwargs: Any) -> None:
205
205
 
206
206
  cli_utils.print_pydantic_models(
207
207
  repos,
208
- exclude_columns=["created", "updated", "user", "workspace"],
208
+ exclude_columns=["created", "updated", "user", "project"],
209
209
  )
210
210
 
211
211
 
zenml/cli/login.py CHANGED
@@ -246,7 +246,7 @@ def connect_to_pro_server(
246
246
  """
247
247
  from zenml.login.credentials_store import get_credentials_store
248
248
  from zenml.login.pro.client import ZenMLProClient
249
- from zenml.login.pro.tenant.models import TenantStatus
249
+ from zenml.login.pro.workspace.models import WorkspaceStatus
250
250
 
251
251
  pro_api_url = pro_api_url or ZENML_PRO_API_URL
252
252
  pro_api_url = pro_api_url.rstrip("/")
@@ -295,7 +295,7 @@ def connect_to_pro_server(
295
295
  # We also need to remove all existing API tokens associated with the
296
296
  # target ZenML Pro API, otherwise they will continue to be used after
297
297
  # the re-login flow.
298
- credentials_store.clear_all_pro_tokens(pro_api_url)
298
+ credentials_store.clear_all_pro_tokens()
299
299
  try:
300
300
  token = web_login(
301
301
  pro_api_url=pro_api_url,
@@ -310,13 +310,14 @@ def connect_to_pro_server(
310
310
  "your session expires."
311
311
  )
312
312
 
313
- tenant_id: Optional[str] = None
313
+ workspace_id: Optional[str] = None
314
314
  if token.device_metadata:
315
- tenant_id = token.device_metadata.get("tenant_id")
315
+ # TODO: is this still correct?
316
+ workspace_id = token.device_metadata.get("tenant_id")
316
317
 
317
- if tenant_id is None and pro_server is None:
318
+ if workspace_id is None and pro_server is None:
318
319
  # This is not really supposed to happen, because the implementation
319
- # of the web login workflow should always return a tenant ID, but
320
+ # of the web login workflow should always return a workspace ID, but
320
321
  # we're handling it just in case.
321
322
  cli_utils.declare(
322
323
  "A valid server was not selected during the login process. "
@@ -328,14 +329,14 @@ def connect_to_pro_server(
328
329
 
329
330
  # The server selected during the web login process overrides any
330
331
  # server argument passed to the command.
331
- server_id = UUID(tenant_id)
332
+ server_id = UUID(workspace_id)
332
333
 
333
334
  client = ZenMLProClient(pro_api_url)
334
335
 
335
336
  if server_id:
336
- server = client.tenant.get(server_id)
337
+ server = client.workspace.get(server_id)
337
338
  elif server_url:
338
- servers = client.tenant.list(url=server_url, member_only=True)
339
+ servers = client.workspace.list(url=server_url, member_only=True)
339
340
  if not servers:
340
341
  raise AuthorizationException(
341
342
  f"The '{server_url}' URL belongs to a ZenML Pro server, "
@@ -345,7 +346,9 @@ def connect_to_pro_server(
345
346
 
346
347
  server = servers[0]
347
348
  elif server_name:
348
- servers = client.tenant.list(tenant_name=server_name, member_only=True)
349
+ servers = client.workspace.list(
350
+ workspace_name=server_name, member_only=True
351
+ )
349
352
  if not servers:
350
353
  raise AuthorizationException(
351
354
  f"No ZenML Pro server with the name '{server_name}' exists "
@@ -361,15 +364,15 @@ def connect_to_pro_server(
361
364
 
362
365
  server_id = server.id
363
366
 
364
- if server.status == TenantStatus.PENDING:
367
+ if server.status == WorkspaceStatus.PENDING:
365
368
  with console.status(
366
369
  f"Waiting for your `{server.name}` ZenML Pro server to be set up..."
367
370
  ):
368
371
  timeout = 180 # 3 minutes
369
372
  while True:
370
373
  time.sleep(5)
371
- server = client.tenant.get(server_id)
372
- if server.status != TenantStatus.PENDING:
374
+ server = client.workspace.get(server_id)
375
+ if server.status != WorkspaceStatus.PENDING:
373
376
  break
374
377
  timeout -= 5
375
378
  if timeout <= 0:
@@ -380,7 +383,7 @@ def connect_to_pro_server(
380
383
  f"ZenML Pro dashboard at {server.dashboard_url}."
381
384
  )
382
385
 
383
- if server.status == TenantStatus.FAILED:
386
+ if server.status == WorkspaceStatus.FAILED:
384
387
  cli_utils.error(
385
388
  f"Your `{server.name}` ZenML Pro server is currently in a "
386
389
  "failed state. Please manage the server state by visiting the "
@@ -388,7 +391,7 @@ def connect_to_pro_server(
388
391
  "your server administrator."
389
392
  )
390
393
 
391
- elif server.status == TenantStatus.DEACTIVATED:
394
+ elif server.status == WorkspaceStatus.DEACTIVATED:
392
395
  cli_utils.error(
393
396
  f"Your `{server.name}` ZenML Pro server is currently "
394
397
  "deactivated. Please manage the server state by visiting the "
@@ -396,7 +399,7 @@ def connect_to_pro_server(
396
399
  "your server administrator."
397
400
  )
398
401
 
399
- elif server.status == TenantStatus.AVAILABLE:
402
+ elif server.status == WorkspaceStatus.AVAILABLE:
400
403
  if not server.url:
401
404
  cli_utils.error(
402
405
  f"The ZenML Pro server '{server.name}' is not currently "
@@ -418,7 +421,7 @@ def connect_to_pro_server(
418
421
  connect_to_server(server.url, api_key=api_key, pro_server=True)
419
422
 
420
423
  # Update the stored server info with more accurate data taken from the
421
- # ZenML Pro tenant object.
424
+ # ZenML Pro workspace object.
422
425
  credentials_store.update_server_info(server.url, server)
423
426
 
424
427
  cli_utils.declare(f"Connected to ZenML Pro server: {server.name}.")
@@ -836,7 +839,7 @@ def login(
836
839
  pro_api_url=pro_api_url,
837
840
  )
838
841
 
839
- elif current_non_local_server:
842
+ elif current_non_local_server and not refresh:
840
843
  # The server argument is not provided, so we default to
841
844
  # re-authenticating to the current non-local server that the client is
842
845
  # connected to.
zenml/cli/pipeline.py CHANGED
@@ -382,7 +382,7 @@ def list_pipelines(**kwargs: Any) -> None:
382
382
 
383
383
  cli_utils.print_pydantic_models(
384
384
  pipelines,
385
- exclude_columns=["id", "created", "updated", "user", "workspace"],
385
+ exclude_columns=["id", "created", "updated", "user", "project"],
386
386
  )
387
387
 
388
388
 
@@ -447,7 +447,7 @@ def list_schedules(**kwargs: Any) -> None:
447
447
 
448
448
  cli_utils.print_pydantic_models(
449
449
  schedules,
450
- exclude_columns=["id", "created", "updated", "user", "workspace"],
450
+ exclude_columns=["id", "created", "updated", "user", "project"],
451
451
  )
452
452
 
453
453
 
@@ -600,7 +600,7 @@ def list_pipeline_builds(**kwargs: Any) -> None:
600
600
  "created",
601
601
  "updated",
602
602
  "user",
603
- "workspace",
603
+ "project",
604
604
  "images",
605
605
  "stack_checksum",
606
606
  ],
zenml/cli/project.py ADDED
@@ -0,0 +1,172 @@
1
+ # Copyright (c) ZenML GmbH 2022. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at:
6
+ #
7
+ # https://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
12
+ # or implied. See the License for the specific language governing
13
+ # permissions and limitations under the License.
14
+ """Functionality to administer projects of the ZenML CLI and server."""
15
+
16
+ from typing import Any, Optional
17
+
18
+ import click
19
+
20
+ from zenml.cli import utils as cli_utils
21
+ from zenml.cli.cli import TagGroup, cli
22
+ from zenml.cli.utils import (
23
+ check_zenml_pro_project_availability,
24
+ is_sorted_or_filtered,
25
+ list_options,
26
+ )
27
+ from zenml.client import Client
28
+ from zenml.console import console
29
+ from zenml.enums import CliCategories
30
+ from zenml.models import ProjectFilter
31
+
32
+
33
+ @cli.group(cls=TagGroup, tag=CliCategories.MANAGEMENT_TOOLS)
34
+ def project() -> None:
35
+ """Commands for project management."""
36
+
37
+
38
+ @project.command("list")
39
+ @list_options(ProjectFilter)
40
+ @click.pass_context
41
+ def list_projects(ctx: click.Context, **kwargs: Any) -> None:
42
+ """List all projects.
43
+
44
+ Args:
45
+ ctx: The click context object
46
+ **kwargs: Keyword arguments to filter the list of projects.
47
+ """
48
+ check_zenml_pro_project_availability()
49
+ client = Client()
50
+ with console.status("Listing projects...\n"):
51
+ projects = client.list_projects(**kwargs)
52
+ if projects:
53
+ cli_utils.print_pydantic_models(
54
+ projects,
55
+ exclude_columns=["id", "created", "updated"],
56
+ active_models=[Client().active_project],
57
+ show_active=not is_sorted_or_filtered(ctx),
58
+ )
59
+ else:
60
+ cli_utils.declare("No projects found for the given filter.")
61
+
62
+
63
+ @project.command("register")
64
+ @click.option(
65
+ "--set",
66
+ "set_project",
67
+ is_flag=True,
68
+ help="Immediately set this project as active.",
69
+ type=click.BOOL,
70
+ )
71
+ @click.option(
72
+ "--display-name",
73
+ "display_name",
74
+ type=str,
75
+ required=False,
76
+ help="The display name of the project.",
77
+ )
78
+ @click.argument("project_name", type=str, required=True)
79
+ def register_project(
80
+ project_name: str,
81
+ set_project: bool = False,
82
+ display_name: Optional[str] = None,
83
+ ) -> None:
84
+ """Register a new project.
85
+
86
+ Args:
87
+ project_name: The name of the project to register.
88
+ set_project: Whether to set the project as active.
89
+ display_name: The display name of the project.
90
+ """
91
+ check_zenml_pro_project_availability()
92
+ client = Client()
93
+ with console.status("Creating project...\n"):
94
+ try:
95
+ client.create_project(
96
+ project_name,
97
+ description="",
98
+ display_name=display_name,
99
+ )
100
+ cli_utils.declare("Project created successfully.")
101
+ except Exception as e:
102
+ cli_utils.error(str(e))
103
+
104
+ if set_project:
105
+ client.set_active_project(project_name)
106
+ cli_utils.declare(f"The active project has been set to {project_name}")
107
+
108
+
109
+ @project.command("set")
110
+ @click.argument("project_name_or_id", type=str, required=True)
111
+ def set_project(project_name_or_id: str) -> None:
112
+ """Set the active project.
113
+
114
+ Args:
115
+ project_name_or_id: The name or ID of the project to set as active.
116
+ """
117
+ check_zenml_pro_project_availability()
118
+ client = Client()
119
+ with console.status("Setting project...\n"):
120
+ try:
121
+ client.set_active_project(project_name_or_id)
122
+ cli_utils.declare(
123
+ f"The active project has been set to {project_name_or_id}"
124
+ )
125
+ except Exception as e:
126
+ cli_utils.error(str(e))
127
+
128
+
129
+ @project.command("describe")
130
+ @click.argument("project_name_or_id", type=str, required=False)
131
+ def describe_project(project_name_or_id: Optional[str] = None) -> None:
132
+ """Get the project.
133
+
134
+ Args:
135
+ project_name_or_id: The name or ID of the project to set as active.
136
+ """
137
+ check_zenml_pro_project_availability()
138
+ client = Client()
139
+ if not project_name_or_id:
140
+ active_project = client.active_project
141
+ cli_utils.print_pydantic_models(
142
+ [active_project], exclude_columns=["created", "updated"]
143
+ )
144
+ else:
145
+ try:
146
+ project_ = client.get_project(project_name_or_id)
147
+ except KeyError as err:
148
+ cli_utils.error(str(err))
149
+ else:
150
+ cli_utils.print_pydantic_models(
151
+ [project_], exclude_columns=["created", "updated"]
152
+ )
153
+
154
+
155
+ @project.command("delete")
156
+ @click.argument("project_name_or_id", type=str, required=True)
157
+ def delete_project(project_name_or_id: str) -> None:
158
+ """Delete a project.
159
+
160
+ Args:
161
+ project_name_or_id: The name or ID of the project to delete.
162
+ """
163
+ check_zenml_pro_project_availability()
164
+ client = Client()
165
+ with console.status("Deleting project...\n"):
166
+ try:
167
+ client.delete_project(project_name_or_id)
168
+ cli_utils.declare(
169
+ f"Project '{project_name_or_id}' deleted successfully."
170
+ )
171
+ except Exception as e:
172
+ cli_utils.error(str(e))
zenml/cli/server.py CHANGED
@@ -220,7 +220,7 @@ def status() -> None:
220
220
  )
221
221
  if pro_credentials:
222
222
  pro_client = ZenMLProClient(pro_credentials.url)
223
- pro_servers = pro_client.tenant.list(
223
+ pro_servers = pro_client.workspace.list(
224
224
  url=store_cfg.url, member_only=True
225
225
  )
226
226
  if pro_servers:
@@ -575,7 +575,7 @@ def server_list(
575
575
  from zenml.login.credentials_store import get_credentials_store
576
576
  from zenml.login.pro.client import ZenMLProClient
577
577
  from zenml.login.pro.constants import ZENML_PRO_API_URL
578
- from zenml.login.pro.tenant.models import TenantRead, TenantStatus
578
+ from zenml.login.pro.workspace.models import WorkspaceRead, WorkspaceStatus
579
579
 
580
580
  pro_api_url = pro_api_url or ZENML_PRO_API_URL
581
581
  pro_api_url = pro_api_url.rstrip("/")
@@ -601,10 +601,10 @@ def server_list(
601
601
  # that the user has never connected to (and are therefore not stored in
602
602
  # the credentials store).
603
603
 
604
- accessible_pro_servers: List[TenantRead] = []
604
+ accessible_pro_servers: List[WorkspaceRead] = []
605
605
  try:
606
606
  client = ZenMLProClient(pro_api_url)
607
- accessible_pro_servers = client.tenant.list(member_only=not all)
607
+ accessible_pro_servers = client.workspace.list(member_only=not all)
608
608
  except AuthorizationException as e:
609
609
  cli_utils.warning(f"ZenML Pro authorization error: {e}")
610
610
 
@@ -638,7 +638,7 @@ def server_list(
638
638
  accessible_pro_servers = [
639
639
  s
640
640
  for s in accessible_pro_servers
641
- if s.status == TenantStatus.AVAILABLE
641
+ if s.status == WorkspaceStatus.AVAILABLE
642
642
  ]
643
643
 
644
644
  if not accessible_pro_servers:
@@ -410,7 +410,6 @@ def list_api_keys(service_account_name_or_id: str, **kwargs: Any) -> None:
410
410
  exclude_columns=[
411
411
  "created",
412
412
  "updated",
413
- "workspace",
414
413
  "key",
415
414
  "retain_period_minutes",
416
415
  ],
@@ -1902,29 +1902,28 @@ def login_service_connector(
1902
1902
  "list-resources",
1903
1903
  help="""List all resources accessible by service connectors.
1904
1904
 
1905
- This command can be used to list all resources that can be accessed by service
1906
- connectors configured in your workspace. You can filter the list by connector
1905
+ This command can be used to list all resources that can be accessed by the
1906
+ currently registered service connectors. You can filter the list by connector
1907
1907
  type and/or resource type.
1908
1908
 
1909
1909
  Use this command to answer questions like:
1910
1910
 
1911
1911
  - show a list of all Kubernetes clusters that can be accessed by way of service
1912
- connectors configured in my workspace
1913
- - show a list of all connectors configured for my workspace along with all the
1914
- resources they can access or the error state they are in, if any
1912
+ connectors
1913
+ - show a list of all connectors along with all the resources they can access or
1914
+ the error state they are in, if any
1915
1915
 
1916
- NOTE: since this command exercises all service connectors in your workspace, it
1917
- may take a while to complete.
1916
+ NOTE: since this command exercises all service connectors currently registered
1917
+ with ZenML, it may take a while to complete.
1918
1918
 
1919
1919
  Examples:
1920
1920
 
1921
- - show a list of all S3 buckets that can be accessed by service connectors
1922
- configured in your workspace:
1921
+ - show a list of all S3 buckets that can be accessed by service connectors:
1923
1922
 
1924
1923
  $ zenml service-connector list-resources --resource-type s3-bucket
1925
1924
 
1926
- - show a list of all resources that the AWS connectors in your workspace can
1927
- access:
1925
+ - show a list of all resources that the AWS connectors currently registered
1926
+ with ZenML can access:
1928
1927
 
1929
1928
  $ zenml service-connector list-resources --connector-type aws
1930
1929
 
@@ -1982,10 +1981,10 @@ def list_service_connector_resources(
1982
1981
  if not resource_type and not resource_id:
1983
1982
  cli_utils.warning(
1984
1983
  "Fetching all service connector resources can take a long time, "
1985
- "depending on the number of connectors configured in your "
1986
- "workspace. Consider using the '--connector-type', "
1987
- "'--resource-type' and '--resource-id' options to narrow down the "
1988
- "list of resources to fetch."
1984
+ "depending on the number of connectors currently registered with "
1985
+ "ZenML. Consider using the '--connector-type', '--resource-type' "
1986
+ "and '--resource-id' options to narrow down the list of resources "
1987
+ "to fetch."
1989
1988
  )
1990
1989
 
1991
1990
  with console.status(
@@ -2030,7 +2029,7 @@ def list_service_connector_resources(
2030
2029
 
2031
2030
  click.echo(
2032
2031
  f"The {resource_str} can be accessed by"
2033
- f"{connector_str} service connectors configured in your workspace:"
2032
+ f"{connector_str} service connectors:"
2034
2033
  )
2035
2034
 
2036
2035
  cli_utils.print_service_connector_resource_table(
zenml/cli/stack.py CHANGED
@@ -503,7 +503,6 @@ def register_stack(
503
503
  try:
504
504
  created_stack = client.zen_store.create_stack(
505
505
  stack=StackRequest(
506
- workspace=client.active_workspace.id,
507
506
  name=stack_name,
508
507
  components=components,
509
508
  service_connectors=[service_connector]
@@ -1913,7 +1912,6 @@ def _get_stack_component_info(
1913
1912
  "Enter the subscription ID:"
1914
1913
  )
1915
1914
  config["resource_group"] = Prompt.ask("Enter the resource group:")
1916
- config["workspace"] = Prompt.ask("Enter the workspace name:")
1917
1915
  elif flavor == "vertex":
1918
1916
  config["location"] = query_region(
1919
1917
  StackDeploymentProvider.GCP, "Vertex AI job"
@@ -1424,8 +1424,8 @@ def connect_stack_component_with_service_connector(
1424
1424
 
1425
1425
  cli_utils.error(
1426
1426
  f"No compatible valid resources were found for the "
1427
- f"'{component_model.name}' {display_name} in your "
1428
- f"workspace. {additional_info}You can create a new "
1427
+ f"'{component_model.name}' {display_name}. "
1428
+ f"{additional_info}You can create a new "
1429
1429
  "connector using the 'zenml service-connector register' "
1430
1430
  "command or list the compatible resources using the "
1431
1431
  f"'zenml service-connector list-resources{command_args}' "
zenml/cli/utils.py CHANGED
@@ -2268,12 +2268,12 @@ def print_pipeline_runs_table(
2268
2268
  print_table(runs_dicts)
2269
2269
 
2270
2270
 
2271
- def check_zenml_pro_workspace_availability() -> None:
2272
- """Check if the ZenML Pro workspace feature is available."""
2271
+ def check_zenml_pro_project_availability() -> None:
2272
+ """Check if the ZenML Pro project feature is available."""
2273
2273
  client = Client()
2274
2274
  if not client.zen_store.get_store_info().is_pro_server():
2275
2275
  warning(
2276
- "The ZenML workspace feature is available only on ZenML Pro. "
2276
+ "The ZenML projects feature is available only on ZenML Pro. "
2277
2277
  "Please visit https://zenml.io/pro to learn more."
2278
2278
  )
2279
2279