anyscale 0.24.88__py3-none-any.whl → 0.25.5__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 (148) hide show
  1. anyscale/__init__.py +56 -0
  2. anyscale/_private/anyscale_client/anyscale_client.py +179 -28
  3. anyscale/_private/anyscale_client/common.py +109 -2
  4. anyscale/_private/anyscale_client/fake_anyscale_client.py +239 -1
  5. anyscale/_private/docgen/README.md +1 -1
  6. anyscale/_private/docgen/__main__.py +71 -21
  7. anyscale/_private/docgen/api.md +13 -20
  8. anyscale/_private/docgen/generator.py +3 -2
  9. anyscale/_private/docgen/models.md +4 -49
  10. anyscale/_private/workload/workload_config.py +21 -7
  11. anyscale/aggregated_instance_usage/__init__.py +1 -1
  12. anyscale/aggregated_instance_usage/commands.py +2 -4
  13. anyscale/aggregated_instance_usage/models.py +8 -8
  14. anyscale/client/README.md +25 -22
  15. anyscale/client/openapi_client/__init__.py +16 -14
  16. anyscale/client/openapi_client/api/default_api.py +1139 -959
  17. anyscale/client/openapi_client/models/__init__.py +16 -14
  18. anyscale/client/openapi_client/models/baseimagesenum.py +43 -1
  19. anyscale/client/openapi_client/models/{session_event_types.py → cloud_deployment_config.py} +35 -24
  20. anyscale/client/openapi_client/models/{platformfinetuningjob_response.py → clouddeploymentconfig_response.py} +11 -11
  21. anyscale/client/openapi_client/models/{log_level_types.py → cluster_event_source.py} +12 -7
  22. anyscale/client/openapi_client/models/{company_size.py → cluster_size.py} +10 -10
  23. anyscale/client/openapi_client/models/cluster_status_details.py +2 -1
  24. anyscale/client/openapi_client/models/{sessionevent_list_response.py → clusterevent_list_response.py} +15 -15
  25. anyscale/client/openapi_client/models/create_experimental_workspace.py +29 -1
  26. anyscale/client/openapi_client/models/create_notification_channel_record.py +29 -3
  27. anyscale/client/openapi_client/models/decorated_interactive_session.py +1 -57
  28. anyscale/client/openapi_client/models/decorated_job.py +1 -57
  29. anyscale/client/openapi_client/models/decorated_job_submission.py +1 -29
  30. anyscale/client/openapi_client/models/decorated_production_job.py +1 -29
  31. anyscale/client/openapi_client/models/decorated_session.py +1 -57
  32. anyscale/client/openapi_client/models/decorated_unified_job.py +1 -30
  33. anyscale/client/openapi_client/models/{resubmit_ft_job_request.py → describe_machine_pool_request.py} +21 -20
  34. anyscale/client/openapi_client/models/describe_machine_pool_response.py +123 -0
  35. anyscale/client/openapi_client/models/describemachinepoolresponse_response.py +121 -0
  36. anyscale/client/openapi_client/models/ha_jobs_sort_field.py +1 -2
  37. anyscale/client/openapi_client/models/internal_production_job.py +1 -29
  38. anyscale/client/openapi_client/models/jobs_sort_field.py +1 -2
  39. anyscale/client/openapi_client/models/machine_allocation_state.py +3 -1
  40. anyscale/client/openapi_client/models/machine_state_info.py +326 -0
  41. anyscale/client/openapi_client/models/{fine_tuning_job_status.py → notification_channel_slack_config.py} +34 -16
  42. anyscale/client/openapi_client/models/organization_marketing_questions.py +80 -54
  43. anyscale/client/openapi_client/models/request_state_info.py +210 -0
  44. anyscale/client/openapi_client/models/{platformfinetuningjob_list_response.py → scheduler_info.py} +43 -38
  45. anyscale/client/openapi_client/models/serve_deployment_fast_api_docs_status.py +123 -0
  46. anyscale/client/openapi_client/models/serve_deployment_state.py +2 -1
  47. anyscale/client/openapi_client/models/servedeploymentfastapidocsstatus_response.py +121 -0
  48. anyscale/client/openapi_client/models/sessions_sort_field.py +1 -2
  49. anyscale/client/openapi_client/models/supportedbaseimagesenum.py +43 -1
  50. anyscale/client/openapi_client/models/unified_job_sort_field.py +1 -2
  51. anyscale/client/openapi_client/models/update_cloud_collaborator.py +121 -0
  52. anyscale/client/openapi_client/models/usage_by_cluster.py +28 -1
  53. anyscale/client/openapi_client/models/usage_by_user.py +30 -3
  54. anyscale/client/openapi_client/models/workload_info.py +210 -0
  55. anyscale/cloud/__init__.py +83 -0
  56. anyscale/cloud/_private/cloud_sdk.py +25 -0
  57. anyscale/cloud/commands.py +45 -0
  58. anyscale/cloud/models.py +91 -0
  59. anyscale/cluster_compute.py +1 -1
  60. anyscale/commands/aggregated_instance_usage_commands.py +4 -4
  61. anyscale/commands/cloud_commands.py +87 -14
  62. anyscale/commands/command_examples.py +65 -0
  63. anyscale/commands/job_commands.py +15 -3
  64. anyscale/commands/machine_pool_commands.py +113 -1
  65. anyscale/commands/organization_invitation_commands.py +98 -0
  66. anyscale/commands/project_commands.py +52 -2
  67. anyscale/commands/resource_quota_commands.py +98 -11
  68. anyscale/commands/service_account_commands.py +65 -8
  69. anyscale/commands/service_commands.py +61 -1
  70. anyscale/commands/session_commands_hidden.py +5 -1
  71. anyscale/commands/user_commands.py +1 -1
  72. anyscale/commands/util.py +2 -2
  73. anyscale/commands/workspace_commands.py +1 -1
  74. anyscale/connect.py +1 -1
  75. anyscale/connect_utils/project.py +7 -4
  76. anyscale/controllers/cloud_controller.py +63 -30
  77. anyscale/controllers/cloud_functional_verification_controller.py +1 -1
  78. anyscale/controllers/cluster_controller.py +3 -11
  79. anyscale/controllers/compute_config_controller.py +1 -1
  80. anyscale/controllers/experimental_integrations_controller.py +1 -1
  81. anyscale/controllers/job_controller.py +8 -6
  82. anyscale/controllers/list_controller.py +2 -2
  83. anyscale/controllers/machine_pool_controller.py +12 -1
  84. anyscale/controllers/project_controller.py +4 -3
  85. anyscale/controllers/schedule_controller.py +1 -1
  86. anyscale/controllers/service_controller.py +1 -1
  87. anyscale/controllers/workspace_controller.py +1 -1
  88. anyscale/models/job_model.py +1 -1
  89. anyscale/organization_invitation/__init__.py +61 -0
  90. anyscale/organization_invitation/_private/organization_invitation_sdk.py +24 -0
  91. anyscale/organization_invitation/commands.py +84 -0
  92. anyscale/organization_invitation/models.py +45 -0
  93. anyscale/project/__init__.py +35 -0
  94. anyscale/project/_private/project_sdk.py +27 -0
  95. anyscale/project/commands.py +56 -0
  96. anyscale/project/models.py +91 -0
  97. anyscale/{project.py → project_utils.py} +3 -4
  98. anyscale/resource_quota/__init__.py +99 -0
  99. anyscale/resource_quota/_private/resource_quota_sdk.py +120 -0
  100. anyscale/resource_quota/commands.py +150 -0
  101. anyscale/resource_quota/models.py +303 -0
  102. anyscale/scripts.py +4 -0
  103. anyscale/sdk/anyscale_client/__init__.py +0 -5
  104. anyscale/sdk/anyscale_client/api/default_api.py +119 -150
  105. anyscale/sdk/anyscale_client/models/__init__.py +0 -5
  106. anyscale/sdk/anyscale_client/models/baseimagesenum.py +43 -1
  107. anyscale/sdk/anyscale_client/models/cluster_status_details.py +2 -1
  108. anyscale/sdk/anyscale_client/models/jobs_sort_field.py +1 -2
  109. anyscale/sdk/anyscale_client/models/supportedbaseimagesenum.py +43 -1
  110. anyscale/sdk/anyscale_client/sdk.py +1 -1
  111. anyscale/service/__init__.py +21 -0
  112. anyscale/service/_private/service_sdk.py +13 -0
  113. anyscale/service/commands.py +35 -0
  114. anyscale/service_account/__init__.py +88 -0
  115. anyscale/service_account/_private/service_account_sdk.py +101 -0
  116. anyscale/service_account/commands.py +147 -0
  117. anyscale/service_account/models.py +66 -0
  118. anyscale/shared_anyscale_utils/latest_ray_version.py +1 -1
  119. anyscale/shared_anyscale_utils/utils/id_gen.py +2 -0
  120. anyscale/user/__init__.py +1 -1
  121. anyscale/user/commands.py +1 -1
  122. anyscale/user/models.py +25 -15
  123. anyscale/util.py +23 -0
  124. anyscale/utils/cloud_utils.py +1 -1
  125. anyscale/version.py +1 -1
  126. anyscale/workspace_utils.py +1 -1
  127. {anyscale-0.24.88.dist-info → anyscale-0.25.5.dist-info}/METADATA +1 -5
  128. {anyscale-0.24.88.dist-info → anyscale-0.25.5.dist-info}/RECORD +134 -119
  129. anyscale/client/openapi_client/models/create_fine_tuning_hyperparameters.py +0 -156
  130. anyscale/client/openapi_client/models/create_fine_tuning_job_product_request.py +0 -353
  131. anyscale/client/openapi_client/models/finish_ft_job_request.py +0 -204
  132. anyscale/client/openapi_client/models/platform_fine_tuning_job.py +0 -577
  133. anyscale/client/openapi_client/models/session_event.py +0 -267
  134. anyscale/client/openapi_client/models/session_event_cause.py +0 -150
  135. anyscale/controllers/resource_quota_controller.py +0 -183
  136. anyscale/controllers/service_account_controller.py +0 -168
  137. anyscale/sdk/anyscale_client/models/log_level_types.py +0 -100
  138. anyscale/sdk/anyscale_client/models/session_event.py +0 -267
  139. anyscale/sdk/anyscale_client/models/session_event_cause.py +0 -150
  140. anyscale/sdk/anyscale_client/models/session_event_types.py +0 -111
  141. anyscale/sdk/anyscale_client/models/sessionevent_list_response.py +0 -147
  142. anyscale/utils/imports/azure.py +0 -14
  143. /anyscale/{cloud.py → cloud_utils.py} +0 -0
  144. {anyscale-0.24.88.dist-info → anyscale-0.25.5.dist-info}/LICENSE +0 -0
  145. {anyscale-0.24.88.dist-info → anyscale-0.25.5.dist-info}/NOTICE +0 -0
  146. {anyscale-0.24.88.dist-info → anyscale-0.25.5.dist-info}/WHEEL +0 -0
  147. {anyscale-0.24.88.dist-info → anyscale-0.25.5.dist-info}/entry_points.txt +0 -0
  148. {anyscale-0.24.88.dist-info → anyscale-0.25.5.dist-info}/top_level.txt +0 -0
