anyscale 0.26.66__py3-none-any.whl → 0.26.67__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.
@@ -4235,6 +4235,7 @@ class CloudController(BaseController):
4235
4235
  " --set-string workloadServiceAccountName=anyscale-operator",
4236
4236
  " --namespace <namespace>",
4237
4237
  " --create-namespace",
4238
+ " --wait",
4238
4239
  " -i",
4239
4240
  ]
4240
4241
  )
@@ -1519,6 +1519,14 @@ class KubernetesCloudDeploymentVerifier:
1519
1519
 
1520
1520
  def _get_kubectl_config(self):
1521
1521
  """Get kubectl context and operator namespace from user"""
1522
+ # If k8s_config is already set, skip prompting
1523
+ if self.k8s_config is not None:
1524
+ self.log.info(
1525
+ f"Using configured context='{self.k8s_config.context}', "
1526
+ f"namespace='{self.k8s_config.operator_namespace}'"
1527
+ )
1528
+ return
1529
+
1522
1530
  # Check if kubectl is available
1523
1531
  temp_kubectl = KubectlOperations("", self.log)
1524
1532
  if not temp_kubectl.check_kubectl_available():
@@ -0,0 +1,364 @@
1
+ """
2
+ CloudFormation utility functions for creating and managing stacks.
3
+
4
+ This module provides reusable utilities for CloudFormation stack operations
5
+ including creation, waiting, and output retrieval.
6
+ """
7
+
8
+ import time
9
+ from typing import Any, Dict, Optional
10
+
11
+ import boto3
12
+ from botocore.exceptions import ClientError
13
+ from click import ClickException
14
+
15
+ from anyscale.cli_logger import BlockLogger
16
+
17
+
18
+ class CloudFormationUtils:
19
+ """Utility class for CloudFormation operations."""
20
+
21
+ def __init__(self, logger: Optional[BlockLogger] = None):
22
+ self.log = logger or BlockLogger()
23
+
24
+ def create_and_wait_for_stack( # noqa: PLR0913
25
+ self,
26
+ stack_name: str,
27
+ template_body: str,
28
+ parameters: list,
29
+ region: str,
30
+ capabilities: Optional[list] = None,
31
+ timeout_seconds: int = 600,
32
+ boto3_session: Optional[boto3.Session] = None,
33
+ update_if_exists: bool = False,
34
+ ) -> Dict[str, Any]:
35
+ """
36
+ Create a CloudFormation stack and wait for it to complete.
37
+
38
+ Args:
39
+ stack_name: Name of the CloudFormation stack
40
+ template_body: CloudFormation template body
41
+ parameters: Stack parameters
42
+ region: AWS region
43
+ capabilities: Stack capabilities (default: CAPABILITY_NAMED_IAM, CAPABILITY_AUTO_EXPAND)
44
+ timeout_seconds: Timeout in seconds (default: 600)
45
+ boto3_session: Optional boto3 session (creates new if not provided)
46
+ update_if_exists: Whether to update stack if it already exists (default: False)
47
+
48
+ Returns:
49
+ CloudFormation stack information
50
+
51
+ Raises:
52
+ ClickException: If stack creation fails or times out
53
+ """
54
+ if boto3_session is None:
55
+ boto3_session = boto3.Session(region_name=region)
56
+
57
+ cfn_client = boto3_session.client("cloudformation", region_name=region)
58
+
59
+ if capabilities is None:
60
+ capabilities = ["CAPABILITY_NAMED_IAM", "CAPABILITY_AUTO_EXPAND"]
61
+
62
+ # Create the stack
63
+ self.log.info(f"Creating CloudFormation stack: {stack_name}")
64
+ try:
65
+ cfn_client.create_stack(
66
+ StackName=stack_name,
67
+ TemplateBody=template_body,
68
+ Parameters=parameters,
69
+ Capabilities=capabilities,
70
+ )
71
+ except ClientError as e:
72
+ error_code = e.response.get("Error", {}).get("Code", "")
73
+ if error_code == "AlreadyExistsException" and update_if_exists:
74
+ self.log.warning(f"Stack {stack_name} already exists, updating...")
75
+ try:
76
+ cfn_client.update_stack(
77
+ StackName=stack_name,
78
+ TemplateBody=template_body,
79
+ Parameters=parameters,
80
+ Capabilities=capabilities,
81
+ )
82
+ except ClientError as update_error:
83
+ raise ClickException(
84
+ f"Failed to update existing stack: {update_error}"
85
+ )
86
+ else:
87
+ raise ClickException(f"Failed to create CloudFormation stack: {e}")
88
+
89
+ # Wait for stack completion
90
+ return self._wait_for_stack_completion(
91
+ cfn_client, stack_name, region, timeout_seconds
92
+ )
93
+
94
+ def _wait_for_stack_completion(
95
+ self, cfn_client, stack_name: str, region: str, timeout_seconds: int
96
+ ) -> Dict[str, Any]:
97
+ """Wait for CloudFormation stack to complete with timeout."""
98
+ stack_url = f"https://{region}.console.aws.amazon.com/cloudformation/home?region={region}#/stacks/stackinfo?stackId={stack_name}"
99
+ self.log.info(f"Track progress at: {stack_url}")
100
+
101
+ with self.log.spinner("Creating cloud resources through CloudFormation..."):
102
+ start_time = time.time()
103
+ end_time = start_time + timeout_seconds
104
+
105
+ while time.time() < end_time:
106
+ try:
107
+ stacks = cfn_client.describe_stacks(StackName=stack_name)
108
+ cfn_stack = stacks["Stacks"][0]
109
+ stack_status = cfn_stack["StackStatus"]
110
+
111
+ if stack_status in (
112
+ "CREATE_FAILED",
113
+ "ROLLBACK_COMPLETE",
114
+ "ROLLBACK_IN_PROGRESS",
115
+ "UPDATE_FAILED",
116
+ ):
117
+ # Clean up resources if stack failed
118
+ self._cleanup_failed_stack(cfn_client, stack_name, region)
119
+
120
+ # Get error details
121
+ error_details = self._get_stack_error_details(
122
+ cfn_client, stack_name
123
+ )
124
+ raise ClickException(
125
+ f"CloudFormation stack failed: {stack_status}. "
126
+ f"Error details: {error_details}. "
127
+ f"Check the stack at: {stack_url}"
128
+ )
129
+
130
+ if stack_status in ("CREATE_COMPLETE", "UPDATE_COMPLETE"):
131
+ self.log.info(
132
+ f"CloudFormation stack {stack_name} completed successfully"
133
+ )
134
+ return cfn_stack
135
+
136
+ # Still in progress
137
+ time.sleep(5)
138
+
139
+ except ClientError as e:
140
+ if "does not exist" in str(e):
141
+ raise ClickException(
142
+ f"CloudFormation stack {stack_name} not found"
143
+ )
144
+ raise ClickException(f"Error checking CloudFormation stack: {e}")
145
+
146
+ # Timeout
147
+ raise ClickException(
148
+ f"CloudFormation stack {stack_name} timed out after {timeout_seconds} seconds. "
149
+ f"Check the stack at: {stack_url}"
150
+ )
151
+
152
+ def _cleanup_failed_stack(self, cfn_client, stack_name: str, region: str) -> None:
153
+ """Clean up resources from a failed CloudFormation stack."""
154
+ try:
155
+ # Try to get stack outputs to find resources to clean up
156
+ stacks = cfn_client.describe_stacks(StackName=stack_name)
157
+ stack = stacks["Stacks"][0]
158
+
159
+ # Look for S3 bucket in outputs
160
+ for output in stack.get("Outputs", []):
161
+ if "Bucket" in output.get("OutputKey", ""):
162
+ bucket_name = output.get("OutputValue")
163
+ if bucket_name:
164
+ self._cleanup_s3_bucket(bucket_name, region)
165
+
166
+ except Exception as e: # noqa: BLE001
167
+ self.log.warning(f"Failed to cleanup resources from failed stack: {e}")
168
+
169
+ def _cleanup_s3_bucket(self, bucket_name: str, region: str) -> None:
170
+ """Clean up S3 bucket created by failed stack."""
171
+ try:
172
+ s3_client = boto3.client("s3", region_name=region)
173
+ s3_client.delete_bucket(Bucket=bucket_name)
174
+ self.log.info(f"Successfully deleted S3 bucket: {bucket_name}")
175
+ except ClientError as e:
176
+ if e.response["Error"]["Code"] != "NoSuchBucket":
177
+ self.log.error(f"Failed to delete S3 bucket {bucket_name}: {e}")
178
+ except Exception as e: # noqa: BLE001
179
+ self.log.error(f"Failed to delete S3 bucket {bucket_name}: {e}")
180
+
181
+ def _get_stack_error_details(self, cfn_client, stack_name: str) -> str:
182
+ """Get detailed error information from CloudFormation stack events."""
183
+ try:
184
+ events = cfn_client.describe_stack_events(StackName=stack_name)
185
+ error_events = [
186
+ event
187
+ for event in events.get("StackEvents", [])
188
+ if event.get("ResourceStatus", "").endswith("_FAILED")
189
+ ]
190
+
191
+ if error_events:
192
+ latest_error = error_events[0]
193
+ return (
194
+ f"Resource: {latest_error.get('LogicalResourceId', 'Unknown')}, "
195
+ f"Status: {latest_error.get('ResourceStatus', 'Unknown')}, "
196
+ f"Reason: {latest_error.get('ResourceStatusReason', 'Unknown')}"
197
+ )
198
+ else:
199
+ return "No detailed error information available"
200
+
201
+ except Exception as e: # noqa: BLE001
202
+ return f"Failed to get error details: {e}"
203
+
204
+ def get_stack_outputs(
205
+ self,
206
+ stack_name: str,
207
+ region: str,
208
+ boto3_session: Optional[boto3.Session] = None,
209
+ ) -> Dict[str, str]:
210
+ """
211
+ Get all outputs from a CloudFormation stack.
212
+
213
+ Args:
214
+ stack_name: Name of the CloudFormation stack
215
+ region: AWS region
216
+ boto3_session: Optional boto3 session (creates new if not provided)
217
+
218
+ Returns:
219
+ Dictionary of output key-value pairs
220
+
221
+ Raises:
222
+ ClickException: If stack not found or error retrieving outputs
223
+ """
224
+ if boto3_session is None:
225
+ boto3_session = boto3.Session(region_name=region)
226
+
227
+ cfn_client = boto3_session.client("cloudformation", region_name=region)
228
+
229
+ try:
230
+ stacks = cfn_client.describe_stacks(StackName=stack_name)
231
+ stack = stacks["Stacks"][0]
232
+ outputs = {}
233
+
234
+ for output in stack.get("Outputs", []):
235
+ outputs[output["OutputKey"]] = output["OutputValue"]
236
+
237
+ return outputs
238
+ except ClientError as e:
239
+ if "does not exist" in str(e):
240
+ raise ClickException(f"CloudFormation stack {stack_name} not found")
241
+ raise ClickException(f"Failed to get CloudFormation outputs: {e}")
242
+
243
+ def get_stack_output(
244
+ self,
245
+ stack_name: str,
246
+ output_key: str,
247
+ region: str,
248
+ boto3_session: Optional[boto3.Session] = None,
249
+ ) -> str:
250
+ """
251
+ Get a specific output value from a CloudFormation stack.
252
+
253
+ Args:
254
+ stack_name: Name of the CloudFormation stack
255
+ output_key: Key of the output to retrieve
256
+ region: AWS region
257
+ boto3_session: Optional boto3 session (creates new if not provided)
258
+
259
+ Returns:
260
+ Output value
261
+
262
+ Raises:
263
+ ClickException: If stack not found or output key not found
264
+ """
265
+ outputs = self.get_stack_outputs(stack_name, region, boto3_session)
266
+
267
+ if output_key not in outputs:
268
+ available_keys = list(outputs.keys())
269
+ raise ClickException(
270
+ f"Output key '{output_key}' not found in stack {stack_name}. "
271
+ f"Available keys: {available_keys}"
272
+ )
273
+
274
+ return outputs[output_key]
275
+
276
+ def delete_stack(
277
+ self,
278
+ stack_name: str,
279
+ region: str,
280
+ boto3_session: Optional[boto3.Session] = None,
281
+ ) -> None:
282
+ """
283
+ Delete a CloudFormation stack.
284
+
285
+ Args:
286
+ stack_name: Name of the CloudFormation stack
287
+ region: AWS region
288
+ boto3_session: Optional boto3 session (creates new if not provided)
289
+
290
+ Raises:
291
+ ClickException: If stack deletion fails
292
+ """
293
+ if boto3_session is None:
294
+ boto3_session = boto3.Session(region_name=region)
295
+
296
+ cfn_client = boto3_session.client("cloudformation", region_name=region)
297
+
298
+ try:
299
+ self.log.info(f"Deleting CloudFormation stack: {stack_name}")
300
+ cfn_client.delete_stack(StackName=stack_name)
301
+
302
+ # Wait for deletion to complete
303
+ with self.log.spinner("Deleting CloudFormation stack..."):
304
+ start_time = time.time()
305
+ timeout_seconds = 300 # 5 minutes for deletion
306
+ end_time = start_time + timeout_seconds
307
+
308
+ while time.time() < end_time:
309
+ try:
310
+ cfn_client.describe_stacks(StackName=stack_name)
311
+ time.sleep(5) # Still exists, wait
312
+ except ClientError as e:
313
+ if "does not exist" in str(e):
314
+ self.log.info(
315
+ f"CloudFormation stack {stack_name} deleted successfully"
316
+ )
317
+ return
318
+ raise ClickException(f"Error checking stack deletion: {e}")
319
+
320
+ raise ClickException(
321
+ f"Stack deletion timed out after {timeout_seconds} seconds"
322
+ )
323
+
324
+ except ClientError as e:
325
+ if "does not exist" in str(e):
326
+ self.log.info(f"Stack {stack_name} does not exist")
327
+ return
328
+ raise ClickException(f"Failed to delete CloudFormation stack: {e}")
329
+
330
+
331
+ # Convenience functions for backward compatibility
332
+ def create_cloudformation_stack(
333
+ stack_name: str,
334
+ template_body: str,
335
+ parameters: list,
336
+ region: str,
337
+ logger: Optional[BlockLogger] = None,
338
+ **kwargs,
339
+ ) -> Dict[str, Any]:
340
+ """Convenience function to create a CloudFormation stack."""
341
+ utils = CloudFormationUtils(logger)
342
+ return utils.create_and_wait_for_stack(
343
+ stack_name, template_body, parameters, region, **kwargs
344
+ )
345
+
346
+
347
+ def get_cloudformation_outputs(
348
+ stack_name: str, region: str, logger: Optional[BlockLogger] = None, **kwargs
349
+ ) -> Dict[str, str]:
350
+ """Convenience function to get CloudFormation stack outputs."""
351
+ utils = CloudFormationUtils(logger)
352
+ return utils.get_stack_outputs(stack_name, region, **kwargs)
353
+
354
+
355
+ def get_cloudformation_output(
356
+ stack_name: str,
357
+ output_key: str,
358
+ region: str,
359
+ logger: Optional[BlockLogger] = None,
360
+ **kwargs,
361
+ ) -> str:
362
+ """Convenience function to get a specific CloudFormation stack output."""
363
+ utils = CloudFormationUtils(logger)
364
+ return utils.get_stack_output(stack_name, output_key, region, **kwargs)
anyscale/version.py CHANGED
@@ -1 +1 @@
1
- __version__ = "0.26.66"
1
+ __version__ = "0.26.67"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: anyscale
3
- Version: 0.26.66
3
+ Version: 0.26.67
4
4
  Summary: Command Line Interface for Anyscale
