anyscale 0.26.30__py3-none-any.whl → 0.26.32__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 (36) hide show
  1. anyscale/_private/anyscale_client/anyscale_client.py +22 -60
  2. anyscale/_private/anyscale_client/common.py +12 -1
  3. anyscale/_private/anyscale_client/fake_anyscale_client.py +24 -0
  4. anyscale/_private/docgen/__main__.py +2 -0
  5. anyscale/_private/docgen/models.md +2 -2
  6. anyscale/client/README.md +9 -0
  7. anyscale/client/openapi_client/__init__.py +7 -0
  8. anyscale/client/openapi_client/api/default_api.py +232 -0
  9. anyscale/client/openapi_client/models/__init__.py +7 -0
  10. anyscale/client/openapi_client/models/baseimagesenum.py +135 -1
  11. anyscale/client/openapi_client/models/cluster_operation.py +266 -0
  12. anyscale/client/openapi_client/models/cluster_operation_type.py +101 -0
  13. anyscale/client/openapi_client/models/clusteroperation_response.py +121 -0
  14. anyscale/client/openapi_client/models/get_or_create_build_from_image_uri_request.py +207 -0
  15. anyscale/client/openapi_client/models/operation_error.py +123 -0
  16. anyscale/client/openapi_client/models/operation_progress.py +123 -0
  17. anyscale/client/openapi_client/models/operation_result.py +150 -0
  18. anyscale/client/openapi_client/models/supportedbaseimagesenum.py +135 -1
  19. anyscale/cloud/__init__.py +16 -0
  20. anyscale/cloud/_private/cloud_sdk.py +33 -0
  21. anyscale/cloud/commands.py +35 -0
  22. anyscale/cluster_compute.py +3 -8
  23. anyscale/commands/cloud_commands.py +35 -0
  24. anyscale/commands/command_examples.py +6 -0
  25. anyscale/controllers/compute_config_controller.py +3 -19
  26. anyscale/sdk/anyscale_client/models/baseimagesenum.py +135 -1
  27. anyscale/sdk/anyscale_client/models/supportedbaseimagesenum.py +135 -1
  28. anyscale/shared_anyscale_utils/latest_ray_version.py +1 -1
  29. anyscale/version.py +1 -1
  30. {anyscale-0.26.30.dist-info → anyscale-0.26.32.dist-info}/METADATA +1 -1
  31. {anyscale-0.26.30.dist-info → anyscale-0.26.32.dist-info}/RECORD +36 -29
  32. {anyscale-0.26.30.dist-info → anyscale-0.26.32.dist-info}/LICENSE +0 -0
  33. {anyscale-0.26.30.dist-info → anyscale-0.26.32.dist-info}/NOTICE +0 -0
  34. {anyscale-0.26.30.dist-info → anyscale-0.26.32.dist-info}/WHEEL +0 -0
  35. {anyscale-0.26.30.dist-info → anyscale-0.26.32.dist-info}/entry_points.txt +0 -0
  36. {anyscale-0.26.30.dist-info → anyscale-0.26.32.dist-info}/top_level.txt +0 -0
