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.
@@ -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)
@@ -0,0 +1,178 @@
1
+ #!/usr/bin/env python3
2
+ import asyncio
3
+ import logging
4
+ import os
5
+ import sys
6
+
7
+ import websockets
8
+
9
+
10
+ # Define global constants
11
+ DEFAULT_CHUNK_SIZE = 4096
12
+ LOG_FORMAT = "%(asctime)s - %(name)s - %(levelname)s - %(funcName)s - %(message)s"
13
+
14
+ # Configure logging
15
+ DEBUG_ENABLED = os.environ.get("ANYSCALE_SSH_DEBUG") == "1"
16
+ LOG_LEVEL = logging.DEBUG if DEBUG_ENABLED else logging.INFO
17
+ logging.basicConfig(level=LOG_LEVEL, format=LOG_FORMAT, stream=sys.stderr)
18
+ logger = logging.getLogger(__name__)
19
+
20
+
21
+ async def pump(stream_reader: asyncio.StreamReader, send_func):
22
+ logger.debug("pump: started")
23
+ try:
24
+ while True:
25
+ logger.debug("pump: trying to read from stream_reader")
26
+ chunk = await stream_reader.read(DEFAULT_CHUNK_SIZE)
27
+ logger.debug(
28
+ f"pump: read {len(chunk) if chunk else 0} bytes from stream_reader"
29
+ )
30
+ if not chunk: # EOF
31
+ logger.debug("pump: EOF from stream_reader, closing send_func")
32
+ await send_func.close()
33
+ logger.debug("pump: send_func closed")
34
+ return
35
+ logger.debug(f"pump: sending {len(chunk)} bytes to websocket")
36
+ await send_func(chunk)
37
+ logger.debug("pump: sent to websocket")
38
+ except websockets.ConnectionClosedOK:
39
+ logger.debug("pump: ConnectionClosedOK")
40
+ except asyncio.CancelledError:
41
+ logger.debug("pump: CancelledError")
42
+ raise
43
+ except Exception:
44
+ logger.exception("pump: Exception encountered")
45
+ if not getattr(send_func, "closed", False):
46
+ logger.debug("pump: Exception, closing send_func")
47
+ await send_func.close()
48
+ logger.debug("pump: send_func closed due to exception")
49
+ raise
50
+ finally:
51
+ logger.debug("pump: finished")
52
+
53
+
54
+ async def drain(ws_receive_func):
55
+ logger.debug("drain: started")
56
+ try:
57
+ async for msg in ws_receive_func:
58
+ logger.debug(
59
+ f"drain: received {len(msg) if isinstance(msg, bytes) else type(msg)} from websocket"
60
+ )
61
+ if isinstance(msg, bytes):
62
+ sys.stdout.buffer.write(msg)
63
+ sys.stdout.buffer.flush()
64
+ logger.debug("drain: wrote to stdout and flushed")
65
+ else:
66
+ logger.warning(f"Received unexpected non-bytes message: {type(msg)}")
67
+ except websockets.ConnectionClosedOK:
68
+ logger.debug("drain: ConnectionClosedOK")
69
+ except asyncio.CancelledError:
70
+ logger.debug("drain: CancelledError")
71
+ raise
72
+ except Exception:
73
+ logger.exception("drain: Exception encountered")
74
+ raise
75
+ finally:
76
+ logger.debug("drain: finished")
77
+
78
+
79
+ async def main():
80
+ if len(sys.argv) < 2:
81
+ logger.debug("WebSocket URL must be provided as the first argument.")
82
+ sys.exit(1)
83
+
84
+ ws_url = sys.argv[1]
85
+ logger.debug(f"WebSocket URL: {ws_url}")
86
+
87
+ # Check for optional token argument
88
+ auth_token = None
89
+ if len(sys.argv) >= 3:
90
+ auth_token = sys.argv[2]
91
+ logger.debug("Authentication token provided as second argument")
92
+
93
+ loop = asyncio.get_running_loop()
94
+ reader = asyncio.StreamReader(loop=loop)
95
+ protocol = asyncio.StreamReaderProtocol(reader, loop=loop)
96
+ await loop.connect_read_pipe(lambda: protocol, sys.stdin)
97
+ logger.debug("stdin connected to StreamReader")
98
+
99
+ # Prepare additional headers if token is provided
100
+ additional_headers = {}
101
+ if auth_token:
102
+ additional_headers["Authorization"] = f"Bearer {auth_token}"
103
+ logger.debug("Added Authorization header with Bearer token")
104
+
105
+ try:
106
+ logger.debug("Attempting to connect to websocket...")
107
+ async with websockets.connect(
108
+ ws_url, additional_headers=additional_headers
109
+ ) as ws:
110
+ logger.debug("Connected to websocket successfully")
111
+ pump_task = asyncio.create_task(pump(reader, ws.send))
112
+ drain_task = asyncio.create_task(drain(ws))
113
+
114
+ done, pending = await asyncio.wait(
115
+ [pump_task, drain_task], return_when=asyncio.FIRST_COMPLETED,
116
+ )
117
+
118
+ # Convert pending set to a list to maintain order for results processing
119
+ pending_list = list(pending)
120
+
121
+ for task in pending_list: # Iterate over the list
122
+ logger.debug(f"Cancelling pending task {task.get_name()}")
123
+ task.cancel()
124
+
125
+ # Wait for pending tasks to finish cancellation
126
+ # Pass the list of pending tasks to gather
127
+ results = await asyncio.gather(*pending_list, return_exceptions=True)
128
+
129
+ for i, result in enumerate(results):
130
+ if isinstance(result, Exception) and not isinstance(
131
+ result, asyncio.CancelledError
132
+ ):
133
+ # Use pending_list[i] to get the corresponding task
134
+ task_name = (
135
+ pending_list[i].get_name()
136
+ if pending_list[i].get_name()
137
+ else "unnamed task"
138
+ )
139
+ logger.debug(
140
+ f"Pending task '{task_name}' raised an exception: {result!r}"
141
+ )
142
+ logger.debug("Pump and drain tasks finished or cancelled.")
143
+
144
+ except asyncio.TimeoutError:
145
+ logger.error("Connection to websocket timed out.")
146
+ sys.exit(1)
147
+ except Exception:
148
+ logger.exception("Exception in main connection/task management logic")
149
+ raise # Re-raise after logging
150
+ finally:
151
+ logger.debug("main: finished")
152
+
153
+
154
+ if __name__ == "__main__":
155
+ try:
156
+ logger.debug("Starting proxy script")
157
+ asyncio.run(main())
158
+ except KeyboardInterrupt:
159
+ logger.debug("KeyboardInterrupt received. Exiting.")
160
+ # Python's default handler for KeyboardInterrupt will exit (usually with code 130)
161
+ except SystemExit as e:
162
+ logger.debug(f"SystemExit called with code {e.code}")
163
+ sys.exit(e.code) # Propagate the intended exit code
164
+ except websockets.exceptions.InvalidStatusCode as e_is:
165
+ # Handle InvalidStatusCode specifically to access status_code and headers
166
+ logger.debug(
167
+ f"Unhandled WebSocket InvalidStatusCode error: {e_is!r}, Status code: {e_is.status_code}"
168
+ )
169
+ sys.exit(1)
170
+ except (websockets.exceptions.WebSocketException, OSError) as e_wso:
171
+ # Handle other WebSocket and OS errors
172
+ logger.debug(f"Unhandled WebSocket/OS error: {e_wso!r}")
173
+ sys.exit(1)
174
+ except Exception as e_unhandled: # noqa: BLE001 # Catch any other unexpected exceptions
175
+ logger.debug(f"Unhandled exception: {e_unhandled!r}", exc_info=True)
176
+ sys.exit(1)
177
+ finally:
178
+ logger.debug("Proxy script exiting")
anyscale/version.py CHANGED
@@ -1 +1 @@
1
- __version__ = "0.26.29"
1
+ __version__ = "0.26.30"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: anyscale
3
- Version: 0.26.29
3
+ Version: 0.26.30
4
4
  Summary: Command Line Interface for Anyscale