5
5
  Author: Anyscale Inc.
6
6
  License: AS License
@@ -28,7 +28,7 @@ anyscale/snapshot.py,sha256=UGJT5C1s_4xmQxjWODK5DFpGxHRBX5jOCdSCqXESH8E,1685
28
28
  anyscale/tables.py,sha256=TV4F2uLnwehvbkAfaP7iuLlT2wLIo6ORH2LVdRGXW5g,2840
29
29
  anyscale/telemetry.py,sha256=U90C2Vgx48z9PMTI6EbzHFbP3jWnDUutbIfMPBb8-SI,14711
30
30
  anyscale/util.py,sha256=3jfGH2CyDmXrSg-3owSF7F8FnqKbLJ-aHUbepyCKuqQ,42903
31
- anyscale/version.py,sha256=zj93ulo-laQiiTnH5BhCREtuFiM0mXZERQJbP5vaSNk,24
31
+ anyscale/version.py,sha256=4mkZX01-EDXdRnvNIK0wtKyNwhcnPvBpwO-aAxb3rCk,24
32
32
  anyscale/workspace_utils.py,sha256=OViE88CnIF5ruVxd3kazQ0Mf2BxqtMq6wx-XQ5A2cp8,1204
33
33
  anyscale/_private/anyscale_client/README.md,sha256=kSfI2Jfw5RHZWYtu0di3XtdSCx0d2pSwKMfjmDvw7Tg,3770
