anyscale 0.26.29__py3-none-any.whl → 0.26.30__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.
anyscale/__init__.py CHANGED
@@ -25,6 +25,7 @@ from anyscale import (
25
25
  image,
26
26
  integrations,
27
27
  job,
28
+ job_queue,
28
29
  llm,
29
30
  organization_invitation,
30
31
  project,
@@ -46,6 +47,7 @@ from anyscale.compute_config import ComputeConfigSDK
46
47
  from anyscale.connect import ClientBuilder
47
48
  from anyscale.image import ImageSDK
48
49
  from anyscale.job import JobSDK
50
+ from anyscale.job_queue import JobQueueSDK
49
51
  from anyscale.llm import LLMSDK
50
52
  from anyscale.organization_invitation import OrganizationInvitationSDK
51
53
  from anyscale.project import ProjectSDK
@@ -119,6 +121,7 @@ class Anyscale:
119
121
  client=self._anyscale_client
120
122
  )
121
123
  self._job_sdk = JobSDK(client=self._anyscale_client)
124
+ self._job_queue_sdk = JobQueueSDK(client=self._anyscale_client)
122
125
  self._service_sdk = ServiceSDK(client=self._anyscale_client)
123
126
  self._compute_config_sdk = ComputeConfigSDK(client=self._anyscale_client)
124
127
  self._cloud_sdk = CloudSDK(client=self._anyscale_client)
@@ -146,6 +149,9 @@ class Anyscale:
146
149
  client=client, logger=logger, timer=timer
147
150
  )
148
151
  obj._job_sdk = JobSDK(client=client, logger=logger, timer=timer) # noqa: SLF001
152
+ obj._job_queue_sdk = JobQueueSDK( # noqa: SLF001
153
+ client=client, logger=logger, timer=timer
154
+ )
149
155
  obj._service_sdk = ServiceSDK( # noqa: SLF001
150
156
  client=client, logger=logger, timer=timer
151
157
  )
@@ -187,6 +193,10 @@ class Anyscale:
187
193
  def job(self) -> JobSDK: # noqa: F811
188
194
  return self._job_sdk
189
195
 
196
+ @property
197
+ def job_queue(self) -> JobQueueSDK: # noqa: F811
198
+ return self._job_queue_sdk
199
+
190
200
  @property
191
201
  def service(self) -> ServiceSDK: # noqa: F811
192
202
  return self._service_sdk