5
5
  Author: Anyscale Inc.
6
6
  License: AS License
@@ -37,6 +37,8 @@ Requires-Dist: log_symbols>=0.0.14
37
37
  Requires-Dist: spinners>=0.0.24
38
38
  Requires-Dist: termcolor>=1.1.0
39
39
  Requires-Dist: colorama>=0.3.9
40
+ Requires-Dist: websockets; python_version > "3.8"
41
+ Requires-Dist: websockets==13.1.0; python_version <= "3.8"
40
42
  Provides-Extra: backend
41
43
  Requires-Dist: terminado==0.10.1; extra == "backend"
42
44
  Requires-Dist: tornado; extra == "backend"
@@ -1,4 +1,4 @@
1
- anyscale/__init__.py,sha256=YtAe4ql_2J7SnRMMvJzx1Fdw2ZjtC2VLfZFPSDMdLxA,8595
1
+ anyscale/__init__.py,sha256=ENKr1ipvMdG5mR9YEPCLBKgNGW-cWW5GHE6GRJZ1GqY,8951
2
2
  anyscale/anyscale-cloud-setup-gcp-oa.yaml,sha256=varT3AFGxDy7V8o3_zCwUyoi22MiDmZovfpvkbkyeAU,2715
3
3
  anyscale/anyscale-cloud-setup-gcp.yaml,sha256=b9fKDG8syJuoZJOAr4LZdLGto3sDDil9EOoboXWC9UE,4011