34
34
  anyscale/_private/anyscale_client/__init__.py,sha256=807Blx3RHQeS8BmKZcsOQQ4dYoKlCnpm6Bdsif2CrHg,337
@@ -834,7 +834,7 @@ anyscale/cloud/_private/cloud_sdk.py,sha256=5TBGyGSjMI4jLOnSle1WWC6za0psP9xgTGWU
834
834
  anyscale/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
835
835
  anyscale/commands/aggregated_instance_usage_commands.py,sha256=TRP1X3hdIWbKg9V20VtazlDXsYAeV--M0DH3-Z5tnj4,2293
836
836
  anyscale/commands/auth_commands.py,sha256=X1g6Yu9kqgPb4HLODlZTYEk8G5AVLeyizPIgagWx-p0,1026
837
- anyscale/commands/cloud_commands.py,sha256=iNuDD8LoJe4y12bZpCDiYCs2YNxRC1rkLuzmgt7Rj_k,58604
837
+ anyscale/commands/cloud_commands.py,sha256=NdB4O_Nee-ute0lXWs7xIotdoVuoyHUvBbYXueODFGk,60185
838
838
  anyscale/commands/cluster_commands.py,sha256=taNcffyFfqJ1MgOQd0cz9kzRXWFTdp-wfLPM4l_2tBc,13487