@@ -16,10 +16,15 @@ from anyscale.cli_logger import BlockLogger
16
16
  from anyscale.client.openapi_client.models import (
17
17
  AdminCreatedUser,
18
18
  AdminCreateUser,
19
+ AnyscaleServiceAccount,
19
20
  Cloud,
21
+ CloudProviders,
20
22
  ComputeTemplateConfig,
23
+ CreateCloudCollaborator,
21
24
  CreateExperimentalWorkspace,
22
25
  CreateInternalProductionJob,
26
+ CreateResourceQuota,
27
+ CreateUserProjectCollaborator,
23
28
  DecoratedComputeTemplate,
24
29
  DeletedPlatformFineTunedModel,
25
30
  ExperimentalWorkspace,
@@ -28,9 +33,16 @@ from anyscale.client.openapi_client.models import (
28
33
  HaJobGoalStates,
29
34
  HaJobStates,
30
35
  InternalProductionJob,
36
+ MiniCloud,
37
+ MiniUser,
38
+ OrganizationCollaborator,
39
+ OrganizationInvitation,
40
+ OrganizationPermissionLevel,
31
41
  ProductionJob,
32
42
  ProductionJobStateTransition,
33
43
  Project,
44
+ ResourceQuota,
45
+ ServerSessionToken,
34
46
  WorkspaceDataplaneProxiedArtifacts,
35
47
  )
36
48
  from anyscale.client.openapi_client.models.create_schedule import CreateSchedule
@@ -132,9 +144,11 @@ class FakeAnyscaleClient(AnyscaleClientInterface):
132
144
  self._workspace_cluster: Optional[Cluster] = None
133
145
  self._workspace_dependency_tracking_enabled: bool = False
134
146
  self._services: Dict[str, ServiceModel] = {}
147
+ self._archived_services: Dict[str, ServiceModel] = {}
135
148
  self._jobs: Dict[str, ProductionJob] = {}
136
149
  self._job_runs: Dict[str, List[APIJobRun]] = defaultdict(list)
137
150
  self._project_to_id: Dict[Optional[str] : Dict[Optional[str], str]] = {}
151
+ self._project_collaborators: Dict[str, List[CreateUserProjectCollaborator]] = {}
138
152
  self._rolled_out_model: Optional[ApplyServiceModel] = None
139
153
  self._sent_workspace_notifications: List[WorkspaceNotification] = []
140
154
  self._rolled_back_service: Optional[Tuple[str, Optional[int]]] = None
@@ -154,6 +168,10 @@ class FakeAnyscaleClient(AnyscaleClientInterface):
154
168
  self._workspaces_env_vars: Dict[str, Dict[str, str]] = {}
155
169
  self._clusters_headnode_ip: Dict[str, str] = {}
156
170
  self._clusters_ssh_key: Dict[str, SessionSshKey] = {}
171
+ self._api_keys: Dict[str, List[str]] = defaultdict(list)
172
+ self._organization_collaborators: List[OrganizationCollaborator] = []
173
+ self._organization_invitations: Dict[str, OrganizationInvitation] = {}
174
+ self._resource_quotas: Dict[str, ResourceQuota] = {}
157
175
 
158
176
  # Cloud ID -> Cloud.
159
177
  self._clouds: Dict[str, Cloud] = {
@@ -164,6 +182,9 @@ class FakeAnyscaleClient(AnyscaleClientInterface):
164
182
  ),
165
183
  }