4
4
  anyscale/anyscale-cloud-setup-oa.yaml,sha256=MMfjT2UCNQS43I3mGOMoSq1cq1dufxtnXU9Zy260TK8,3192
@@ -23,19 +23,19 @@ anyscale/integrations.py,sha256=bv8m5rck0Cfxpi59klyYGJhPknpXtnHCSvF1Uu8vTHU,1339
23
23
  anyscale/links.py,sha256=xFXN5TjL61p5T23dn66nNalkV47LNkPJxQqOPhGXfww,193
24
24
  anyscale/memorydb_supported_zones.json,sha256=l5Iup9wFDZcHLfZqH640axxe4UiKteuraZRohi3MwRk,1098
25
25
  anyscale/project_utils.py,sha256=SBwkD5B10ku2kkmp6y-Cr5RL7xf52b9zELP35kfg2PE,17621
26
- anyscale/scripts.py,sha256=2LWIBxPHRhFG8m0La7xJXM2xKOQIG3SvlQobS4op2b0,5624
26
+ anyscale/scripts.py,sha256=d806tM5h0CNUOdu8e_McVmjttiJeX77rQ_R6L8zAT8I,5593
27
27
  anyscale/snapshot.py,sha256=UGJT5C1s_4xmQxjWODK5DFpGxHRBX5jOCdSCqXESH8E,1685
28
28
  anyscale/tables.py,sha256=TV4F2uLnwehvbkAfaP7iuLlT2wLIo6ORH2LVdRGXW5g,2840
29
29
  anyscale/util.py,sha256=14AHIhl4c4hKAW4gLZIvy5w56-zDjcPmrdWqazsvnHU,41860
30
- anyscale/version.py,sha256=Jzc54csSsi_6iMQZJqqcXO-acccbDvRyXCrBatuYXu8,24
30
+ anyscale/version.py,sha256=tfQN72SxYDy_EDQ1uFfglNDm1-8v1NaeHxD6QZGWR4Y,24
31
31
  anyscale/workspace_utils.py,sha256=OViE88CnIF5ruVxd3kazQ0Mf2BxqtMq6wx-XQ5A2cp8,1204
32
32
  anyscale/_private/anyscale_client/README.md,sha256=gk8obk7kqg6VWoUHcqDMwJULh35tYKEZFC0UF_dixGA,718
33
33
  anyscale/_private/anyscale_client/__init__.py,sha256=807Blx3RHQeS8BmKZcsOQQ4dYoKlCnpm6Bdsif2CrHg,337