839
839
  anyscale/commands/cluster_env_commands.py,sha256=KNWylyE8Ew1sDi7yu2Tp4RLcRu2_KJJJIzVGRyPflJo,3899
840
840
  anyscale/commands/command_examples.py,sha256=pSj1DyHwlzmSxw-Ko5RUTQ57uFA7v7Jgur0s7K55bts,25182
@@ -859,6 +859,7 @@ anyscale/commands/schedule_commands.py,sha256=Bw2aKp_w6xcuRSVVi9FLdUjRVCr8_v4Tt2
859
859
  anyscale/commands/service_account_commands.py,sha256=JlppTmcaDofJn7TYqd3PW4hDGykdEN56fr0PT3qgBIg,3271
860
860
  anyscale/commands/service_commands.py,sha256=DBrPkW7JH3kCsr038aQStm7AF1u-n80sLjwc2Hjifks,34014
861
861
  anyscale/commands/session_commands_hidden.py,sha256=APEypnUB1yV2Rr6wdSFWy1vQbAnn-lOn0rU2enF5JdM,6200
862
+ anyscale/commands/setup_k8s.py,sha256=__Z7p8mISxK2AntvrUUzQ5RRQVnnPQJmu8vejY8x0wU,40821
862
863
  anyscale/commands/user_commands.py,sha256=C-i1dGpdhboywN_2XgPS2BekKx2y6LZq8c8gvS0S-tY,1259
