anyscale 0.26.29__py3-none-any.whl → 0.26.31__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 (39) hide show
  1. anyscale/__init__.py +10 -0
  2. anyscale/_private/anyscale_client/anyscale_client.py +76 -60
  3. anyscale/_private/anyscale_client/common.py +39 -1
  4. anyscale/_private/anyscale_client/fake_anyscale_client.py +11 -0
  5. anyscale/_private/docgen/__main__.py +4 -0
  6. anyscale/_private/docgen/models.md +2 -2
  7. anyscale/client/README.md +2 -0
  8. anyscale/client/openapi_client/__init__.py +1 -0
  9. anyscale/client/openapi_client/api/default_api.py +118 -0
  10. anyscale/client/openapi_client/models/__init__.py +1 -0
  11. anyscale/client/openapi_client/models/baseimagesenum.py +68 -1
  12. anyscale/client/openapi_client/models/get_or_create_build_from_image_uri_request.py +207 -0
  13. anyscale/client/openapi_client/models/supportedbaseimagesenum.py +68 -1
  14. anyscale/cluster_compute.py +3 -8
  15. anyscale/commands/command_examples.py +10 -0
  16. anyscale/commands/job_queue_commands.py +295 -104
  17. anyscale/commands/list_util.py +14 -1
  18. anyscale/commands/machine_pool_commands.py +14 -2
  19. anyscale/commands/service_commands.py +6 -12
  20. anyscale/commands/workspace_commands_v2.py +462 -25
  21. anyscale/controllers/compute_config_controller.py +3 -19
  22. anyscale/controllers/job_controller.py +5 -210
  23. anyscale/job_queue/__init__.py +89 -0
  24. anyscale/job_queue/_private/job_queue_sdk.py +158 -0
  25. anyscale/job_queue/commands.py +130 -0
  26. anyscale/job_queue/models.py +284 -0
  27. anyscale/scripts.py +1 -1
  28. anyscale/sdk/anyscale_client/models/baseimagesenum.py +68 -1
  29. anyscale/sdk/anyscale_client/models/supportedbaseimagesenum.py +68 -1
  30. anyscale/shared_anyscale_utils/latest_ray_version.py +1 -1
  31. anyscale/utils/ssh_websocket_proxy.py +178 -0
  32. anyscale/version.py +1 -1
  33. {anyscale-0.26.29.dist-info → anyscale-0.26.31.dist-info}/METADATA +3 -1
  34. {anyscale-0.26.29.dist-info → anyscale-0.26.31.dist-info}/RECORD +39 -33
  35. {anyscale-0.26.29.dist-info → anyscale-0.26.31.dist-info}/LICENSE +0 -0
  36. {anyscale-0.26.29.dist-info → anyscale-0.26.31.dist-info}/NOTICE +0 -0
  37. {anyscale-0.26.29.dist-info → anyscale-0.26.31.dist-info}/WHEEL +0 -0
  38. {anyscale-0.26.29.dist-info → anyscale-0.26.31.dist-info}/entry_points.txt +0 -0
  39. {anyscale-0.26.29.dist-info → anyscale-0.26.31.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,284 @@
1
+ from dataclasses import dataclass, field
2
+ from datetime import datetime
3
+ from typing import get_type_hints, Literal, Optional, TYPE_CHECKING, Union
4
+
5
+ from anyscale._private.models import ModelBase, ModelEnum
6
+
7
+
8
+ class JobQueueState(ModelEnum):
9
+ """Current state of a job queue."""
10
+
11
+ ACTIVE = "ACTIVE"
12
+ SEALED = "SEALED"
13
+ # Add other potential states if necessary based on API reality
14
+ UNKNOWN = "UNKNOWN"
15
+
16
+ __docstrings__ = {
17
+ ACTIVE: "The job queue is active and accepting jobs.",
18
+ SEALED: "The job queue is sealed and not accepting new jobs. It may still be processing existing jobs.",
19
+ UNKNOWN: "The state of the job queue is unknown or could not be determined.",
20
+ }
21
+
22
+
23
+ class JobQueueSortField(ModelEnum):
24
+ """Fields available for sorting job queues."""
25
+
26
+ ID = "ID"
27
+ NAME = "NAME"
28
+ CREATED_AT = "CREATED_AT"
29
+ CREATOR_ID = "CREATOR_ID"
30
+ CREATOR_EMAIL = "CREATOR_EMAIL"
31
+ PROJECT_ID = "PROJECT_ID"
32
+ CLOUD_ID = "CLOUD_ID"
33
+ QUEUE_STATE = "QUEUE_STATE"
34
+ CLUSTER_STATE = "CLUSTER_STATE"
35
+
36
+ __docstrings__ = {
37
+ ID: "Sort by Job Queue ID.",
38
+ NAME: "Sort by Job Queue name.",
39
+ CREATED_AT: "Sort by creation timestamp.",
40
+ CREATOR_ID: "Sort by the ID of the creator.",
41
+ CREATOR_EMAIL: "Sort by the email of the creator.",
42
+ PROJECT_ID: "Sort by the Project ID.",
43
+ CLOUD_ID: "Sort by the Cloud ID.",
44
+ QUEUE_STATE: "Sort by the Job Queue's state (ACTIVE, SEALED).",
45
+ CLUSTER_STATE: "Sort by the state of the associated cluster.",
46
+ }
47
+
48
+
49
+ class ExecutionMode(ModelEnum):
50
+ """Execution mode of a job queue."""
51
+
52
+ FIFO = "FIFO"
53
+ LIFO = "LIFO"
54
+ PRIORITY = "PRIORITY"
55
+ # Add other execution modes as needed
56
+ UNKNOWN = "UNKNOWN"
57
+
58
+ __docstrings__ = {
59
+ FIFO: "FIFO execution mode.",
60
+ LIFO: "LIFO execution mode.",
61
+ PRIORITY: "Priority-based execution mode.",
62
+ UNKNOWN: "Unknown execution mode.",
63
+ }
64
+
65
+
66
+ class ClusterState(ModelEnum):
67
+ """Possible states for a cluster."""
68
+
69
+ RUNNING = "RUNNING"
70
+ TERMINATED = "TERMINATED"
71
+ PENDING = "PENDING"
72
+ # Add other states as needed
73
+ UNKNOWN = "UNKNOWN"
74
+
75
+ __docstrings__ = {
76
+ RUNNING: "The cluster is running.",
77
+ TERMINATED: "The cluster is terminated.",
78
+ PENDING: "The cluster is pending creation.",
79
+ UNKNOWN: "The state of the cluster is unknown.",
80
+ }
81
+
82
+
83
+ @dataclass(frozen=True)
84
+ class JobQueueStatus(ModelBase):
85
+ """Represents the status and details of a Job Queue."""
86
+
87
+ id: str = field(metadata={"docstring": "Unique ID of the job queue."})
88
+ state: Union[JobQueueState, str] = field(
89
+ metadata={"docstring": "Current state of the job queue."}
90
+ )
91
+ name: Optional[str] = field(
92
+ default=None, metadata={"docstring": "Name of the job queue."}
93
+ )
94
+ creator_email: Optional[str] = field(
95
+ default=None,
96
+ metadata={"docstring": "Email of the user who created the job queue."},
97
+ )
98
+ project_id: Optional[str] = field(
99
+ default=None,
100
+ metadata={"docstring": "ID of the project this job queue belongs to."},
101
+ )
102
+ created_at: Optional[datetime] = field(
103
+ default=None,
104
+ metadata={"docstring": "Timestamp when the job queue was created."},
105
+ )
106
+ max_concurrency: Optional[int] = field(
107
+ default=None,
108
+ metadata={"docstring": "Maximum number of jobs allowed to run concurrently."},
109
+ )
110
+ idle_timeout_s: Optional[int] = field(
111
+ default=None,
112
+ metadata={
113
+ "docstring": "Idle timeout in seconds before the queue's cluster may shut down."
114
+ },
115
+ )
116
+ user_provided_id: Optional[str] = field(
117
+ default=None,
118
+ metadata={"docstring": "User provided identifier of the job queue."},
119
+ )
120
+ execution_mode: Optional[Union[ExecutionMode, str]] = field(
121
+ default=None, metadata={"docstring": "The execution mode of the job queue."}
122
+ )
123
+ creator_id: Optional[str] = field(
124
+ default=None,
125
+ metadata={"docstring": "Identifier of user who created the job queue."},
126
+ )
127
+ cloud_id: Optional[str] = field(
128
+ default=None,
129
+ metadata={"docstring": "The cloud ID associated with the job queue."},
130
+ )
131
+ total_jobs: Optional[int] = field(
132
+ default=None, metadata={"docstring": "Total number of jobs in the job queue."},
133
+ )
134
+ successful_jobs: Optional[int] = field(
135
+ default=None,
136
+ metadata={"docstring": "Number of successful jobs in the job queue."},
137
+ )
138
+ failed_jobs: Optional[int] = field(
139
+ default=None, metadata={"docstring": "Number of failed jobs in the job queue."},
140
+ )
141
+ active_jobs: Optional[int] = field(
142
+ default=None, metadata={"docstring": "Number of active jobs in the job queue."},
143
+ )
144
+
145
+ def _validate_id(self, id: str) -> str: # noqa: A002
146
+ if not isinstance(id, str) or not id:
147
+ raise ValueError("'id' must be a non-empty string.")
148
+ return id
149
+
150
+ def _validate_name(self, name: Optional[str]) -> Optional[str]:
151
+ if name is not None and not isinstance(name, str):
152
+ raise ValueError("'name' must be a string or None.")
153
+ return name
154
+
155
+ def _validate_state(self, state: Union[JobQueueState, str]) -> JobQueueState:
156
+ return JobQueueState.validate(state)
157
+
158
+ def _validate_creator_email(self, creator_email: Optional[str]) -> Optional[str]:
159
+ if creator_email is not None and not isinstance(creator_email, str):
160
+ raise ValueError("'creator_email' must be a string or None.")
161
+ return creator_email
162
+
163
+ def _validate_project_id(self, project_id: Optional[str]) -> Optional[str]:
164
+ if project_id is not None and not isinstance(project_id, str):
165
+ raise ValueError("'project_id' must be a string or None.")
166
+ return project_id
167
+
168
+ def _validate_created_at(
169
+ self, created_at: Optional[datetime]
170
+ ) -> Optional[datetime]:
171
+ if created_at is not None and not isinstance(created_at, datetime):
172
+ raise ValueError("'created_at' must be a datetime object or None.")
173
+ return created_at
174
+
175
+ def _validate_max_concurrency(
176
+ self, max_concurrency: Optional[int]
177
+ ) -> Optional[int]:
178
+ if max_concurrency is not None:
179
+ if not isinstance(max_concurrency, int):
180
+ raise ValueError("'max_concurrency' must be an integer or None.")
181
+ if max_concurrency < 0:
182
+ raise ValueError("'max_concurrency' cannot be negative.")
183
+ return max_concurrency
184
+
185
+ def _validate_idle_timeout_s(self, idle_timeout_s: Optional[int]) -> Optional[int]:
186
+ if idle_timeout_s is not None:
187
+ if not isinstance(idle_timeout_s, int):
188
+ raise ValueError("'idle_timeout_s' must be an integer or None.")
189
+ if idle_timeout_s < 0:
190
+ raise ValueError("'idle_timeout_s' cannot be negative.")
191
+ return idle_timeout_s
192
+
193
+ def _validate_user_provided_id(
194
+ self, user_provided_id: Optional[str]
195
+ ) -> Optional[str]:
196
+ if user_provided_id is not None and not isinstance(user_provided_id, str):
197
+ raise ValueError("'user_provided_id' must be a string or None.")
198
+ return user_provided_id
199
+
200
+ def _validate_execution_mode(
201
+ self, execution_mode: Optional[Union[ExecutionMode, str]]
202
+ ) -> Optional[ExecutionMode]:
203
+ if execution_mode is not None:
204
+ return ExecutionMode.validate(execution_mode)
205
+ return None
206
+
207
+ def _validate_creator_id(self, creator_id: Optional[str]) -> Optional[str]:
208
+ if creator_id is not None and not isinstance(creator_id, str):
209
+ raise ValueError("'creator_id' must be a string or None.")
210
+ return creator_id
211
+
212
+ def _validate_cluster_id(self, cluster_id: Optional[str]) -> Optional[str]:
213
+ if cluster_id is not None and not isinstance(cluster_id, str):
214
+ raise ValueError("'cluster_id' must be a string or None.")
215
+ return cluster_id
216
+
217
+ def _validate_current_cluster_state(
218
+ self, current_cluster_state: Optional[Union[ClusterState, str]]
219
+ ) -> Optional[ClusterState]:
220
+ if current_cluster_state is not None:
221
+ return ClusterState.validate(current_cluster_state)
222
+ return None
223
+
224
+ def _validate_cloud_id(self, cloud_id: Optional[str]) -> Optional[str]:
225
+ if cloud_id is not None and not isinstance(cloud_id, str):
226
+ raise ValueError("'cloud_id' must be a string or None.")
227
+ return cloud_id
228
+
229
+ def _validate_total_jobs(self, total_jobs: Optional[int]) -> Optional[int]:
230
+ if total_jobs is not None:
231
+ if not isinstance(total_jobs, int):
232
+ raise ValueError("'total_jobs' must be an integer or None.")
233
+ if total_jobs < 0:
234
+ raise ValueError("'total_jobs' cannot be negative.")
235
+ return total_jobs
236
+
237
+ def _validate_successful_jobs(
238
+ self, successful_jobs: Optional[int]
239
+ ) -> Optional[int]:
240
+ if successful_jobs is not None:
241
+ if not isinstance(successful_jobs, int):
242
+ raise ValueError("'successful_jobs' must be an integer or None.")
243
+ if successful_jobs < 0:
244
+ raise ValueError("'successful_jobs' cannot be negative.")
245
+ return successful_jobs
246
+
247
+ def _validate_failed_jobs(self, failed_jobs: Optional[int]) -> Optional[int]:
248
+ if failed_jobs is not None:
249
+ if not isinstance(failed_jobs, int):
250
+ raise ValueError("'failed_jobs' must be an integer or None.")
251
+ if failed_jobs < 0:
252
+ raise ValueError("'failed_jobs' cannot be negative.")
253
+ return failed_jobs
254
+
255
+ def _validate_active_jobs(self, active_jobs: Optional[int]) -> Optional[int]:
256
+ if active_jobs is not None:
257
+ if not isinstance(active_jobs, int):
258
+ raise ValueError("'active_jobs' must be an integer or None.")
259
+ if active_jobs < 0:
260
+ raise ValueError("'active_jobs' cannot be negative.")
261
+ return active_jobs
262
+
263
+
264
+ if TYPE_CHECKING:
265
+ JobQueueStatusKeys = Literal[
266
+ "active_jobs",
267
+ "cloud_id",
268
+ "created_at",
269
+ "creator_email",
270
+ "creator_id",
271
+ "execution_mode",
272
+ "failed_jobs",
273
+ "id",
274
+ "idle_timeout_s",
275
+ "max_concurrency",
276
+ "name",
277
+ "project_id",
278
+ "state",
279
+ "successful_jobs",
280
+ "total_jobs",
281
+ "user_provided_id",
282
+ ]
283
+ else:
284
+ JobQueueStatusKeys = Literal[tuple(get_type_hints(JobQueueStatus).keys())]
anyscale/scripts.py CHANGED
@@ -121,7 +121,7 @@ cli.add_command(version_cli)
121
121
  cli.add_command(list_cli)
122
122
  cli.add_command(cluster_env_cli)
123
123
  cli.add_command(job_cli)
124
- # cli.add_command(job_queue_cli) # TODO will be enabled later
124
+ cli.add_command(job_queue_cli)
125
125
  cli.add_command(schedule_cli)
126
126
  cli.add_command(service_cli)
127
127
  cli.add_command(cluster_cli)