34
- anyscale/_private/anyscale_client/anyscale_client.py,sha256=Txevk6u-nrJRN0qfNmbq6wVyzzCeVrzCyA4UZRX1gBw,82843
35
- anyscale/_private/anyscale_client/common.py,sha256=rqS9pP2P5m76Ao5Y0Az6aVY-tmrRV_0NzozkGln1ZIQ,25416
36
- anyscale/_private/anyscale_client/fake_anyscale_client.py,sha256=54jDPs2ZkLIP1A-69i-gI6bvEgB5mgYbZav18jxWEzw,57041
34
+ anyscale/_private/anyscale_client/anyscale_client.py,sha256=s9m_xTrVwpcOfhuZnXfu67N5vZ6hAJoB-Mp_wsDqfmI,85335
35
+ anyscale/_private/anyscale_client/common.py,sha256=h-glZioO0NPfT2tqVYP5f4_zvNy5Q0yyj8nawdIbOPU,26617
36
+ anyscale/_private/anyscale_client/fake_anyscale_client.py,sha256=pJGJZMCVeSUUheAe50j5mJwjUeyWqONBtcAbiKtDpjo,57533
37
37
  anyscale/_private/docgen/README.md,sha256=z0tj8Jy0KmxWJBQMHKyzXGX_cYYgI8m5DCD6KCMU8oI,762
38
- anyscale/_private/docgen/__main__.py,sha256=2WUy55vYOhS8NV_sNP76ROeRGATDwOvQLsWHBIrt_Bk,24982
38
+ anyscale/_private/docgen/__main__.py,sha256=cUV0mW8CapfGjcnIzz1FMBN_waZ8TWy_two9WgZcHeQ,25211
39
39
  anyscale/_private/docgen/api.md,sha256=VKW293yubbeUG17A38wYuaONKDL5XICMguyfZ2xkIyY,27495
40
40
  anyscale/_private/docgen/generator.py,sha256=jAOaprAeU659glRDBATAkAQeYC1nDU14jgdobcILS1s,21737
41
41
  anyscale/_private/docgen/generator_legacy.py,sha256=pss_6ONF55XhARrKGcREDmg0J5plWact6USgb5Tr5mM,3002
@@ -712,32 +712,32 @@ anyscale/commands/cloud_commands.py,sha256=E2zWvr4154mG7oBsygiDyLQ-zKAS3RwNB4DEB
712
712
  anyscale/commands/cloud_commands_util.py,sha256=d-6TSZ_syrGkZ3Fc1uRX6jG4dqYMebNkBNpYLojOJFg,247
713
713
  anyscale/commands/cluster_commands.py,sha256=taNcffyFfqJ1MgOQd0cz9kzRXWFTdp-wfLPM4l_2tBc,13487
714
714
  anyscale/commands/cluster_env_commands.py,sha256=KNWylyE8Ew1sDi7yu2Tp4RLcRu2_KJJJIzVGRyPflJo,3899
715
- anyscale/commands/command_examples.py,sha256=NpKuuQBgmZ9sYO6zYHW1EP4Q7dhgk8ES61EmWK8JSNE,26448
715
+ anyscale/commands/command_examples.py,sha256=Oc8Y0lhnfK0c2L24ysJgCbz2VfUEbnEfRbMSIYIDQgQ,26778
716
716
  anyscale/commands/compute_config_commands.py,sha256=vdyrtMcdP8eeK32p_Y6zF-qps6_SyzprhbjRZ9p18tQ,7828
717
717
  anyscale/commands/config_commands.py,sha256=p55uM6WrhfbFoRXC9hNAV-8c5ANghw7tBUYwaQDAtjE,7195
718
718
  anyscale/commands/exec_commands.py,sha256=cMOP1u6xQbl81h69Jug3y73XnNSwpbM6XC1X57SIp4c,465
719
719
  anyscale/commands/experimental_integrations_commands.py,sha256=_e1yESwRGu621Y5MUBqdC3S79YJUdEG1W67b_uQL8wY,2038
720
720
  anyscale/commands/image_commands.py,sha256=hdarnfH5upsgErzs8hJ0CcrWiVu7PxWLKEoD3892lk4,3651
721
721
  anyscale/commands/job_commands.py,sha256=hXEwOSD70JEfNsk-cGYXsMT5pEyxtzdX4YJ8ng-D0_U,25194