863
864
  anyscale/commands/util.py,sha256=fIob29G1jZ4VU9PKVSJnT6hqX7wAqsS4L9sApsMZcNs,8585
864
865
  anyscale/commands/workspace_commands.py,sha256=5JoF5xftkwkxHidp8xyj9POrlZE_WxwSKtZGnKCbDV4,18597
@@ -878,7 +879,7 @@ anyscale/connect_utils/start_interactive_session.py,sha256=m-RCH0e_bQBF6dAOskbP9
878
879
  anyscale/controllers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
879
880
  anyscale/controllers/auth_controller.py,sha256=hDY2sPvUP8pvh8PnlDYH5rCHjQes2v3b_KBVjMbrzeE,5127
880
881
  anyscale/controllers/base_controller.py,sha256=1QFJoScFUV7YTzpKarhwPOc1SvI-xqX3TZmwxKonW6I,1998
881
- anyscale/controllers/cloud_controller.py,sha256=PYugEBT2UV0_pPYI6FCn7J6QI2F_LW5LxliIHK1ta3o,201971
882
+ anyscale/controllers/cloud_controller.py,sha256=r1jDAKG-rZmKVDCqR2SuLpZcl8lXanI-Ij7BOqLDCys,201999
882
883
  anyscale/controllers/cloud_file_storage_utils.py,sha256=ifaqClEybTgxhqGWHYoH1vrlbxwjRuO-De_3666R2O4,6987
