skypilot-nightly 1.0.0.dev20250902__py3-none-any.whl → 1.0.0.dev20250903__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.

Potentially problematic release.


This version of skypilot-nightly might be problematic. Click here for more details.

Files changed (59) hide show
  1. sky/__init__.py +2 -2
  2. sky/adaptors/runpod.py +68 -0
  3. sky/backends/backend_utils.py +5 -3
  4. sky/client/cli/command.py +20 -5
  5. sky/clouds/kubernetes.py +1 -1
  6. sky/clouds/runpod.py +17 -0
  7. sky/dashboard/out/404.html +1 -1
  8. sky/dashboard/out/_next/static/chunks/1121-ec35954c8cbea535.js +1 -0
  9. sky/dashboard/out/_next/static/chunks/pages/clusters/[cluster]/[job]-b77360a343d48902.js +16 -0
  10. sky/dashboard/out/_next/static/chunks/{webpack-0eaa6f7e63f51311.js → webpack-60556df644cd5d71.js} +1 -1
  11. sky/dashboard/out/_next/static/{tio0QibqY2C0F2-rPy00p → yLz6EPhW_XXmnNs1I6dmS}/_buildManifest.js +1 -1
  12. sky/dashboard/out/clusters/[cluster]/[job].html +1 -1
  13. sky/dashboard/out/clusters/[cluster].html +1 -1
  14. sky/dashboard/out/clusters.html +1 -1
  15. sky/dashboard/out/config.html +1 -1
  16. sky/dashboard/out/index.html +1 -1
  17. sky/dashboard/out/infra/[context].html +1 -1
  18. sky/dashboard/out/infra.html +1 -1
  19. sky/dashboard/out/jobs/[job].html +1 -1
  20. sky/dashboard/out/jobs/pools/[pool].html +1 -1
  21. sky/dashboard/out/jobs.html +1 -1
  22. sky/dashboard/out/users.html +1 -1
  23. sky/dashboard/out/volumes.html +1 -1
  24. sky/dashboard/out/workspace/new.html +1 -1
  25. sky/dashboard/out/workspaces/[name].html +1 -1
  26. sky/dashboard/out/workspaces.html +1 -1
  27. sky/global_user_state.py +5 -2
  28. sky/models.py +1 -0
  29. sky/provision/runpod/__init__.py +3 -0
  30. sky/provision/runpod/instance.py +17 -0
  31. sky/provision/runpod/utils.py +23 -5
  32. sky/provision/runpod/volume.py +158 -0
  33. sky/server/requests/payloads.py +7 -1
  34. sky/server/requests/preconditions.py +8 -7
  35. sky/server/requests/requests.py +123 -57
  36. sky/server/server.py +32 -25
  37. sky/server/stream_utils.py +14 -6
  38. sky/server/uvicorn.py +2 -1
  39. sky/templates/kubernetes-ray.yml.j2 +5 -5
  40. sky/templates/runpod-ray.yml.j2 +8 -0
  41. sky/utils/benchmark_utils.py +60 -0
  42. sky/utils/command_runner.py +4 -0
  43. sky/utils/db/migration_utils.py +20 -4
  44. sky/utils/resource_checker.py +6 -5
  45. sky/utils/schemas.py +1 -1
  46. sky/utils/volume.py +3 -0
  47. sky/volumes/client/sdk.py +28 -0
  48. sky/volumes/server/server.py +11 -1
  49. sky/volumes/utils.py +117 -68
  50. sky/volumes/volume.py +98 -39
  51. {skypilot_nightly-1.0.0.dev20250902.dist-info → skypilot_nightly-1.0.0.dev20250903.dist-info}/METADATA +34 -34
  52. {skypilot_nightly-1.0.0.dev20250902.dist-info → skypilot_nightly-1.0.0.dev20250903.dist-info}/RECORD +57 -55
  53. sky/dashboard/out/_next/static/chunks/1121-8afcf719ea87debc.js +0 -1
  54. sky/dashboard/out/_next/static/chunks/pages/clusters/[cluster]/[job]-06afb50d25f7c61f.js +0 -16
  55. /sky/dashboard/out/_next/static/{tio0QibqY2C0F2-rPy00p → yLz6EPhW_XXmnNs1I6dmS}/_ssgManifest.js +0 -0
  56. {skypilot_nightly-1.0.0.dev20250902.dist-info → skypilot_nightly-1.0.0.dev20250903.dist-info}/WHEEL +0 -0
  57. {skypilot_nightly-1.0.0.dev20250902.dist-info → skypilot_nightly-1.0.0.dev20250903.dist-info}/entry_points.txt +0 -0
  58. {skypilot_nightly-1.0.0.dev20250902.dist-info → skypilot_nightly-1.0.0.dev20250903.dist-info}/licenses/LICENSE +0 -0
  59. {skypilot_nightly-1.0.0.dev20250902.dist-info → skypilot_nightly-1.0.0.dev20250903.dist-info}/top_level.txt +0 -0