722
- anyscale/commands/job_queue_commands.py,sha256=eq80XfHJpajBY9sBfdFqQRiuZfcHJGTYFm7eX_gESUQ,4953
722
+ anyscale/commands/job_queue_commands.py,sha256=FEPzfvD3FO0nbApqh6sZLbEOQoT3EmrkMNBPqeWC4dU,11660
723
723
  anyscale/commands/list_commands.py,sha256=rcDn-Qh3z99zE9oD7RPPa80-y0ml90W4UbGiYMw4aQo,2710
724
- anyscale/commands/list_util.py,sha256=tDKC6jQ7XtOVUe2KfHYkF2yRCbGw2fmAHtdmPgchWv8,3717
724
+ anyscale/commands/list_util.py,sha256=up2f4zGNe6oNOqLr8tYnEpBbSD9pHFLC4cYzi1jDzII,4129
725
725
  anyscale/commands/login_commands.py,sha256=0pIjpRC3Mw86WjDubJ5v2FHINke-Tk3JvGal_aiQMG0,3477
726
726
  anyscale/commands/logs_commands.py,sha256=OgOwBsEbhcGH-STQ9MOJy8sQBYcZYmd31wzHzVPUo0g,9495
727
727
  anyscale/commands/machine_commands.py,sha256=73rgz9aTIOBYcWX8zH-OYlUx3UuhODHtl1RnKtBdU1E,3641
728
- anyscale/commands/machine_pool_commands.py,sha256=ZXcHmKfwX6kHALT86LywI34ADbKKM31uq08R7pcAMoM,9476
728
+ anyscale/commands/machine_pool_commands.py,sha256=mOvcvQkf2IZ46xuNazeY1qHATKm00Z4h9QuVdxWhA2k,9700
729
729
  anyscale/commands/migrate_commands.py,sha256=QL1sVL7KGaOFpL4sVNUM96I4kOEzYmIXFuG90LRJ9Uw,3258
730
730
  anyscale/commands/organization_invitation_commands.py,sha256=L0OEz_mF5Dm02KjVzDu_CRKlLm4-c2w8HcHqEvP2nIs,2723
731
731
  anyscale/commands/project_commands.py,sha256=xVm-W5kKzgfbQjAiHSRhnyMIlYgGji1TUfYAi8QrGBo,7131
732
732
  anyscale/commands/resource_quota_commands.py,sha256=J6r8b6Bo1wMys5pYWieD6F-VsC2OpQZGVLaNFlvAKmI,8536
733
733
  anyscale/commands/schedule_commands.py,sha256=mdwelVght3HnN5YPjtG4Spn0KiEDWmg-UosfaDkQPKE,14485
734
734
  anyscale/commands/service_account_commands.py,sha256=u45N2akHsZxyu5LK03FGEEnZh4dTt4B2Be-dXgbSg3U,3977
735
- anyscale/commands/service_commands.py,sha256=FXnrJ-IRV6pUVGYFaSrTWfS1R9VXj8zVtmJbtGkfNPE,33884
735
+ anyscale/commands/service_commands.py,sha256=lq_FuS9YWvPJkzH641DBLFISMIi1EwVVwc5kTqOftvo,33660
736
736
  anyscale/commands/session_commands_hidden.py,sha256=APEypnUB1yV2Rr6wdSFWy1vQbAnn-lOn0rU2enF5JdM,6200
737
737
  anyscale/commands/user_commands.py,sha256=C-i1dGpdhboywN_2XgPS2BekKx2y6LZq8c8gvS0S-tY,1259
738
738
  anyscale/commands/util.py,sha256=N8gkVv9LBr5QypBGm2e_Pw2F2e_tiiR4YNLmn8CtsK0,5124
739
739
  anyscale/commands/workspace_commands.py,sha256=RjK8rPlIPoReZBb7RPB6z9aFp7gSmnsxDge8d3uj9t8,15768
740
- anyscale/commands/workspace_commands_v2.py,sha256=9pNJXrerZ7BveZBjZ_h0Q0232IwuNwpcKd7TJM3zrEE,28045
740
+ anyscale/commands/workspace_commands_v2.py,sha256=D6YmcjD7Db7KK6adaGxiyiIdlCzMa4Y1v_xVT_cWmmI,43582
741
741
  anyscale/commands/anyscale_api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