883
884
  anyscale/controllers/cloud_functional_verification_controller.py,sha256=uro10r981CTlt2zlisUCmNYljbrYBiWzh7vrqrcur3I,33475
884
885
  anyscale/controllers/cluster_controller.py,sha256=Sb5wVjrjpycg5iqmENAVtZ4iy9Kr6kM97_ck-KH85LM,28745
@@ -888,7 +889,7 @@ anyscale/controllers/config_controller.py,sha256=VsfdARHxo4tMLfeiYkTNOMGW3sIcNhV
888
889
  anyscale/controllers/experimental_integrations_controller.py,sha256=_22_hAQCJIMg3E10s8xajoFF6Lf1HqVlAdAVt0Rh2DY,3889
889
890
  anyscale/controllers/job_controller.py,sha256=sNQGzSLtp6e8PSbrmMrW_dp3pYytS8KCGcE-YjaNz5I,25425
890
891
  anyscale/controllers/jobs_bg_controller.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
891
- anyscale/controllers/kubernetes_verifier.py,sha256=rs7aNepuy4wZgteAtJOqGM9HwA0cH_ndrOAp_LpqPeY,58724
892
+ anyscale/controllers/kubernetes_verifier.py,sha256=BGqq65wsF9YfFJva7HJ8DhHoubkoGskEyX_0cRVBOLc,59022
892
893
  anyscale/controllers/list_controller.py,sha256=oaOS6oo2TKPpXhGjs_laxuIVKinv3FwYfHt1CIzeTuU,11621
893
894
  anyscale/controllers/logs_controller.py,sha256=x5GBUVdPYhbWRA3RfMQZJi3hBS2i35RkgzROfmY47h4,17647
894
895
  anyscale/controllers/machine_controller.py,sha256=WauNi7Spzt2TFZrIN4PwULzgJZBVDFlytzFqpDQ106w,1188
@@ -1140,6 +1141,7 @@ anyscale/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1140
1141
  anyscale/utils/cli_version_check_util.py,sha256=U2KU-NRf09pcs-ZZYUm1GQxs7Btp6N4Fv6CQeNoEeTM,2223