166
184
 
185
+ # Cloud ID -> collaborators
186
+ self._cloud_collaborators: Dict[str, List[CreateCloudCollaborator]] = {}
187
+
167
188
  # Cloud ID -> default ClusterCompute.
168
189
  compute_config = ClusterCompute(
169
190
  id=self.DEFAULT_CLUSTER_COMPUTE_ID,
@@ -347,6 +368,25 @@ class FakeAnyscaleClient(AnyscaleClientInterface):
347
368
  def get_cloud(self, *, cloud_id: str) -> Optional[Cloud]:
348
369
  return self._clouds.get(cloud_id, None)
349
370
 
371
+ def add_cloud_collaborators(
372
+ self, cloud_id: str, collaborators: List[CreateCloudCollaborator]
373
+ ) -> None:
374
+ existing_collaborators = [
375
+ collaborator.email
376
+ for collaborator in self._cloud_collaborators.get(cloud_id, [])
377
+ ]
378
+
379
+ for collaborator in collaborators:
380
+ if collaborator.email in existing_collaborators:
381
+ raise ValueError(
382
+ f"Collaborator with email '{collaborator.email}' already exists in cloud '{cloud_id}'."
383
+ )
384
+
385
+ if cloud_id not in self._cloud_collaborators:
386
+ self._cloud_collaborators[cloud_id] = collaborators
387
+ else:
388
+ self._cloud_collaborators[cloud_id].extend(collaborators)
389
+
350
390
  def add_compute_config(self, compute_config: DecoratedComputeTemplate) -> int:
351
391
  compute_config.version = (
352
392
  len(self._compute_config_name_to_ids[compute_config.name]) + 1
@@ -579,6 +619,28 @@ class FakeAnyscaleClient(AnyscaleClientInterface):
579
619
  )
580
620
  return None
581
621
 
622
+ def add_project_collaborators(
623
+ self, project_id: str, collaborators: List[CreateUserProjectCollaborator]
624
+ ):
625
+ existing_collaborators = [
626
+ collaborator.value.email if collaborator.value else None
627
+ for collaborator in self._project_collaborators.get(project_id, [])
628
+ ]
629
+
630
+ for collaborator in collaborators:
631
+ if (
632
+ collaborator.value
633
+ and collaborator.value.email in existing_collaborators
634
+ ):
635
+ raise ValueError(
636
+ f"Collaborator with email '{collaborator.value.email}' already exists in project '{project_id}'."
637
+ )
638
+
639
+ if project_id not in self._project_collaborators:
640
+ self._project_collaborators[project_id] = collaborators
641
+ else:
642
+ self._project_collaborators[project_id].extend(collaborators)
643
+
582
644
  def get_job(
583
645
  self,
584
646
  *,
@@ -702,6 +764,16 @@ class FakeAnyscaleClient(AnyscaleClientInterface):
702
764
  service_id
703
765
  ].primary_version.current_state = ServiceVersionState.TERMINATED
704
766
 
767
+ @property
768
+ def archived_services(self) -> Dict[str, ServiceModel]:
769
+ return self._archived_services
770
+
771
+ def archive_service(self, service_id: str):
772
+ self._archived_services[service_id] = self._services.pop(service_id)
773
+
774
+ def is_archived_service(self, service_id: str) -> bool:
775
+ return service_id in self._archived_services
776
+
705
777
  @property
706
778
  def submitted_job(self) -> Optional[CreateInternalProductionJob]:
707
779
  return self._submitted_job
@@ -908,7 +980,7 @@ class FakeAnyscaleClient(AnyscaleClientInterface):
908
980
  compute_config_id=model.compute_config_id,
909
981
  environment_id=model.cluster_environment_build_id,
910
982
  cloud_id=model.cloud_id or self.get_cloud_id(),
911
- created_at=datetime.now(),
983
+ created_at=datetime.utcnow(),
912
984
  creator_id=self.DEFAULT_USER_ID,
913
985
  creator_email=self.DEFAULT_USER_EMAIL,
914
986
  organization_id=self.DEFAULT_ORGANIZATION_ID,
@@ -1082,6 +1154,20 @@ class FakeAnyscaleClient(AnyscaleClientInterface):
1082
1154
 
1083
1155
  return filepath
1084
1156
 
1157
+ def create_api_key(
1158
+ self, duration: float, user_id: Optional[str] # noqa: ARG002
1159
+ ) -> ServerSessionToken:
1160
+ api_key = f"{uuid.uuid4()!s}"
1161
+ api_keys = self._api_keys.get(user_id or "usr_1", [])
1162
+ self._api_keys[user_id or "usr_1"] = api_keys + [api_key]
1163
+
1164
+ return ServerSessionToken(server_session_id=api_key)
1165
+
1166
+ def rotate_api_key(self, user_id: str) -> None:
1167
+ if user_id not in self._api_keys:
1168
+ raise ValueError(f"User '{user_id}' not found.")
1169
+ self._api_keys[user_id] = [f"{uuid.uuid4()!s}"]
1170
+
1085
1171
  def admin_batch_create_users(
1086
1172
  self, admin_create_users: List[AdminCreateUser]
1087
1173
  ) -> List[AdminCreatedUser]:
@@ -1106,3 +1192,155 @@ class FakeAnyscaleClient(AnyscaleClientInterface):
1106
1192
  self._users[admin_create_user.email] = created_user
1107
1193
 
1108
1194
  return created_users
1195
+
1196
+ def create_organization_invitations(
1197
+ self, emails: List[str]
1198
+ ) -> Tuple[List[str], List[str]]:
1199
+ success_emails, error_messages = [], []
1200
+ for email in emails:
1201
+ if email in self._users:
1202
+ error_messages.append(
1203
+ f"User with email {email} is already a member of your organization."
1204
+ )
1205
+ else:
1206
+ orginv_id = f"orginv_{uuid.uuid4()!s}"
1207
+ self._organization_invitations[email] = OrganizationInvitation(
1208
+ email=email,
1209
+ id=orginv_id,
1210
+ organization_id="org_1",
1211
+ created_at=datetime.utcnow(),
1212
+ expires_at=datetime.utcnow(),
1213
+ )
1214
+ success_emails.append(email)
1215
+
1216
+ return success_emails, error_messages
1217
+
1218
+ def list_organization_invitations(self) -> List[OrganizationInvitation]:
1219
+ return list(self._organization_invitations.values())
1220
+
1221
+ def delete_organization_invitation(self, email: str) -> OrganizationInvitation:
1222
+ if email not in self._organization_invitations:
1223
+ raise ValueError(f"Invitation for email '{email}' not found.")
1224
+
1225
+ return self._organization_invitations.pop(email)
1226
+
1227
+ def get_organization_collaborators(
1228
+ self,
1229
+ email: Optional[str] = None,
1230
+ name: Optional[str] = None,
1231
+ is_service_account: Optional[bool] = None, # noqa: ARG002
1232
+ ) -> List[OrganizationCollaborator]:
1233
+ # Since organization collaborator doesn't include whether it's a service account or not, we'll just return all
1234
+ results = []
1235
+ for organization_collaborator in self._organization_collaborators:
1236
+ if email and organization_collaborator.email != email:
1237
+ continue
1238
+ if name and organization_collaborator.name != name:
1239
+ continue
1240
+
1241
+ results.append(organization_collaborator)
1242
+
1243
+ return results
1244
+
1245
+ def delete_organization_collaborator(self, identity_id: str) -> None:
1246
+ for organization_collaborator in self._organization_collaborators:
1247
+ if organization_collaborator.id == identity_id:
1248
+ self._organization_collaborators.remove(organization_collaborator)
1249
+ return
1250
+
1251
+ raise ValueError(
1252
+ f"Organization collaborator with id '{identity_id}' not found."
1253
+ )
1254
+
1255
+ def create_service_account(self, name) -> AnyscaleServiceAccount:
1256
+ for organization_collaborator in self._organization_collaborators:
1257
+ if organization_collaborator.name == name:
1258
+ raise ValueError(f"Service account with name '{name}' already exists.")
1259
+
1260
+ identity_id = f"id_{uuid.uuid4()!s}"
1261
+ user_id = f"usr_{uuid.uuid4()!s}"
1262
+ organization_collaborator = OrganizationCollaborator(
1263
+ permission_level=OrganizationPermissionLevel.COLLABORATOR,
1264
+ id=identity_id,
1265
+ name=name,
1266
+ email=f"{name}@service-account.com",
1267
+ user_id=user_id,
1268
+ created_at=datetime.utcnow(),
1269
+ )
1270
+
1271
+ self._organization_collaborators.append((organization_collaborator))
1272
+
1273
+ return AnyscaleServiceAccount(
1274
+ user_id=organization_collaborator.user_id,
1275
+ name=organization_collaborator.name,
1276
+ organization_id="org_1",
1277
+ email=organization_collaborator.email,
1278
+ permission_level=organization_collaborator.permission_level,
1279
+ created_at=organization_collaborator.created_at,
1280
+ )
1281
+
1282
+ def create_resource_quota(
1283
+ self, create_resource_quota: CreateResourceQuota
1284
+ ) -> ResourceQuota:
1285
+ resource_quota_id = f"rq_{uuid.uuid4()!s}"
1286
+ resource_quota = ResourceQuota(
1287
+ id=resource_quota_id,
1288
+ name=create_resource_quota.name,
1289
+ cloud_id=create_resource_quota.cloud_id,
1290
+ project_id=create_resource_quota.project_id,
1291
+ quota=create_resource_quota.quota,
1292
+ is_enabled=True,
1293
+ created_at=datetime.utcnow(),
1294
+ creator=MiniUser(
1295
+ id="user_1",
1296
+ email="test@anyscale.com",
1297
+ name="Test User",
1298
+ username="testuser",
1299
+ ),
1300
+ cloud=MiniCloud(
1301
+ id=create_resource_quota.cloud_id,
1302
+ name="Test Cloud",
1303
+ provider=CloudProviders.AWS,
1304
+ ),
1305
+ )
1306
+
1307
+ self._resource_quotas[resource_quota_id] = resource_quota
1308
+
1309
+ return self._resource_quotas[resource_quota_id]
1310
+
1311
+ def list_resource_quotas(
1312
+ self,
1313
+ name: Optional[str] = None,
1314
+ cloud_id: Optional[str] = None,
1315
+ creator_id: Optional[str] = None,
1316
+ is_enabled: Optional[bool] = None,
1317
+ max_items: int = 20,
1318
+ ) -> List[ResourceQuota]:
1319
+ results = []
1320
+ for resource_quota in self._resource_quotas.values():
1321
+ if name and resource_quota.name != name:
1322
+ continue
1323
+ if cloud_id and resource_quota.cloud_id != cloud_id:
1324
+ continue
1325
+ if creator_id and resource_quota.creator.id != creator_id:
1326
+ continue
1327
+ if is_enabled is not None and resource_quota.is_enabled != is_enabled:
1328
+ continue
1329
+ results.append(resource_quota)
1330
+
1331
+ return results[:max_items]
1332
+
1333
+ def delete_resource_quota(self, resource_quota_id: str) -> None:
1334
+ if resource_quota_id not in self._resource_quotas:
1335
+ raise ValueError(f"Resource Quota with id '{resource_quota_id}' not found.")
1336
+
1337
+ self._resource_quotas.pop(resource_quota_id)
1338
+
1339
+ def set_resource_quota_status(
1340
+ self, resource_quota_id: str, is_enabled: bool
1341
+ ) -> None:
1342
+ resource_quota = self._resource_quotas.get(resource_quota_id)
1343
+ if resource_quota is None:
1344
+ raise ValueError(f"Resource Quota with id '{resource_quota_id}' not found.")
1345
+
1346
+ resource_quota.is_enabled = is_enabled
@@ -1,4 +1,4 @@
1
- Tool to autogenerate documentation for the Anyscale SDK/CLI that can be embedded in a [Docusarus](https://docusaurus.io/) site.
1
+ Tool to autogenerate documentation for the Anyscale SDK/CLI that can be embedded in a [Docusarus](https://docusaurus.io/) site. If you're adding a new API reference in anyscale/product, follow this guide to see what changes you need to make: https://www.notion.so/anyscale-hq/How-to-document-new-anyscale-API-references-173027c809cb8080b8e3e53fc244d70b.
2
2
 
3
3
  This is used by: https://github.com/anyscale/docs/tree/master/docs/reference.
4
4
 
@@ -10,6 +10,10 @@ import anyscale
10
10
  from anyscale import scripts
11
11
  from anyscale._private.docgen.generator import MarkdownGenerator, Module
12
12
  from anyscale.aggregated_instance_usage.models import DownloadCSVFilters
13
+ from anyscale.cloud.models import (
14
+ CloudPermissionLevel,
15
+ CreateCloudCollaborator,
16
+ )
13
17
  from anyscale.commands import (
14
18
  aggregated_instance_usage_commands,
15
19
  cloud_commands,
@@ -22,6 +26,7 @@ from anyscale.commands import (
22
26
  logs_commands,
23
27
  machine_commands,
24
28
  machine_pool_commands,
29
+ organization_invitation_commands,
25
30
  project_commands,
26
31
  resource_quota_commands,
27
32
  schedule_commands,
@@ -58,6 +63,9 @@ from anyscale.llm.model.models import (
58
63
  FineTunedModel,
59
64
  FineTuningType,
60
65
  )
66
+ from anyscale.organization_invitation.models import OrganizationInvitation
67
+ from anyscale.project.models import CreateProjectCollaborator, ProjectPermissionLevel
68
+ from anyscale.resource_quota.models import CreateResourceQuota, Quota, ResourceQuota
61
69
  from anyscale.schedule.models import ScheduleConfig, ScheduleState, ScheduleStatus
62
70
  from anyscale.service.models import (
63
71
  RayGCSExternalStorageConfig,
@@ -68,6 +76,7 @@ from anyscale.service.models import (
68
76
  ServiceVersionStatus,
69
77
  TracingConfig,
70
78
  )
79
+ from anyscale.service_account.models import OrganizationPermissionLevel, ServiceAccount
71
80
  from anyscale.user.models import AdminCreatedUser, AdminCreateUser
72
81
  from anyscale.workspace.models import WorkspaceConfig
73
82
 
@@ -92,6 +101,32 @@ ALL_MODULES = [
92
101
  sdk_commands=[anyscale.user.admin_batch_create,],
93
102
  models=[AdminCreateUser, AdminCreatedUser],
94
103
  ),
104
+ Module(
105
+ title="Project",
106
+ filename="project-api.md",
107
+ cli_prefix="anyscale project",
108
+ cli_commands=[project_commands.add_collaborators,],
109
+ sdk_prefix="anyscale.project",
110
+ sdk_commands=[anyscale.project.add_collaborators,],
111
+ models=[ProjectPermissionLevel, CreateProjectCollaborator],
112
+ legacy_cli_commands=[project_commands.create, project_commands.list,],
113
+ legacy_sdk_commands={
114
+ "create_project": None,
115
+ "delete_project": None,
116
+ "get_default_project": None,
117
+ "get_project": None,
118
+ "search_projects": None,
119
+ "update_project": None,
120
+ },
121
+ legacy_sdk_models=[
122
+ "CreateProject",
123
+ "Project",
124
+ "ProjectListResponse",
125
+ "ProjectResponse",
126
+ "ProjectsQuery",
127
+ "UpdateProject",
128
+ ],
129
+ ),
95
130
  Module(
96
131
  title="Job",
97
132
  filename="job-api.md",
@@ -322,8 +357,14 @@ ALL_MODULES = [
322
357
  service_account_commands.rotate_api_keys,
323
358
  ],
324
359
  sdk_prefix="anyscale.service_account",
325
- sdk_commands=[],
326
- models=[],
360
+ sdk_commands=[
361
+ anyscale.service_account.create,
362
+ anyscale.service_account.create_api_key,
363
+ anyscale.service_account.list,
364
+ anyscale.service_account.delete,
365
+ anyscale.service_account.rotate_api_keys,
366
+ ],
367
+ models=[ServiceAccount, OrganizationPermissionLevel],
327
368
  ),
328
369
  Module(
329
370
  title="Image",
@@ -401,10 +442,11 @@ ALL_MODULES = [
401
442
  cloud_commands.list_cloud,
402
443
  cloud_commands.cloud_config_update,
403
444
  cloud_commands.cloud_set_default,
445
+ cloud_commands.add_collaborators,
404
446
  ],
405
447
  sdk_prefix="anyscale.cloud",
406
- sdk_commands=[],
407
- models=[],
448
+ sdk_commands=[anyscale.cloud.add_collaborators],
449
+ models=[CloudPermissionLevel, CreateCloudCollaborator],
408
450
  cli_command_group_prefix={cloud_commands.cloud_config_update: "config"},
409
451
  legacy_sdk_commands={
410
452
  # limited support, no replacement yet
@@ -580,8 +622,31 @@ ALL_MODULES = [
580
622
  resource_quota_commands.disable,
581
623
  ],
582
624
  sdk_prefix="anyscale.resource_quota",
583
- sdk_commands=[], # No SDK commands for resource quotas
584
- models=[],
625
+ sdk_commands=[
626
+ anyscale.resource_quota.create,
627
+ anyscale.resource_quota.list,
628
+ anyscale.resource_quota.delete,
629
+ anyscale.resource_quota.enable,
630
+ anyscale.resource_quota.disable,
631
+ ],
632
+ models=[CreateResourceQuota, Quota, ResourceQuota],
633
+ ),
634
+ Module(
635
+ title="Organization Invitation",
636
+ filename="organization-invitation.md",
637
+ cli_prefix="anyscale organization-invitation",
638
+ cli_commands=[
639
+ organization_invitation_commands.create,
640
+ organization_invitation_commands.list,
641
+ organization_invitation_commands.delete,
642
+ ],
643
+ sdk_prefix="anyscale.organization-invitation",
644
+ sdk_commands=[
645
+ anyscale.organization_invitation.create,
646
+ anyscale.organization_invitation.list,
647
+ anyscale.organization_invitation.delete,
648
+ ],
649
+ models=[OrganizationInvitation],
585
650
  ),
586
651
  Module(
587
652
  title="Other",
@@ -600,23 +665,14 @@ ALL_MODULES = [
600
665
  legacy_cli_commands=[
601
666
  machine_commands.delete_machine,
602
667
  machine_commands.list_machines,
603
- project_commands.create,
604
- project_commands.list,
605
668
  ],
606
669
  legacy_sdk_commands={
607
670
  "get_organization_temporary_object_storage_credentials": None,
608
671
  "partial_update_organization": None,
609
- "create_project": None,
610
- "delete_project": None,
611
- "get_default_project": None,
612
- "get_project": None,
613
- "search_projects": None,
614
- "update_project": None,
615
672
  "get_runtime_environment": None,
616
673
  "create_session_command": None,
617
674
  "get_session_command": None,
618
675
  "list_session_commands": None,
619
- "get_session_event_log": None,
620
676
  "upsert_sso_config": None,
621
677
  "upsert_test_sso_config": None,
622
678
  },
@@ -630,7 +686,6 @@ ALL_MODULES = [
630
686
  "BuildResponse",
631
687
  "BuildStatus",
632
688
  "CreateBuild",
633
- "CreateProject",
634
689
  "CreateSSOConfig",
635
690
  "GrpcProtocolConfig",
636
691
  "HTTPValidationError",
@@ -647,10 +702,6 @@ ALL_MODULES = [
647
702
  "Organization",
648
703
  "OrganizationResponse",
649
704
  "PageQuery",
650
- "Project",
651
- "ProjectListResponse",
652
- "ProjectResponse",
653
- "ProjectsQuery",
654
705
  "Protocols",
655
706
  "PythonModules",
656
707
  "PythonVersion",
@@ -665,7 +716,6 @@ ALL_MODULES = [
665
716
  "TextQuery",
666
717
  "TracingConfig",
667
718
  "UpdateOrganization",
668
- "UpdateProject",
669
719
  "UserServiceAccessTypes",
670
720
  "WorkerNodeType",
671
721
  ],
@@ -949,6 +949,18 @@ Returns [ProductionjobResponse](./models.md#productionjobresponse)
949
949
 
950
950
  ## Services
951
951
 
952
+ ### archive_service
953
+
954
+ Archives a Service. It is a no-op if already archived.
955
+
956
+ Parameters
957
+
958
+ Name | Type | Description | Notes
959
+ ------------- | ------------- | ------------- | -------------
960
+ `service_id` | str| | Defaults to null
961
+
962
+ Returns void (empty response body)
963
+
952
964
  ### get_service
953
965
 
954
966
  Get a Service
@@ -972,6 +984,7 @@ Name | Type | Description | Notes
972
984
  `project_id` | optional str| project_id to filter by | Defaults to null
973
985
  `name` | optional str| name to filter by | Defaults to null
974
986
  `state_filter` | [List[ServiceEventCurrentState]](./models.md#serviceeventcurrentstate)| A list of Service states to filter by | Defaults to []
987
+ `archive_status` | [ArchiveStatus](./models.md#archivestatus)| The archive status to filter by. Defaults to unarchived. | Defaults to null
975
988
  `creator_id` | optional str| creator_id to filter by | Defaults to null
976
989
  `cloud_id` | optional str| cloud_id to filter by | Defaults to null
977
990
  `sort_field` | [ServiceSortField](./models.md#servicesortfield)| If absent, the default sorting order is 1. status (active first).2. Last updated at (desc). 3. Name (asc). | Defaults to null
@@ -1058,26 +1071,6 @@ Name | Type | Description | Notes
1058
1071
 
1059
1072
  Returns [SessioncommandListResponse](./models.md#sessioncommandlistresponse)
1060
1073
 
1061
- ## Session Events
1062
-
1063
- ### get_session_event_log
1064
-
1065
- Retrieves a session's event log.
1066
-
1067
- Parameters
1068
-
1069
- Name | Type | Description | Notes
1070
- ------------- | ------------- | ------------- | -------------
1071
- `session_id` | str| ID of the Session to retrieve event logs for. | Defaults to null
1072
- `before` | optional datetime| Filters events occurring before this datetime. | Defaults to null
1073
- `after` | optional datetime| Filters events occurring after this datetime. | Defaults to null
1074
- `event_types` | [List[SessionEventTypes]](./models.md#sessioneventtypes)| Filters events to these types. | Defaults to null
1075
- `log_level_types` | [List[LogLevelTypes]](./models.md#logleveltypes)| Filters logs to these leves. | Defaults to null
1076
- `paging_token` | optional str| | Defaults to null
1077
- `count` | optional int| | Defaults to 20
1078
-
1079
- Returns [SessioneventListResponse](./models.md#sessioneventlistresponse)
1080
-
1081
1074
  ## Sso Configs
1082
1075
 
1083
1076
  ### upsert_sso_config
@@ -179,10 +179,11 @@ class MarkdownGenerator:
179
179
  output = f"## {m.title} CLI\n"
180
180
 
181
181
  for t in commands or []:
182
+ cli_command_prefix = cli_prefix
182
183
  if m.cli_command_group_prefix and t in m.cli_command_group_prefix:
183
- cli_prefix = f"{cli_prefix} {m.cli_command_group_prefix[t]}"
184
+ cli_command_prefix = f"{cli_prefix} {m.cli_command_group_prefix[t]}"
184
185
  output += "\n" + self._gen_markdown_for_cli_command(
185
- t, cli_prefix=cli_prefix or ""
186
+ t, cli_prefix=cli_command_prefix or ""
186
187
  )
187
188
 
188
189
  return output