@@ -46,6 +46,7 @@ from anyscale.client.openapi_client.models import (
46
46
  CloudDataBucketPresignedUrlResponse,
47
47
  CloudDataBucketPresignedUrlScheme,
48
48
  CloudNameOptions,
49
+ ClusteroperationResponse,
49
50
  ComputeTemplate,
50
51
  ComputeTemplateConfig,
51
52
  ComputeTemplateQuery,
@@ -68,6 +69,7 @@ from anyscale.client.openapi_client.models import (
68
69
  ExperimentalWorkspace,
69
70
  FineTunedModel,
70
71
  FinetunedmodelListResponse,
72
+ GetOrCreateBuildFromImageUriRequest,
71
73
  InternalProductionJob,
72
74
  JobQueueSortDirective,
73
75
  JobQueuesQuery,
@@ -81,6 +83,7 @@ from anyscale.client.openapi_client.models import (
81
83
  SessionState,
82
84
  StartSessionOptions,
83
85
  StopSessionOptions,
86
+ SystemWorkloadName,
84
87
  WorkspaceDataplaneProxiedArtifacts,
85
88
  )
86
89
  from anyscale.client.openapi_client.models.create_schedule import CreateSchedule
@@ -595,6 +598,19 @@ class AnyscaleClient(AnyscaleClientInterface):
595
598
  cloud_id, collaborators
596
599
  )
597
600
 
601
+ @handle_api_exceptions
602
+ def terminate_system_cluster(self, cloud_id: str) -> ClusteroperationResponse:
603
+ return self._internal_api_client.terminate_system_cluster_api_v2_system_workload_cloud_id_terminate_post(
604
+ cloud_id
605
+ )
606
+
607
+ @handle_api_exceptions
608
+ def describe_system_workload_get_status(self, cloud_id: str) -> str:
609
+ res = self._internal_api_client.describe_system_workload_api_v2_system_workload_cloud_id_describe_post(
610
+ cloud_id, SystemWorkloadName.RAY_OBS_EVENTS_API_SERVICE, start_cluster=False
611
+ ).result
612
+ return res.status
613
+
598
614
  @handle_api_exceptions
599
615
  def create_compute_config(
600
616
  self, config: ComputeTemplateConfig, *, name: Optional[str] = None
@@ -946,69 +962,15 @@ class AnyscaleClient(AnyscaleClientInterface):
946
962
  ray_version: Optional[str] = None,
947
963
  name: Optional[str] = None,
948
964
  ) -> str:
949
- if image_uri.is_cluster_env_image():
950
- identifier = image_uri.to_cluster_env_identifier()
951
- try:
952
- build = self._external_api_client.find_cluster_environment_build_by_identifier(
953
- identifier=identifier
954
- ).result
955
- if build.status == ClusterEnvironmentBuildStatus.SUCCEEDED:
956
- return build.id
957
- else:
958
- raise RuntimeError(
959
- f"Legacy cluster environment build '{identifier}' is not a successful build."
960
- )
961
- except ExternalApiException as e:
962
- if e.status == 404:
963
- raise RuntimeError(
964
- f"Legacy cluster environment '{identifier}' is not found."
965
- )
966
- elif image_uri.is_default_image():
967
- # Default image
968
- cluster_envs = self._internal_api_client.list_application_templates_api_v2_application_templates_get(
969
- image_name_contains=image_uri.image_uri
970
- ).results
971
- for cluster_env in cluster_envs:
972
- if (
973
- cluster_env.latest_build is not None
974
- and cluster_env.latest_build.docker_image_name
975
- == image_uri.image_uri
976
- ):
977
- return cluster_env.latest_build.id
978
- raise RuntimeError(f"Default image '{image_uri.image_uri}' is not found.")
979
-
980
- # BYOD image
981
- cluster_env_name = name if name else image_uri.to_cluster_env_name()
982
- image_uri_str = str(image_uri)
983
- cluster_env = self._find_or_create_cluster_env(
984
- cluster_env_name,
985
- anonymous=not name,
986
- image_uri=image_uri_str,
987
- registry_login_secret=registry_login_secret,
988
- ray_version=ray_version,
989
- )
990
- for build in self.list_cluster_env_builds(cluster_env.id):
991
- if (
992
- # NOTE: Ignore ray version mismatch for now. We plan to eventually remove ray version from the API model.
993
- build.docker_image_name == image_uri_str
994
- and build.registry_login_secret == registry_login_secret
995
- and build.status == ClusterEnvironmentBuildStatus.SUCCEEDED
996
- ):
997
- return build.id
998
-
999
- # Still create a new build if the cluster env already exists but the build does not match the image_uri.
1000
- result = self._external_api_client.create_cluster_environment_build(
1001
- CreateClusterEnvironmentBuild(
1002
- # For historical reasons, we have to use docker_image_name instead of image_uri; but it is just a URI to the image.
1003
- cluster_environment_id=cluster_env.id,
1004
- docker_image_name=image_uri_str,
965
+ build = self._internal_api_client.get_or_create_build_from_image_uri_api_v2_builds_get_or_create_build_from_image_uri_post(
966
+ GetOrCreateBuildFromImageUriRequest(
967
+ image_uri=str(image_uri),
1005
968
  registry_login_secret=registry_login_secret,
1006
- ray_version=ray_version if ray_version else LATEST_RAY_VERSION,
969
+ ray_version=ray_version,
970
+ cluster_env_name=name,
1007
971
  )
1008
972
  ).result
1009
-
1010
- assert result.completed
1011
- return result.cluster_environment_build_id
973
+ return build.id
1012
974
 
1013
975
  @handle_api_exceptions
1014
976
  def send_workspace_notification(
@@ -8,6 +8,7 @@ from anyscale.client.openapi_client.models import (
8
8
  AdminCreateUser,
9
9
  AnyscaleServiceAccount,
10
10
  Cloud,
11
+ ClusteroperationResponse,
11
12
  ComputeTemplateConfig,
12
13
  CreateCloudCollaborator,
13
14
  CreateExperimentalWorkspace,
@@ -54,7 +55,7 @@ from anyscale.utils.workspace_notification import WorkspaceNotification
54
55
  # Maybe just make it part of the release process to update it, or fetch the
55
56
  # default builds and get the latest one. The best thing to do is probably
56
57
  # to populate this in the backend.
57
- DEFAULT_RAY_VERSION = "2.46.0" # RAY_RELEASE_UPDATE: update to latest version.
58
+ DEFAULT_RAY_VERSION = "2.47.1" # RAY_RELEASE_UPDATE: update to latest version.
58
59
  DEFAULT_PYTHON_VERSION = "py311"
59
60
  RUNTIME_ENV_PACKAGE_FORMAT = "pkg_{content_hash}.zip"
60
61
 
@@ -175,6 +176,16 @@ class AnyscaleClientInterface(ABC):
175
176
  """Batch add collaborators to a cloud."""
176
177
  raise NotImplementedError
177
178
 
179
+ @abstractmethod
180
+ def terminate_system_cluster(self, cloud_id: str) -> ClusteroperationResponse:
181
+ """Terminate the system cluster for the provided cloud ID."""
182
+ raise NotImplementedError
183
+
184
+ @abstractmethod
185
+ def describe_system_workload_get_status(self, cloud_id: str) -> str:
186
+ """Get the status of the system cluster for the provided cloud ID."""
187
+ raise NotImplementedError
188
+
178
189
  @abstractmethod
179
190
  def create_compute_config(
180
191
  self, config: ComputeTemplateConfig, *, name: Optional[str] = None
@@ -19,6 +19,9 @@ from anyscale.client.openapi_client.models import (
19
19
  AnyscaleServiceAccount,
20
20
  Cloud,
21
21
  CloudProviders,
22
+ ClusterOperation,
23
+ ClusteroperationResponse,
24
+ ClusterState,
22
25
  ComputeTemplateConfig,
23
26
  CreateCloudCollaborator,
24
27
  CreateExperimentalWorkspace,
@@ -177,6 +180,7 @@ class FakeAnyscaleClient(AnyscaleClientInterface):
177
180
  self._organization_collaborators: List[OrganizationCollaborator] = []
178
181
  self._organization_invitations: Dict[str, OrganizationInvitation] = {}
179
182
  self._resource_quotas: Dict[str, ResourceQuota] = {}
183
+ self._system_cluster_status: Dict[str, str] = {}
180
184
 
181
185
  # Cloud ID -> Cloud.
182
186
  self._clouds: Dict[str, Cloud] = {
@@ -369,6 +373,7 @@ class FakeAnyscaleClient(AnyscaleClientInterface):
369
373
 
370
374
  def add_cloud(self, cloud: Cloud):
371
375
  self._clouds[cloud.id] = cloud
376
+ self._system_cluster_status[cloud.id] = ClusterState.RUNNING
372
377
 
373
378
  def get_cloud(self, *, cloud_id: str) -> Optional[Cloud]:
374
379
  return self._clouds.get(cloud_id, None)
@@ -401,6 +406,25 @@ class FakeAnyscaleClient(AnyscaleClientInterface):
401
406
  else:
402
407
  self._cloud_collaborators[cloud_id].extend(collaborators)
403
408
 
409
+ def terminate_system_cluster(
410
+ self, cloud_id: str
411
+ ) -> Optional[ClusteroperationResponse]:
412
+ self._system_cluster_status[cloud_id] = ClusterState.TERMINATING
413
+ return ClusteroperationResponse(
414
+ result=ClusterOperation(
415
+ id="sop_123",
416
+ completed=False,
417
+ progress=None,
418
+ result=None,
419
+ cluster_id="fake-system-cluster-id",
420
+ cluster_operation_type="terminate",
421
+ )
422
+ )
423
+
424
+ def describe_system_workload_get_status(self, cloud_id: str) -> str:
425
+ self._system_cluster_status[cloud_id] = ClusterState.TERMINATED
426
+ return self._system_cluster_status[cloud_id]
427
+
404
428
  def add_compute_config(self, compute_config: DecoratedComputeTemplate) -> int:
405
429
  compute_config.version = (
406
430
  len(self._compute_config_name_to_ids[compute_config.name]) + 1
@@ -436,12 +436,14 @@ ALL_MODULES = [
436
436
  cloud_commands.add_collaborators,
437
437
  cloud_commands.get_cloud,
438
438
  cloud_commands.get_default_cloud,
439
+ cloud_commands.terminate_system_cluster,
439
440
  ],
440
441
  sdk_prefix="anyscale.cloud",
441
442
  sdk_commands=[
442
443
  anyscale.cloud.add_collaborators,
443
444
  anyscale.cloud.get,
444
445
  anyscale.cloud.get_default,
446
+ anyscale.cloud.terminate_system_cluster,
445
447
  ],
446
448
  models=[
447
449
  CloudPermissionLevel,