1141
1142
  anyscale/utils/cloud_update_utils.py,sha256=c53AQyg4OJBkNqTD-8hHvEpdTwtins1rTycifBbQbWI,34106
1142
1143
  anyscale/utils/cloud_utils.py,sha256=DtUkaIvKeX64Scia62fjnK61_gNMJr_H2e73C-ywF7k,12228
1144
+ anyscale/utils/cloudformation_utils.py,sha256=G4QJbnwve8ZQu7qzrT7ZVZ32zqf_bDxBDZBNZEtFkZg,13839
1143
1145
  anyscale/utils/cluster_debug.py,sha256=P_-20L4Rt4LVAIGX-y9F61z5XYO5QbNtqf2MYJxuy_g,6391
1144
1146
  anyscale/utils/connect_helpers.py,sha256=hlTKnaL27pABWPoW5nA5dpJW2ZG_2k7dXjnqtdzoBjo,5956
1145
1147
  anyscale/utils/deprecation_util.py,sha256=2i1SNQIziOZXO24IuBZZUEi4ild1bqk0gfZWl2KgpXw,1160
@@ -1172,10 +1174,10 @@ anyscale/workspace/__init__.py,sha256=Innbm5ZhCyADEVBiYSo_vbpKwUNcMzVSAfxIGKOYe6
1172
1174
  anyscale/workspace/commands.py,sha256=b1sqNseoPj-1VXznqQOLe0V_a663bOTvJX-TaOMJa1Y,14590
1173
1175
  anyscale/workspace/models.py,sha256=uiMqoJRQNRgTcOIIsysSrtlHMtnI7paUWS34EN626Cg,10016
1174
1176
  anyscale/workspace/_private/workspace_sdk.py,sha256=2CMeYfJt0UtIFCocDn1ukw1iI5esKHdopLe6duEs-qE,27599
1175
- anyscale-0.26.66.dist-info/licenses/LICENSE,sha256=UOPu974Wzsna6frFv1mu4VrZgNdZT7lbcNPzo5ue3qs,3494
1176
- anyscale-0.26.66.dist-info/licenses/NOTICE,sha256=gHqDhSnUYlRXX-mDOL5FtE7774oiKyV_HO80qM3r9Xo,196
1177
- anyscale-0.26.66.dist-info/METADATA,sha256=hPPRjsbemUyxKUKtECR6o5sQmIknnbRGC0YLVhdrfoU,3231
1178
- anyscale-0.26.66.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
1179
- anyscale-0.26.66.dist-info/entry_points.txt,sha256=NqO18sCZn6zG6J0S38itjcN00s7aE3C3v3k5lMAfCLk,51
1180
- anyscale-0.26.66.dist-info/top_level.txt,sha256=g3NVNS8Oh0NZwbFFgeX696C5MZZkS5dqV2NqcsbDRJE,9
1181
- anyscale-0.26.66.dist-info/RECORD,,
1177
+ anyscale-0.26.67.dist-info/licenses/LICENSE,sha256=UOPu974Wzsna6frFv1mu4VrZgNdZT7lbcNPzo5ue3qs,3494
1178
+ anyscale-0.26.67.dist-info/licenses/NOTICE,sha256=gHqDhSnUYlRXX-mDOL5FtE7774oiKyV_HO80qM3r9Xo,196
1179
+ anyscale-0.26.67.dist-info/METADATA,sha256=v2m-ZcONwTUVJvL4Mr3fsNVacBDKtjHY6mgJX-ppWEw,3231
1180
+ anyscale-0.26.67.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
1181
+ anyscale-0.26.67.dist-info/entry_points.txt,sha256=NqO18sCZn6zG6J0S38itjcN00s7aE3C3v3k5lMAfCLk,51
1182
+ anyscale-0.26.67.dist-info/top_level.txt,sha256=g3NVNS8Oh0NZwbFFgeX696C5MZZkS5dqV2NqcsbDRJE,9
1183
+ anyscale-0.26.67.dist-info/RECORD,,