742
742
  anyscale/commands/anyscale_api/api_commands.py,sha256=Dze2wuzeZurlbxOu4YHZqln026yXgtWi_jxccyKANmw,473
743
743
  anyscale/commands/anyscale_api/session_operations_commands.py,sha256=LiavgWn2-F7b3GZD0ng_Q1HiEP4o32e8nO9yU92AgxI,803
@@ -763,7 +763,7 @@ anyscale/controllers/cluster_env_controller.py,sha256=JalGzcmnFtMHefYL5U6ijMY3nX
763
763
  anyscale/controllers/compute_config_controller.py,sha256=GnZAJGrPAmGO6MWvqna-0-DBlwC1y8fnKgwsDVa0eDs,14110
764
764
  anyscale/controllers/config_controller.py,sha256=VsfdARHxo4tMLfeiYkTNOMGW3sIcNhVqYi37-SruKnk,17125
765
765
  anyscale/controllers/experimental_integrations_controller.py,sha256=_22_hAQCJIMg3E10s8xajoFF6Lf1HqVlAdAVt0Rh2DY,3889
766
- anyscale/controllers/job_controller.py,sha256=Ef04X790FiohE-n3_n8crJv2zZbTfF6qrTP1q9_3wA0,32050
766
+ anyscale/controllers/job_controller.py,sha256=sNQGzSLtp6e8PSbrmMrW_dp3pYytS8KCGcE-YjaNz5I,25425
767
767
  anyscale/controllers/jobs_bg_controller.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
768
768
  anyscale/controllers/list_controller.py,sha256=oaOS6oo2TKPpXhGjs_laxuIVKinv3FwYfHt1CIzeTuU,11621
769
769
  anyscale/controllers/logs_controller.py,sha256=x5GBUVdPYhbWRA3RfMQZJi3hBS2i35RkgzROfmY47h4,17647
@@ -786,6 +786,10 @@ anyscale/job/__init__.py,sha256=_5Nb3a11F4oAHXirTgx5vDdgpVzJ62FdGFmADxxvcPE,5051
786
786
  anyscale/job/commands.py,sha256=je0WDrd3mxt3iuoGqKvE_2TuMWsffXXM_IQ5SRjUKnU,8524
787
787
  anyscale/job/models.py,sha256=w2qqm69ccCf9Y6Hwe5cLszqn3asS19s24t4akuZPsUM,17922
788
788
  anyscale/job/_private/job_sdk.py,sha256=6kQ5bDggA3f1MXcrlXAGrFRA7WAOcvKDVi8FXwq7z-E,18871
789
+ anyscale/job_queue/__init__.py,sha256=4KhAj-JkzqJdz1AbUoO8sQ4weWISBYaMPe6uRj7-5SA,3194
790
+ anyscale/job_queue/commands.py,sha256=pVgX6MG15zlUFgz6lUvAFqTSYY7gAZ5cFmDJY3QRTx0,3948
791
+ anyscale/job_queue/models.py,sha256=gl98WWvvdUlCWaSpLyUHggzNmUr49ti39itB37mznM0,10538
792
+ anyscale/job_queue/_private/job_queue_sdk.py,sha256=2ytSoTjDQWaWf4iRWtBlaaPsHpajGg_lBL7qbiOmAVc,5992
789
793
  anyscale/llm/__init__.py,sha256=lRp09PWR2gcJF_1Y9ieIIQWirijP5p_l3AQkTir2iN4,76
790
794
  anyscale/llm/sdk.py,sha256=VmA03eegizqikWR3eH2jYNiA8-FY3Qq1GGtvdkgU470,733
791
795
  anyscale/llm/dataset/__init__.py,sha256=J-z8d7Bdvjf_5OOjcHrFQrXnCxbdcvzUBcyapawIuHg,131