@@ -60,6 +60,7 @@ from anyscale.client.openapi_client.models import (
60
60
  Dataset as InternalDataset,
61
61
  DatasetUpload,
62
62
  DecoratedComputeTemplate,
63
+ DecoratedjobqueueListResponse,
63
64
  DecoratedlistserviceapimodelListResponse,
64
65
  DecoratedProductionServiceV2APIModel,
65
66
  DecoratedSession,
@@ -68,6 +69,8 @@ from anyscale.client.openapi_client.models import (
68
69
  FineTunedModel,
69
70
  FinetunedmodelListResponse,
70
71
  InternalProductionJob,
72
+ JobQueueSortDirective,
73
+ JobQueuesQuery,
71
74
  ListResourceQuotasQuery,
72
75
  OrganizationCollaborator,
73
76
  OrganizationInvitation,
@@ -75,13 +78,18 @@ from anyscale.client.openapi_client.models import (
75
78
  ResourceQuotaStatus,
76
79
  ServerSessionToken,
77
80
  SessionSshKey,
81
+ SessionState,
78
82
  StartSessionOptions,
79
83
  StopSessionOptions,
80
84
  WorkspaceDataplaneProxiedArtifacts,
81
85
  )
82
86
  from anyscale.client.openapi_client.models.create_schedule import CreateSchedule
87
+ from anyscale.client.openapi_client.models.decorated_job_queue import DecoratedJobQueue
83
88
  from anyscale.client.openapi_client.models.decorated_schedule import DecoratedSchedule
84
89
  from anyscale.client.openapi_client.models.production_job import ProductionJob
90
+ from anyscale.client.openapi_client.models.update_job_queue_request import (
91
+ UpdateJobQueueRequest,
92
+ )
85
93
  from anyscale.client.openapi_client.rest import ApiException as InternalApiException
86
94
  from anyscale.cluster_compute import parse_cluster_compute_name_version
87
95
  from anyscale.feature_flags import FLAG_DEFAULT_WORKING_DIR_FOR_PROJ
@@ -1154,6 +1162,67 @@ class AnyscaleClient(AnyscaleClientInterface):
1154
1162
  )
1155
1163
  return job_runs
1156
1164
 
1165
+ @handle_api_exceptions
1166
+ def get_job_queue(self, job_queue_id: str) -> Optional[DecoratedJobQueue]:
1167
+ try:
1168
+ return self._internal_api_client.get_job_queue_api_v2_job_queues_job_queue_id_get(
1169
+ job_queue_id
1170
+ ).result
1171
+ except InternalApiException as e:
1172
+ if e.status == 404:
1173
+ return None
1174
+
1175
+ raise e from None
1176
+
1177
+ @handle_api_exceptions
1178
+ def update_job_queue(
1179
+ self,
1180
+ job_queue_id: str,
1181
+ max_concurrency: Optional[int] = None,
1182
+ idle_timeout_s: Optional[int] = None,
1183
+ ) -> DecoratedJobQueue:
1184
+ if max_concurrency is None and idle_timeout_s is None:
1185
+ raise ValueError("No fields to update")
1186
+
1187
+ return self._internal_api_client.update_job_queue_api_v2_job_queues_job_queue_id_put(
1188
+ job_queue_id,
1189
+ update_job_queue_request=UpdateJobQueueRequest(
1190
+ max_concurrency=max_concurrency, idle_timeout_sec=idle_timeout_s,
1191
+ ),
1192
+ ).result
1193
+
1194
+ @handle_api_exceptions
1195
+ def list_job_queues(
1196
+ self,
1197
+ *,
1198
+ name: Optional[str] = None,
1199
+ creator_id: Optional[str] = None,
1200
+ cluster_status: Optional[SessionState] = None,
1201
+ project: Optional[str] = None,
1202
+ cloud: Optional[str] = None,
1203
+ count: Optional[int] = None,
1204
+ paging_token: Optional[str] = None,
1205
+ sorting_directives: Optional[List[JobQueueSortDirective]] = None,
1206
+ ) -> DecoratedjobqueueListResponse:
1207
+ cloud_id = self.get_cloud_id(cloud_name=cloud) if cloud else None
1208
+ project_id = (
1209
+ self.get_project_id(parent_cloud_id=cloud_id, name=project)
1210
+ if project
1211
+ else None
1212
+ )
1213
+
1214
+ return self._internal_api_client.list_job_queues_api_v2_job_queues_post(
1215
+ job_queues_query=JobQueuesQuery(
1216
+ name=name,
1217
+ creator_id=creator_id,
1218
+ cluster_status=cluster_status,
1219
+ project_id=project_id,
1220
+ cloud_id=cloud_id,
1221
+ paging=PageQuery(count=count, paging_token=paging_token),
1222
+ sorting_directives=sorting_directives,
1223
+ ),
1224
+ )
1225
+
1157
1226
  @handle_api_exceptions
1158
1227
  def rollout_service(
1159
1228
  self, model: ApplyProductionServiceV2Model
@@ -15,19 +15,23 @@ from anyscale.client.openapi_client.models import (
15
15
  CreateResourceQuota,
16
16
  CreateUserProjectCollaborator,
17
17
  DecoratedComputeTemplate,
18
+ DecoratedjobqueueListResponse,
18
19
  DecoratedlistserviceapimodelListResponse,
19
20
  DecoratedProductionServiceV2APIModel,
20
21
  DeletedPlatformFineTunedModel,
21
22
  FineTunedModel,
22
23
  InternalProductionJob,
24
+ JobQueueSortDirective,
23
25
  OrganizationCollaborator,
24
26
  OrganizationInvitation,
25
27
  Project,
26
28
  ResourceQuota,
27
29
  ServerSessionToken,
30
+ SessionState,
28
31
  WorkspaceDataplaneProxiedArtifacts,
29
32
  )
30
33
  from anyscale.client.openapi_client.models.create_schedule import CreateSchedule
34
+ from anyscale.client.openapi_client.models.decorated_job_queue import DecoratedJobQueue
31
35
  from anyscale.client.openapi_client.models.decorated_schedule import DecoratedSchedule
32
36
  from anyscale.client.openapi_client.models.decorated_session import DecoratedSession
33
37
  from anyscale.client.openapi_client.models.production_job import ProductionJob
@@ -366,6 +370,24 @@ class AnyscaleClientInterface(ABC):
366
370
  """
367
371
  raise NotImplementedError
368
372
 
373
+ @abstractmethod
374
+ def get_job_queue(self, job_queue_id: str) -> Optional[DecoratedJobQueue]:
375
+ """Get a job queue by id.
376
+
377
+ Returns None if not found.
378
+ """
379
+ raise NotImplementedError
380
+
381
+ @abstractmethod
382
+ def update_job_queue(
383
+ self,
384
+ job_queue_id: str,
385
+ max_concurrency: Optional[int] = None,
386
+ idle_timeout_s: Optional[int] = None,
387
+ ) -> DecoratedJobQueue:
388
+ """Update a job queue."""
389
+ raise NotImplementedError
390
+
369
391
  @abstractmethod
370
392
  def get_job_runs(self, job_id: str) -> List[APIJobRun]:
371
393
  """Returns all job runs for a given job id.
@@ -374,6 +396,22 @@ class AnyscaleClientInterface(ABC):
374
396
  """
375
397
  raise NotImplementedError
376
398
 
399
+ @abstractmethod
400
+ def list_job_queues(
401
+ self,
402
+ *,
403
+ name: Optional[str] = None,
404
+ creator_id: Optional[str] = None,
405
+ cluster_status: Optional[SessionState] = None,
406
+ project: Optional[str] = None,
407
+ cloud: Optional[str] = None,
408
+ count: Optional[int] = None,
409
+ paging_token: Optional[str] = None,
410
+ sorting_directives: Optional[List[JobQueueSortDirective]] = None,
411
+ ) -> DecoratedjobqueueListResponse:
412
+ """List job queues."""
413
+ raise NotImplementedError
414
+
377
415
  @abstractmethod
378
416
  def rollout_service(
379
417
  self, model: ApplyProductionServiceV2Model
@@ -49,6 +49,7 @@ from anyscale.client.openapi_client.models import (
49
49
  WorkspaceDataplaneProxiedArtifacts,
50
50
  )
51
51
  from anyscale.client.openapi_client.models.create_schedule import CreateSchedule
52
+ from anyscale.client.openapi_client.models.decorated_job_queue import DecoratedJobQueue
52
53
  from anyscale.client.openapi_client.models.decorated_schedule import DecoratedSchedule
53
54
  from anyscale.client.openapi_client.models.decorated_session import DecoratedSession
54
55
  from anyscale.client.openapi_client.models.session_ssh_key import SessionSshKey
@@ -150,6 +151,7 @@ class FakeAnyscaleClient(AnyscaleClientInterface):
150
151
  self._deleted_services: Dict[str, DecoratedProductionServiceV2APIModel] = {}
151
152
  self._jobs: Dict[str, ProductionJob] = {}
152
153
  self._job_runs: Dict[str, List[APIJobRun]] = defaultdict(list)
154
+ self._job_queues: Dict[str, DecoratedJobQueue] = {}
153
155
  self._project_to_id: Dict[Optional[str] : Dict[Optional[str], str]] = {}
154
156
  self._project_collaborators: Dict[str, List[CreateUserProjectCollaborator]] = {}
155
157
  self._rolled_out_model: Optional[ApplyProductionServiceV2Model] = None
@@ -702,6 +704,15 @@ class FakeAnyscaleClient(AnyscaleClientInterface):
702
704
  def update_job_run(self, prod_job_id: str, model: APIJobRun):
703
705
  self._job_runs[prod_job_id].append(model)
704
706
 
707
+ def list_job_queues(self) -> List[DecoratedJobQueue]:
708
+ return list(self._job_queues.values())
709
+
710
+ def get_job_queue(self, job_queue_id: str) -> Optional[DecoratedJobQueue]:
711
+ return self._job_queues.get(job_queue_id, None)
712
+
713
+ def update_job_queue(self, model: DecoratedJobQueue):
714
+ self._job_queues[model.id] = model
715
+
705
716
  def register_project_by_name(
706
717
  self,
707
718
  name: str,
@@ -527,8 +527,12 @@ ALL_MODULES = [
527
527
  cli_prefix="anyscale machine-pool",
528
528
  cli_commands=[
529
529
  machine_pool_commands.create_machine_pool,
530
+ machine_pool_commands.update_machine_pool,
530
531
  machine_pool_commands.delete_machine_pool,
532
+ machine_pool_commands.attach_machine_pool_to_cloud,
533
+ machine_pool_commands.detach_machine_pool_from_cloud,
531
534
  machine_pool_commands.list_machine_pools,
535
+ machine_pool_commands.describe,
532
536
  ],
533
537
  sdk_prefix="anyscale.machine_pool",
534
538
  sdk_commands=[],
@@ -312,6 +312,16 @@ MACHINE POOL ID Clouds
312
312
  can-testing mp_8ogdz85mdwxb8a92yo44nn84ox
313
313
  """
314
314
 
315
+ MACHINE_POOL_ATTACH_EXAMPLE = """\
316
+ $ anyscale machine-pool attach --name can-testing --cloud my-cloud
317
+ Attached machine pool 'can-testing' to cloud 'my-cloud'.
318
+ """
319
+
320
+ MACHINE_POOL_DETACH_EXAMPLE = """\
321
+ $ anyscale machine-pool detach --name can-testing --cloud my-cloud
322
+ Detached machine pool 'can-testing' from cloud 'my-cloud'.
323
+ """
324
+
315
325
  LLM_MODELS_GET_EXAMPLE = """
316
326
  $ anyscale llm model get --model-id my-model-id
317
327
  Output