sky/volumes/utils.py CHANGED
@@ -13,6 +13,19 @@ from sky.utils import volume
13
13
 
14
14
  logger = sky_logging.init_logger(__name__)
15
15
 
16
+ _BASIC_COLUMNS = [
17
+ 'NAME',
18
+ 'TYPE',
19
+ 'INFRA',
20
+ 'SIZE',
21
+ 'USER',
22
+ 'WORKSPACE',
23
+ 'AGE',
24
+ 'STATUS',
25
+ 'LAST_USE',
26
+ 'USED_BY',
27
+ ]
28
+
16
29
 
17
30
  def _get_infra_str(cloud: Optional[str], region: Optional[str],
18
31
  zone: Optional[str]) -> str:
@@ -30,20 +43,71 @@ def _get_infra_str(cloud: Optional[str], region: Optional[str],
30
43
  class VolumeTable(abc.ABC):
31
44
  """The volume table."""
32
45
 
46
+ def __init__(self, volumes: List[Dict[str, Any]], show_all: bool = False):
47
+ super().__init__()
48
+ self.table = self._create_table(show_all)
49
+ self._add_rows(volumes, show_all)
50
+
51
+ def _get_row_base_columns(self,
52
+ row: Dict[str, Any],
53
+ show_all: bool = False) -> List[str]:
54
+ """Get the base columns for a row."""
55
+ # Convert last_attached_at timestamp to human readable string
56
+ last_attached_at = row.get('last_attached_at')
57
+ if last_attached_at is not None:
58
+ last_attached_at_str = datetime.fromtimestamp(
59
+ last_attached_at).strftime('%Y-%m-%d %H:%M:%S')
60
+ else:
61
+ last_attached_at_str = '-'
62
+ size = row.get('size', '')
63
+ if size:
64
+ size = f'{size}Gi'
65
+ usedby_str = '-'
66
+ usedby_clusters = row.get('usedby_clusters')
67
+ usedby_pods = row.get('usedby_pods')
68
+ if usedby_clusters:
69
+ usedby_str = f'{", ".join(usedby_clusters)}'
70
+ elif usedby_pods:
71
+ usedby_str = f'{", ".join(usedby_pods)}'
72
+ if show_all:
73
+ usedby = usedby_str
74
+ else:
75
+ usedby = common_utils.truncate_long_string(
76
+ usedby_str, constants.USED_BY_TRUNC_LENGTH)
77
+ infra = _get_infra_str(row.get('cloud'), row.get('region'),
78
+ row.get('zone'))
79
+ return [
80
+ row.get('name', ''),
81
+ row.get('type', ''),
82
+ infra,
83
+ size,
84
+ row.get('user_name', '-'),
85
+ row.get('workspace', '-'),
86
+ log_utils.human_duration(row.get('launched_at', 0)),
87
+ row.get('status', ''),
88
+ last_attached_at_str,
89
+ usedby,
90
+ ]
91
+
92
+ def _create_table(self, show_all: bool = False) -> prettytable.PrettyTable:
93
+ """Create the volume table."""
94
+ raise NotImplementedError
95
+
96
+ def _add_rows(self,
97
+ volumes: List[Dict[str, Any]],
98
+ show_all: bool = False) -> None:
99
+ """Add rows to the volume table."""
100
+ raise NotImplementedError
101
+
33
102
  @abc.abstractmethod
34
103
  def format(self) -> str:
35
104
  """Format the volume table for display."""
36
- pass
105
+ raise NotImplementedError
37
106
 
38
107
 
39
108
  class PVCVolumeTable(VolumeTable):
40
109
  """The PVC volume table."""
41
110
 
42
- def __init__(self, volumes: List[Dict[str, Any]], show_all: bool = False):
43
- super().__init__()
44
- self.table = self._create_table(show_all)
45
- self._add_rows(volumes, show_all)
46
-
47
111
  def _create_table(self, show_all: bool = False) -> prettytable.PrettyTable:
48
112
  """Create the PVC volume table."""
49
113
  # If show_all is False, show the table with the columns:
@@ -55,34 +119,13 @@ class PVCVolumeTable(VolumeTable):
55
119
  # STORAGE_CLASS, ACCESS_MODE
56
120
 
57
121
  if show_all:
58
- columns = [
59
- 'NAME',
60
- 'TYPE',
61
- 'INFRA',
62
- 'SIZE',
63
- 'USER',
64
- 'WORKSPACE',
65
- 'AGE',
66
- 'STATUS',
67
- 'LAST_USE',
68
- 'USED_BY',
122
+ columns = _BASIC_COLUMNS + [
69
123
  'NAME_ON_CLOUD',
70
124
  'STORAGE_CLASS',
71
125
  'ACCESS_MODE',
72
126
  ]
73
127
  else:
74
- columns = [
75
- 'NAME',
76
- 'TYPE',
77
- 'INFRA',
78
- 'SIZE',
79
- 'USER',
80
- 'WORKSPACE',
81
- 'AGE',
82
- 'STATUS',
83
- 'LAST_USE',
84
- 'USED_BY',
85
- ]
128
+ columns = _BASIC_COLUMNS
86
129
 
87
130
  table = log_utils.create_table(columns)
88
131
  return table
@@ -92,42 +135,7 @@ class PVCVolumeTable(VolumeTable):
92
135
  show_all: bool = False) -> None:
93
136
  """Add rows to the PVC volume table."""
94
137
  for row in volumes:
95
- # Convert last_attached_at timestamp to human readable string
96
- last_attached_at = row.get('last_attached_at')
97
- if last_attached_at is not None:
98
- last_attached_at_str = datetime.fromtimestamp(
99
- last_attached_at).strftime('%Y-%m-%d %H:%M:%S')
100
- else:
101
- last_attached_at_str = '-'
102
- size = row.get('size', '')
103
- if size:
104
- size = f'{size}Gi'
105
- usedby_str = '-'
106
- usedby_clusters = row.get('usedby_clusters')
107
- usedby_pods = row.get('usedby_pods')
108
- if usedby_clusters:
109
- usedby_str = f'{", ".join(usedby_clusters)}'
110
- elif usedby_pods:
111
- usedby_str = f'{", ".join(usedby_pods)}'
112
- if show_all:
113
- usedby = usedby_str
114
- else:
115
- usedby = common_utils.truncate_long_string(
116
- usedby_str, constants.USED_BY_TRUNC_LENGTH)
117
- infra = _get_infra_str(row.get('cloud'), row.get('region'),
118
- row.get('zone'))
119
- table_row = [
120
- row.get('name', ''),
121
- row.get('type', ''),
122
- infra,
123
- size,
124
- row.get('user_name', '-'),
125
- row.get('workspace', '-'),
126
- log_utils.human_duration(row.get('launched_at', 0)),
127
- row.get('status', ''),
128
- last_attached_at_str,
129
- usedby,
130
- ]
138
+ table_row = self._get_row_base_columns(row, show_all)
131
139
  if show_all:
132
140
  table_row.append(row.get('name_on_cloud', ''))
133
141
  table_row.append(
@@ -138,7 +146,43 @@ class PVCVolumeTable(VolumeTable):
138
146
 
139
147
  def format(self) -> str:
140
148
  """Format the PVC volume table for display."""
141
- return str(self.table)
149
+ return 'Kubernetes PVCs:\n' + str(self.table)
150
+
151
+
152
+ class RunPodVolumeTable(VolumeTable):
153
+ """The RunPod volume table."""
154
+
155
+ def _create_table(self, show_all: bool = False) -> prettytable.PrettyTable:
156
+ """Create the RunPod volume table."""
157
+ # If show_all is False, show the table with the columns:
158
+ # NAME, TYPE, INFRA, SIZE, USER, WORKSPACE,
159
+ # AGE, STATUS, LAST_USE, USED_BY
160
+ # If show_all is True, show the table with the columns:
161
+ # NAME, TYPE, INFRA, SIZE, USER, WORKSPACE,
162
+ # AGE, STATUS, LAST_USE, USED_BY, NAME_ON_CLOUD
163
+
164
+ if show_all:
165
+ columns = _BASIC_COLUMNS + ['NAME_ON_CLOUD']
166
+ else:
167
+ columns = _BASIC_COLUMNS
168
+
169
+ table = log_utils.create_table(columns)
170
+ return table
171
+
172
+ def _add_rows(self,
173
+ volumes: List[Dict[str, Any]],
174
+ show_all: bool = False) -> None:
175
+ """Add rows to the RunPod volume table."""
176
+ for row in volumes:
177
+ table_row = self._get_row_base_columns(row, show_all)
178
+ if show_all:
179
+ table_row.append(row.get('name_on_cloud', ''))
180
+
181
+ self.table.add_row(table_row)
182
+
183
+ def format(self) -> str:
184
+ """Format the RunPod volume table for display."""
185
+ return 'RunPod Network Volumes:\n' + str(self.table)
142
186
 
143
187
 
144
188
  def format_volume_table(volumes: List[Dict[str, Any]],
@@ -166,9 +210,14 @@ def format_volume_table(volumes: List[Dict[str, Any]],
166
210
  continue
167
211
  table_str = ''
168
212
  for volume_type, volume_list in volumes_per_type.items():
213
+ if table_str:
214
+ table_str += '\n\n'
169
215
  if volume_type == volume.VolumeType.PVC.value:
170
- table = PVCVolumeTable(volume_list, show_all)
171
- table_str += table.format()
216
+ pvc_table = PVCVolumeTable(volume_list, show_all)
217
+ table_str += pvc_table.format()
218
+ elif volume_type == volume.VolumeType.RUNPOD_NETWORK_VOLUME.value:
219
+ runpod_table = RunPodVolumeTable(volume_list, show_all)
220
+ table_str += runpod_table.format()
172
221
  if table_str:
173
222
  return table_str
174
223
  else:
sky/volumes/volume.py CHANGED
@@ -1,11 +1,18 @@
1
1
  """Volume types and access modes."""
2
2
  from typing import Any, Dict, Optional
3
3
 
4
+ from sky import clouds
4
5
  from sky.utils import common_utils
5
6
  from sky.utils import infra_utils
6
7
  from sky.utils import registry
7
8
  from sky.utils import resources_utils
8
9
  from sky.utils import schemas
10
+ from sky.utils import volume as volume_lib
11
+
12
+ VOLUME_TYPE_TO_CLOUD = {
13
+ volume_lib.VolumeType.PVC: clouds.Kubernetes(),
14
+ volume_lib.VolumeType.RUNPOD_NETWORK_VOLUME: clouds.RunPod(),
15
+ }
9
16
 
10
17
 
11
18
  class Volume:
@@ -42,18 +49,42 @@ class Volume:
42
49
  self.region: Optional[str] = None
43
50
  self.zone: Optional[str] = None
44
51
 
52
+ self._normalize_config()
53
+
45
54
  @classmethod
46
- def from_dict(cls, config_dict: Dict[str, Any]) -> 'Volume':
47
- """Create a Volume instance from a dictionary."""
48
- return cls(name=config_dict.get('name'),
49
- type=config_dict.get('type'),
50
- infra=config_dict.get('infra'),
51
- size=config_dict.get('size'),
52
- labels=config_dict.get('labels'),
53
- resource_name=config_dict.get('resource_name'),
54
- config=config_dict.get('config', {}))
55
-
56
- def to_dict(self) -> Dict[str, Any]:
55
+ def from_yaml_config(cls, config: Dict[str, Any]) -> 'Volume':
56
+ """Create a Volume subclass instance from a dictionary via factory."""
57
+ vol_type_val = config.get('type')
58
+ try:
59
+ vt = (volume_lib.VolumeType(vol_type_val)
60
+ if vol_type_val is not None else None)
61
+ except Exception: # pylint: disable=broad-except
62
+ vt = None
63
+
64
+ if vt is None:
65
+ raise ValueError(f'Invalid volume type: {vol_type_val}')
66
+
67
+ if vt == volume_lib.VolumeType.PVC:
68
+ return PVCVolume(name=config.get('name'),
69
+ type=vol_type_val,
70
+ infra=config.get('infra'),
71
+ size=config.get('size'),
72
+ labels=config.get('labels'),
73
+ resource_name=config.get('resource_name'),
74
+ config=config.get('config', {}))
75
+ if vt == volume_lib.VolumeType.RUNPOD_NETWORK_VOLUME:
76
+ return RunpodNetworkVolume(
77
+ name=config.get('name'),
78
+ type=vol_type_val,
79
+ infra=config.get('infra'),
80
+ size=config.get('size'),
81
+ labels=config.get('labels'),
82
+ resource_name=config.get('resource_name'),
83
+ config=config.get('config', {}))
84
+
85
+ raise ValueError(f'Invalid volume type: {vol_type_val}')
86
+
87
+ def to_yaml_config(self) -> Dict[str, Any]:
57
88
  """Convert the Volume to a dictionary."""
58
89
  return {
59
90
  'name': self.name,
@@ -68,32 +99,10 @@ class Volume:
68
99
  'zone': self.zone,
69
100
  }
70
101
 
71
- def normalize_config(
72
- self,
73
- name: Optional[str] = None,
74
- infra: Optional[str] = None,
75
- type: Optional[str] = None, # pylint: disable=redefined-builtin
76
- size: Optional[str] = None) -> None:
77
- """Override the volume config with CLI options,
78
- adjust and validate the config.
79
-
80
- Args:
81
- name: Volume name to override
82
- infra: Infrastructure to override
83
- type: Volume type to override
84
- size: Volume size to override
85
- """
86
- if name is not None:
87
- self.name = name
88
- if infra is not None:
89
- self.infra = infra
90
- if type is not None:
91
- self.type = type
92
- if size is not None:
93
- self.size = size
94
-
102
+ def _normalize_config(self) -> None:
103
+ """Adjust and validate the config."""
95
104
  # Validate schema
96
- common_utils.validate_schema(self.to_dict(),
105
+ common_utils.validate_schema(self.to_yaml_config(),
97
106
  schemas.get_volume_schema(),
98
107
  'Invalid volumes config: ')
99
108
 
@@ -125,9 +134,21 @@ class Volume:
125
134
 
126
135
  def _validate_config(self) -> None:
127
136
  """Validate the volume config."""
128
- assert self.cloud is not None, 'Cloud must be specified'
129
- cloud_obj = registry.CLOUD_REGISTRY.from_str(self.cloud)
130
- assert cloud_obj is not None
137
+ cloud_obj_from_type = VOLUME_TYPE_TO_CLOUD.get(
138
+ volume_lib.VolumeType(self.type))
139
+ if self.cloud:
140
+ cloud_obj = registry.CLOUD_REGISTRY.from_str(self.cloud)
141
+ assert cloud_obj is not None
142
+ if not cloud_obj.is_same_cloud(cloud_obj_from_type):
143
+ raise ValueError(
144
+ f'Invalid cloud {self.cloud} for volume type {self.type}')
145
+ else:
146
+ self.cloud = str(cloud_obj_from_type)
147
+ cloud_obj = cloud_obj_from_type
148
+ assert cloud_obj is not None
149
+
150
+ self.region, self.zone = cloud_obj.validate_region_zone(
151
+ self.region, self.zone)
131
152
 
132
153
  valid, err_msg = cloud_obj.is_volume_name_valid(self.name)
133
154
  if not valid:
@@ -142,3 +163,41 @@ class Volume:
142
163
  valid, err_msg = cloud_obj.is_label_valid(key, value)
143
164
  if not valid:
144
165
  raise ValueError(f'{err_msg}')
166
+
167
+ # Extra, type-specific validations
168
+ self._validate_config_extra()
169
+
170
+ # Hook methods for subclasses
171
+ def _validate_config_extra(self) -> None:
172
+ """Additional type-specific validation.
173
+
174
+ Subclasses can override to enforce stricter rules.
175
+ """
176
+ return
177
+
178
+
179
+ class PVCVolume(Volume):
180
+ """Kubernetes PVC-backed volume."""
181
+ pass
182
+
183
+
184
+ class RunpodNetworkVolume(Volume):
185
+ """RunPod Network Volume."""
186
+
187
+ def _validate_config_extra(self) -> None:
188
+ if self.size is not None:
189
+ try:
190
+ size_int = int(self.size)
191
+ if size_int < volume_lib.MIN_RUNPOD_NETWORK_VOLUME_SIZE_GB:
192
+ raise ValueError(
193
+ f'RunPod network volume size must be at least '
194
+ f'{volume_lib.MIN_RUNPOD_NETWORK_VOLUME_SIZE_GB}GB.')
195
+ except Exception as e: # pylint: disable=broad-except
196
+ raise ValueError(f'Invalid volume size {self.size!r}: '
197
+ f'{e}') from e
198
+ if not self.zone:
199
+ raise ValueError(
200
+ 'RunPod DataCenterId is required to create a network '
201
+ 'volume. Set the zone in the infra field.')
202
+
203
+ return
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: skypilot-nightly
3
- Version: 1.0.0.dev20250902
3
+ Version: 1.0.0.dev20250903
4
4
  Summary: SkyPilot: Run AI on Any Infra — Unified, Faster, Cheaper.
5
5
  Author: SkyPilot Team
6
6
  License: Apache 2.0
@@ -145,48 +145,48 @@ Requires-Dist: grpcio>=1.63.0; extra == "server"
145
145
  Requires-Dist: protobuf<7.0.0,>=5.26.1; extra == "server"
146
146
  Requires-Dist: aiosqlite; extra == "server"
147
147
  Provides-Extra: all
148
- Requires-Dist: sqlalchemy_adapter; extra == "all"
148
+ Requires-Dist: ibm-cos-sdk; extra == "all"
149
+ Requires-Dist: ray[default]!=2.6.0,>=2.2.0; extra == "all"
150
+ Requires-Dist: vastai-sdk>=0.1.12; extra == "all"
151
+ Requires-Dist: aiohttp; extra == "all"
152
+ Requires-Dist: google-cloud-storage; extra == "all"
153
+ Requires-Dist: websockets; extra == "all"
154
+ Requires-Dist: azure-mgmt-compute>=33.0.0; extra == "all"
155
+ Requires-Dist: kubernetes!=32.0.0,>=20.0.0; extra == "all"
156
+ Requires-Dist: msgraph-sdk; extra == "all"
157
+ Requires-Dist: azure-storage-blob>=12.23.1; extra == "all"
158
+ Requires-Dist: anyio; extra == "all"
159
+ Requires-Dist: boto3>=1.26.1; extra == "all"
149
160
  Requires-Dist: google-api-python-client>=2.69.0; extra == "all"
150
- Requires-Dist: oci; extra == "all"
151
- Requires-Dist: azure-common; extra == "all"
161
+ Requires-Dist: pyopenssl<24.3.0,>=23.2.0; extra == "all"
162
+ Requires-Dist: cudo-compute>=0.1.10; extra == "all"
163
+ Requires-Dist: azure-mgmt-network>=27.0.0; extra == "all"
152
164
  Requires-Dist: pyvmomi==8.0.1.0.2; extra == "all"
153
- Requires-Dist: azure-core>=1.31.0; extra == "all"
154
- Requires-Dist: colorama<0.4.5; extra == "all"
155
- Requires-Dist: azure-cli>=2.65.0; extra == "all"
156
- Requires-Dist: azure-storage-blob>=12.23.1; extra == "all"
157
- Requires-Dist: docker; extra == "all"
165
+ Requires-Dist: passlib; extra == "all"
158
166
  Requires-Dist: azure-identity>=1.19.0; extra == "all"
159
167
  Requires-Dist: botocore>=1.29.10; extra == "all"
160
- Requires-Dist: casbin; extra == "all"
161
- Requires-Dist: runpod>=1.6.1; extra == "all"
162
- Requires-Dist: cudo-compute>=0.1.10; extra == "all"
163
- Requires-Dist: protobuf<7.0.0,>=5.26.1; extra == "all"
164
- Requires-Dist: ibm-vpc; extra == "all"
165
168
  Requires-Dist: awscli>=1.27.10; extra == "all"
169
+ Requires-Dist: python-dateutil; extra == "all"
166
170
  Requires-Dist: pyjwt; extra == "all"
167
- Requires-Dist: anyio; extra == "all"
168
- Requires-Dist: boto3>=1.26.1; extra == "all"
169
- Requires-Dist: aiohttp; extra == "all"
170
- Requires-Dist: msrestazure; extra == "all"
171
- Requires-Dist: kubernetes!=32.0.0,>=20.0.0; extra == "all"
172
- Requires-Dist: vastai-sdk>=0.1.12; extra == "all"
171
+ Requires-Dist: oci; extra == "all"
172
+ Requires-Dist: ibm-cloud-sdk-core; extra == "all"
173
+ Requires-Dist: azure-cli>=2.65.0; extra == "all"
174
+ Requires-Dist: aiosqlite; extra == "all"
173
175
  Requires-Dist: pydo>=0.3.0; extra == "all"
174
- Requires-Dist: pyopenssl<24.3.0,>=23.2.0; extra == "all"
175
- Requires-Dist: nebius>=0.2.47; extra == "all"
176
- Requires-Dist: websockets; extra == "all"
176
+ Requires-Dist: docker; extra == "all"
177
+ Requires-Dist: azure-common; extra == "all"
178
+ Requires-Dist: colorama<0.4.5; extra == "all"
179
+ Requires-Dist: msrestazure; extra == "all"
180
+ Requires-Dist: ibm-vpc; extra == "all"
177
181
  Requires-Dist: ibm-platform-services>=0.48.0; extra == "all"
178
- Requires-Dist: google-cloud-storage; extra == "all"
179
- Requires-Dist: ray[default]!=2.6.0,>=2.2.0; extra == "all"
180
- Requires-Dist: grpcio>=1.63.0; extra == "all"
181
- Requires-Dist: azure-mgmt-network>=27.0.0; extra == "all"
182
- Requires-Dist: azure-mgmt-compute>=33.0.0; extra == "all"
183
- Requires-Dist: python-dateutil; extra == "all"
184
- Requires-Dist: passlib; extra == "all"
185
182
  Requires-Dist: azure-core>=1.24.0; extra == "all"
186
- Requires-Dist: msgraph-sdk; extra == "all"
187
- Requires-Dist: aiosqlite; extra == "all"
188
- Requires-Dist: ibm-cloud-sdk-core; extra == "all"
189
- Requires-Dist: ibm-cos-sdk; extra == "all"
183
+ Requires-Dist: sqlalchemy_adapter; extra == "all"
184
+ Requires-Dist: azure-core>=1.31.0; extra == "all"
185
+ Requires-Dist: nebius>=0.2.47; extra == "all"
186
+ Requires-Dist: casbin; extra == "all"
187
+ Requires-Dist: protobuf<7.0.0,>=5.26.1; extra == "all"
188
+ Requires-Dist: grpcio>=1.63.0; extra == "all"
189
+ Requires-Dist: runpod>=1.6.1; extra == "all"
190
190
  Dynamic: author
191
191
  Dynamic: classifier
192
192
  Dynamic: description