@@ -1042,6 +1046,7 @@ anyscale/utils/ray_version_checker.py,sha256=IiBJzBFJpOs4or0FeuaXKRysbCaFzCEoO_D
1042
1046
  anyscale/utils/ray_version_utils.py,sha256=DhrkyJAB7M-61QA73RkuVwXk3FfApFH3vShGSbcdsck,1932
1043
1047
  anyscale/utils/runtime_env.py,sha256=WDHQXJYFZM9__RvuT6Fq66fWgtMENGP3umz3zLqHczU,18592
1044
1048
  anyscale/utils/s3.py,sha256=cxlR5baJIGaEFRUmND_i66Nh9TA7N0AGgcq8MdLZBdU,3427
1049
+ anyscale/utils/ssh_websocket_proxy.py,sha256=AHDzFk6G8x4envhWs1IAYjv08VZIMieug7e-1n8-xhw,6805
1045
1050
  anyscale/utils/user_utils.py,sha256=wM0npdWAfaahRMUI26jz8tm3oQsqpk7A1QEyygOtt-M,573
1046
1051
  anyscale/utils/workload_types.py,sha256=kKAaKDh5bd6zA2f1HR0VMlkhu9nAIeUMM-NMIGP0ZR4,128
1047
1052
  anyscale/utils/workspace_notification.py,sha256=3utuEVFj7iHAXTHXDWedPcycIV3b0bpdQtAWz2n2GPI,1129
@@ -1058,10 +1063,10 @@ anyscale/workspace/__init__.py,sha256=Innbm5ZhCyADEVBiYSo_vbpKwUNcMzVSAfxIGKOYe6
1058
1063
  anyscale/workspace/commands.py,sha256=b1sqNseoPj-1VXznqQOLe0V_a663bOTvJX-TaOMJa1Y,14590
1059
1064
  anyscale/workspace/models.py,sha256=HBvM9ybOdJjqQeViQ30C36gdKT_AwH_JHPoL-DTkESo,9841
1060
1065
  anyscale/workspace/_private/workspace_sdk.py,sha256=2CMeYfJt0UtIFCocDn1ukw1iI5esKHdopLe6duEs-qE,27599
1061
- anyscale-0.26.29.dist-info/LICENSE,sha256=UOPu974Wzsna6frFv1mu4VrZgNdZT7lbcNPzo5ue3qs,3494
1062
- anyscale-0.26.29.dist-info/METADATA,sha256=9Sq3afeWWPoHWCLUFxgclZIQ_hbtcUOKc7QG8YQSdnA,3160
1063
- anyscale-0.26.29.dist-info/NOTICE,sha256=gHqDhSnUYlRXX-mDOL5FtE7774oiKyV_HO80qM3r9Xo,196
1064
- anyscale-0.26.29.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
1065
- anyscale-0.26.29.dist-info/entry_points.txt,sha256=NqO18sCZn6zG6J0S38itjcN00s7aE3C3v3k5lMAfCLk,51
1066
- anyscale-0.26.29.dist-info/top_level.txt,sha256=g3NVNS8Oh0NZwbFFgeX696C5MZZkS5dqV2NqcsbDRJE,9
1067
- anyscale-0.26.29.dist-info/RECORD,,
1066
+ anyscale-0.26.30.dist-info/LICENSE,sha256=UOPu974Wzsna6frFv1mu4VrZgNdZT7lbcNPzo5ue3qs,3494
1067
+ anyscale-0.26.30.dist-info/METADATA,sha256=h5NOjd0pDVHlNOcaFFcdJgKeuIR47gCQmEmEgUUTz-M,3269
1068
+ anyscale-0.26.30.dist-info/NOTICE,sha256=gHqDhSnUYlRXX-mDOL5FtE7774oiKyV_HO80qM3r9Xo,196
1069
+ anyscale-0.26.30.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
1070
+ anyscale-0.26.30.dist-info/entry_points.txt,sha256=NqO18sCZn6zG6J0S38itjcN00s7aE3C3v3k5lMAfCLk,51
1071
+ anyscale-0.26.30.dist-info/top_level.txt,sha256=g3NVNS8Oh0NZwbFFgeX696C5MZZkS5dqV2NqcsbDRJE,9
1072
+ anyscale-0.26.30.dist-info/RECORD,,