anyscale 0.24.86__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 (1131) hide show
  1. anyscale/__init__.py +181 -0
  2. anyscale/_private/anyscale_client/README.md +16 -0
  3. anyscale/_private/anyscale_client/__init__.py +8 -0
  4. anyscale/_private/anyscale_client/anyscale_client.py +1847 -0
  5. anyscale/_private/anyscale_client/common.py +593 -0
  6. anyscale/_private/anyscale_client/fake_anyscale_client.py +1080 -0
  7. anyscale/_private/docgen/README.md +15 -0
  8. anyscale/_private/docgen/__main__.py +700 -0
  9. anyscale/_private/docgen/api.md +1106 -0
  10. anyscale/_private/docgen/generator.py +559 -0
  11. anyscale/_private/docgen/generator_legacy.py +104 -0
  12. anyscale/_private/docgen/models.md +2261 -0
  13. anyscale/_private/models/__init__.py +2 -0
  14. anyscale/_private/models/image_uri.py +116 -0
  15. anyscale/_private/models/model_base.py +251 -0
  16. anyscale/_private/sdk/__init__.py +102 -0
  17. anyscale/_private/sdk/base_sdk.py +35 -0
  18. anyscale/_private/sdk/timer.py +46 -0
  19. anyscale/_private/utils/__init__.py +0 -0
  20. anyscale/_private/utils/progress_util.py +85 -0
  21. anyscale/_private/workload/__init__.py +2 -0
  22. anyscale/_private/workload/workload_config.py +195 -0
  23. anyscale/_private/workload/workload_sdk.py +324 -0
  24. anyscale/aggregated_instance_usage/__init__.py +36 -0
  25. anyscale/aggregated_instance_usage/_private/aggregated_instance_usage_sdk.py +30 -0
  26. anyscale/aggregated_instance_usage/commands.py +42 -0
  27. anyscale/aggregated_instance_usage/models.py +85 -0
  28. anyscale/anyscale-cloud-setup-gcp-oa.yaml +88 -0
  29. anyscale/anyscale-cloud-setup-gcp.yaml +113 -0
  30. anyscale/anyscale-cloud-setup-oa.yaml +121 -0
  31. anyscale/anyscale-cloud-setup.yaml +327 -0
  32. anyscale/anyscale_pydantic/HISTORY.md +1254 -0
  33. anyscale/anyscale_pydantic/LICENSE +21 -0
  34. anyscale/anyscale_pydantic/PKG-INFO +1351 -0
  35. anyscale/anyscale_pydantic/README.md +7 -0
  36. anyscale/anyscale_pydantic/__init__.py +131 -0
  37. anyscale/anyscale_pydantic/_hypothesis_plugin.py +391 -0
  38. anyscale/anyscale_pydantic/annotated_types.py +72 -0
  39. anyscale/anyscale_pydantic/class_validators.py +361 -0
  40. anyscale/anyscale_pydantic/color.py +494 -0
  41. anyscale/anyscale_pydantic/config.py +191 -0
  42. anyscale/anyscale_pydantic/dataclasses.py +478 -0
  43. anyscale/anyscale_pydantic/datetime_parse.py +248 -0
  44. anyscale/anyscale_pydantic/decorator.py +264 -0
  45. anyscale/anyscale_pydantic/env_settings.py +350 -0
  46. anyscale/anyscale_pydantic/error_wrappers.py +162 -0
  47. anyscale/anyscale_pydantic/errors.py +646 -0
  48. anyscale/anyscale_pydantic/fields.py +1256 -0
  49. anyscale/anyscale_pydantic/generics.py +400 -0
  50. anyscale/anyscale_pydantic/json.py +112 -0
  51. anyscale/anyscale_pydantic/main.py +1109 -0
  52. anyscale/anyscale_pydantic/mypy.py +943 -0
  53. anyscale/anyscale_pydantic/networks.py +739 -0
  54. anyscale/anyscale_pydantic/parse.py +66 -0
  55. anyscale/anyscale_pydantic/py.typed +0 -0
  56. anyscale/anyscale_pydantic/schema.py +1164 -0
  57. anyscale/anyscale_pydantic/tools.py +92 -0
  58. anyscale/anyscale_pydantic/types.py +1206 -0
  59. anyscale/anyscale_pydantic/typing.py +603 -0
  60. anyscale/anyscale_pydantic/utils.py +803 -0
  61. anyscale/anyscale_pydantic/validators.py +765 -0
  62. anyscale/anyscale_pydantic/version.py +38 -0
  63. anyscale/anyscale_schema.json +9 -0
  64. anyscale/api.py +215 -0
  65. anyscale/api_utils/README.md +2 -0
  66. anyscale/api_utils/__init__.py +0 -0
  67. anyscale/api_utils/common_utils.py +81 -0
  68. anyscale/api_utils/exceptions/__init__.py +0 -0
  69. anyscale/api_utils/exceptions/job_errors.py +2 -0
  70. anyscale/api_utils/job_logs_util.py +116 -0
  71. anyscale/api_utils/job_util.py +22 -0
  72. anyscale/api_utils/logs_util.py +61 -0
  73. anyscale/authenticate.py +298 -0
  74. anyscale/aws_iam_policies.py +465 -0
  75. anyscale/background/__init__.py +0 -0
  76. anyscale/background/job_runner.py +64 -0
  77. anyscale/cli_logger.py +378 -0
  78. anyscale/client/.gitignore +66 -0
  79. anyscale/client/.openapi-generator/VERSION +1 -0
  80. anyscale/client/.openapi-generator-ignore +23 -0
  81. anyscale/client/README.md +1070 -0
  82. anyscale/client/git_push.sh +58 -0
  83. anyscale/client/openapi_client/__init__.py +667 -0
  84. anyscale/client/openapi_client/api/__init__.py +6 -0
  85. anyscale/client/openapi_client/api/default_api.py +40922 -0
  86. anyscale/client/openapi_client/api_client.py +647 -0
  87. anyscale/client/openapi_client/configuration.py +373 -0
  88. anyscale/client/openapi_client/exceptions.py +120 -0
  89. anyscale/client/openapi_client/models/__init__.py +652 -0
  90. anyscale/client/openapi_client/models/access_config.py +122 -0
  91. anyscale/client/openapi_client/models/aggregated_instance_usage_with_cost_model.py +733 -0
  92. anyscale/client/openapi_client/models/aggregatedinstanceusagewithcostmodel_list_response.py +147 -0
  93. anyscale/client/openapi_client/models/aica_endpoint.py +527 -0
  94. anyscale/client/openapi_client/models/aica_endpoint_event.py +433 -0
  95. anyscale/client/openapi_client/models/aica_endpoint_event_level.py +103 -0
  96. anyscale/client/openapi_client/models/aica_endpoint_event_type.py +120 -0
  97. anyscale/client/openapi_client/models/aica_endpoint_scope.py +102 -0
  98. anyscale/client/openapi_client/models/aica_model.py +398 -0
  99. anyscale/client/openapi_client/models/aica_model_accelerator_map.py +123 -0
  100. anyscale/client/openapi_client/models/aica_model_configuration.py +209 -0
  101. anyscale/client/openapi_client/models/aica_observability_urls.py +178 -0
  102. anyscale/client/openapi_client/models/aicaendpoint_list_response.py +147 -0
  103. anyscale/client/openapi_client/models/aicaendpoint_response.py +121 -0
  104. anyscale/client/openapi_client/models/aicaendpointevent_list_response.py +147 -0
  105. anyscale/client/openapi_client/models/aicamodel_list_response.py +147 -0
  106. anyscale/client/openapi_client/models/aicamodel_response.py +121 -0
  107. anyscale/client/openapi_client/models/aioa_cloud_waitlist_record.py +254 -0
  108. anyscale/client/openapi_client/models/aioacloudwaitlistrecord_response.py +121 -0
  109. anyscale/client/openapi_client/models/alert_type.py +103 -0
  110. anyscale/client/openapi_client/models/anyscale_aws_account.py +121 -0
  111. anyscale/client/openapi_client/models/anyscale_service_account.py +256 -0
  112. anyscale/client/openapi_client/models/anyscale_version_response.py +121 -0
  113. anyscale/client/openapi_client/models/anyscaleawsaccount_response.py +121 -0
  114. anyscale/client/openapi_client/models/anyscaled_credential_response.py +121 -0
  115. anyscale/client/openapi_client/models/anyscaledcredentialresponse_response.py +121 -0
  116. anyscale/client/openapi_client/models/anyscaleserviceaccount_response.py +121 -0
  117. anyscale/client/openapi_client/models/anyscaleversionresponse_response.py +121 -0
  118. anyscale/client/openapi_client/models/api_key_parameters.py +147 -0
  119. anyscale/client/openapi_client/models/app_config.py +436 -0
  120. anyscale/client/openapi_client/models/app_config_config_schema.py +235 -0
  121. anyscale/client/openapi_client/models/appconfig_list_response.py +147 -0
  122. anyscale/client/openapi_client/models/appconfig_response.py +121 -0
  123. anyscale/client/openapi_client/models/application_type.py +99 -0
  124. anyscale/client/openapi_client/models/applied_snapshot.py +175 -0
  125. anyscale/client/openapi_client/models/apply_production_service_v2_model.py +490 -0
  126. anyscale/client/openapi_client/models/archive_status.py +101 -0
  127. anyscale/client/openapi_client/models/archived_logs_info.py +164 -0
  128. anyscale/client/openapi_client/models/archivedlogsinfo_response.py +121 -0
  129. anyscale/client/openapi_client/models/attach_machine_pool_to_cloud_request.py +152 -0
  130. anyscale/client/openapi_client/models/attachmachinepooltocloudresponse_response.py +121 -0
  131. anyscale/client/openapi_client/models/aviary_model_config_v2.py +358 -0
  132. anyscale/client/openapi_client/models/aws_credentials.py +181 -0
  133. anyscale/client/openapi_client/models/aws_memory_db_cluster_config.py +148 -0
  134. anyscale/client/openapi_client/models/aws_region_and_zones.py +123 -0
  135. anyscale/client/openapi_client/models/aws_region_info.py +152 -0
  136. anyscale/client/openapi_client/models/awsregionandzones_response.py +121 -0
  137. anyscale/client/openapi_client/models/bank_account_information.py +239 -0
  138. anyscale/client/openapi_client/models/base_job_status.py +105 -0
  139. anyscale/client/openapi_client/models/baseimagesenum.py +2130 -0
  140. anyscale/client/openapi_client/models/batch_response_batched_result_organization_invitation_base.py +121 -0
  141. anyscale/client/openapi_client/models/batched_result_organization_invitation_base.py +173 -0
  142. anyscale/client/openapi_client/models/billing_information.py +181 -0
  143. anyscale/client/openapi_client/models/billing_version_code.py +100 -0
  144. anyscale/client/openapi_client/models/body_aws_marketplace_registration_api_v2_organization_billing_aws_marketplace_registration_post.py +121 -0
  145. anyscale/client/openapi_client/models/buffer_registration.py +285 -0
  146. anyscale/client/openapi_client/models/build.py +607 -0
  147. anyscale/client/openapi_client/models/build_log_response.py +123 -0
  148. anyscale/client/openapi_client/models/build_registration.py +285 -0
  149. anyscale/client/openapi_client/models/build_response.py +121 -0
  150. anyscale/client/openapi_client/models/build_status.py +104 -0
  151. anyscale/client/openapi_client/models/buildlogresponse_response.py +121 -0
  152. anyscale/client/openapi_client/models/card.py +181 -0
  153. anyscale/client/openapi_client/models/card_id.py +108 -0
  154. anyscale/client/openapi_client/models/card_list_response.py +147 -0
  155. anyscale/client/openapi_client/models/change_password_params.py +148 -0
  156. anyscale/client/openapi_client/models/cleanup_leaked_grafana_dashboard_response.py +208 -0
  157. anyscale/client/openapi_client/models/cleanupleakedgrafanadashboardresponse_response.py +121 -0
  158. anyscale/client/openapi_client/models/clone_experimental_workspace.py +151 -0
  159. anyscale/client/openapi_client/models/cloud.py +802 -0
  160. anyscale/client/openapi_client/models/cloud_analytics_event.py +351 -0
  161. anyscale/client/openapi_client/models/cloud_analytics_event_cloud_provider_error.py +152 -0
  162. anyscale/client/openapi_client/models/cloud_analytics_event_cloud_resource.py +117 -0
  163. anyscale/client/openapi_client/models/cloud_analytics_event_command_name.py +103 -0
  164. anyscale/client/openapi_client/models/cloud_analytics_event_error.py +150 -0
  165. anyscale/client/openapi_client/models/cloud_analytics_event_name.py +109 -0
  166. anyscale/client/openapi_client/models/cloud_collaborator.py +175 -0
  167. anyscale/client/openapi_client/models/cloud_collaborator_value.py +177 -0
  168. anyscale/client/openapi_client/models/cloud_collaborators_query.py +122 -0
  169. anyscale/client/openapi_client/models/cloud_config.py +206 -0
  170. anyscale/client/openapi_client/models/cloud_data_bucket_access_mode.py +100 -0
  171. anyscale/client/openapi_client/models/cloud_data_bucket_file_type.py +102 -0
  172. anyscale/client/openapi_client/models/cloud_data_bucket_presigned_upload_info.py +268 -0
  173. anyscale/client/openapi_client/models/cloud_data_bucket_presigned_upload_request.py +152 -0
  174. anyscale/client/openapi_client/models/cloud_data_bucket_presigned_upload_scheme.py +100 -0
  175. anyscale/client/openapi_client/models/cloud_data_bucket_presigned_url_request.py +209 -0
  176. anyscale/client/openapi_client/models/cloud_data_bucket_presigned_url_response.py +296 -0
  177. anyscale/client/openapi_client/models/cloud_data_bucket_presigned_url_scheme.py +100 -0
  178. anyscale/client/openapi_client/models/cloud_data_bucket_request_scope.py +100 -0
  179. anyscale/client/openapi_client/models/cloud_hosting_type.py +100 -0
  180. anyscale/client/openapi_client/models/cloud_list_response.py +147 -0
  181. anyscale/client/openapi_client/models/cloud_name_options.py +121 -0
  182. anyscale/client/openapi_client/models/cloud_overview_dashboard.py +175 -0
  183. anyscale/client/openapi_client/models/cloud_project_collaborator.py +175 -0
  184. anyscale/client/openapi_client/models/cloud_project_collaborator_value.py +121 -0
  185. anyscale/client/openapi_client/models/cloud_provider.py +102 -0
  186. anyscale/client/openapi_client/models/cloud_providers.py +103 -0
  187. anyscale/client/openapi_client/models/cloud_region_and_zones.py +123 -0
  188. anyscale/client/openapi_client/models/cloud_region_info.py +152 -0
  189. anyscale/client/openapi_client/models/cloud_resource.py +740 -0
  190. anyscale/client/openapi_client/models/cloud_resource_gcp.py +691 -0
  191. anyscale/client/openapi_client/models/cloud_response.py +121 -0
  192. anyscale/client/openapi_client/models/cloud_state.py +104 -0
  193. anyscale/client/openapi_client/models/cloud_status.py +100 -0
  194. anyscale/client/openapi_client/models/cloud_type.py +100 -0
  195. anyscale/client/openapi_client/models/cloud_types.py +100 -0
  196. anyscale/client/openapi_client/models/cloud_version.py +100 -0
  197. anyscale/client/openapi_client/models/cloud_waitlist_status.py +102 -0
  198. anyscale/client/openapi_client/models/cloud_with_cloud_resource.py +830 -0
  199. anyscale/client/openapi_client/models/cloud_with_cloud_resource_gcp.py +830 -0
  200. anyscale/client/openapi_client/models/cloudcollaborator_list_response.py +147 -0
  201. anyscale/client/openapi_client/models/clouddatabucketpresigneduploadinfo_response.py +121 -0
  202. anyscale/client/openapi_client/models/clouddatabucketpresignedurlresponse_response.py +121 -0
  203. anyscale/client/openapi_client/models/cloudoverviewdashboard_response.py +121 -0
  204. anyscale/client/openapi_client/models/cloudregionandzones_response.py +121 -0
  205. anyscale/client/openapi_client/models/cloudresource_response.py +121 -0
  206. anyscale/client/openapi_client/models/cloudresourcegcp_response.py +121 -0
  207. anyscale/client/openapi_client/models/cloudwithcloudresource_response.py +121 -0
  208. anyscale/client/openapi_client/models/cloudwithcloudresourcegcp_response.py +121 -0
  209. anyscale/client/openapi_client/models/cluster_auth_response.py +148 -0
  210. anyscale/client/openapi_client/models/cluster_config.py +178 -0
  211. anyscale/client/openapi_client/models/cluster_config_with_session_idle_timeout.py +204 -0
  212. anyscale/client/openapi_client/models/cluster_environments_query.py +290 -0
  213. anyscale/client/openapi_client/models/cluster_event.py +174 -0
  214. anyscale/client/openapi_client/models/cluster_events_output.py +175 -0
  215. anyscale/client/openapi_client/models/cluster_features.py +152 -0
  216. anyscale/client/openapi_client/models/cluster_management_stack_versions.py +100 -0
  217. anyscale/client/openapi_client/models/cluster_startup.py +208 -0
  218. anyscale/client/openapi_client/models/cluster_status.py +104 -0
  219. anyscale/client/openapi_client/models/cluster_status_details.py +100 -0
  220. anyscale/client/openapi_client/models/clusterauthresponse_response.py +121 -0
  221. anyscale/client/openapi_client/models/clusterconfig_response.py +121 -0
  222. anyscale/client/openapi_client/models/clusterconfigwithsessionidletimeout_response.py +121 -0
  223. anyscale/client/openapi_client/models/clustereventsoutput_response.py +121 -0
  224. anyscale/client/openapi_client/models/clusterfeatures_response.py +121 -0
  225. anyscale/client/openapi_client/models/company_size.py +103 -0
  226. anyscale/client/openapi_client/models/compute_node_type.py +292 -0
  227. anyscale/client/openapi_client/models/compute_stack.py +100 -0
  228. anyscale/client/openapi_client/models/compute_template.py +415 -0
  229. anyscale/client/openapi_client/models/compute_template_config.py +461 -0
  230. anyscale/client/openapi_client/models/compute_template_query.py +316 -0
  231. anyscale/client/openapi_client/models/computetemplate_response.py +121 -0
  232. anyscale/client/openapi_client/models/computetemplateconfig_response.py +121 -0
  233. anyscale/client/openapi_client/models/create_aica_endpoint.py +210 -0
  234. anyscale/client/openapi_client/models/create_aioa_cloud_waitlist.py +173 -0
  235. anyscale/client/openapi_client/models/create_analytics_event.py +122 -0
  236. anyscale/client/openapi_client/models/create_app_config.py +235 -0
  237. anyscale/client/openapi_client/models/create_app_config_configuration_schema.py +235 -0
  238. anyscale/client/openapi_client/models/create_billing_version.py +181 -0
  239. anyscale/client/openapi_client/models/create_bug_report_response.py +152 -0
  240. anyscale/client/openapi_client/models/create_build.py +263 -0
  241. anyscale/client/openapi_client/models/create_byod_app_config.py +180 -0
  242. anyscale/client/openapi_client/models/create_byod_app_config_configuration_schema.py +206 -0
  243. anyscale/client/openapi_client/models/create_byod_build.py +152 -0
  244. anyscale/client/openapi_client/models/create_cloud_collaborator.py +148 -0
  245. anyscale/client/openapi_client/models/create_cloud_resource.py +682 -0
  246. anyscale/client/openapi_client/models/create_cloud_resource_gcp.py +633 -0
  247. anyscale/client/openapi_client/models/create_cloud_with_cloud_resource.py +546 -0
  248. anyscale/client/openapi_client/models/create_cluster_compute_config.py +463 -0
  249. anyscale/client/openapi_client/models/create_compute_template.py +229 -0
  250. anyscale/client/openapi_client/models/create_compute_template_config.py +464 -0
  251. anyscale/client/openapi_client/models/create_dataset.py +200 -0
  252. anyscale/client/openapi_client/models/create_experimental_workspace.py +435 -0
  253. anyscale/client/openapi_client/models/create_experimental_workspace_from_job.py +123 -0
  254. anyscale/client/openapi_client/models/create_fine_tuning_hyperparameters.py +156 -0
  255. anyscale/client/openapi_client/models/create_fine_tuning_job_product_request.py +353 -0
  256. anyscale/client/openapi_client/models/create_instance_usage_budget.py +253 -0
  257. anyscale/client/openapi_client/models/create_internal_production_job.py +262 -0
  258. anyscale/client/openapi_client/models/create_job_queue_config.py +206 -0
  259. anyscale/client/openapi_client/models/create_job_queue_requests.py +323 -0
  260. anyscale/client/openapi_client/models/create_machine_pool_request.py +151 -0
  261. anyscale/client/openapi_client/models/create_machine_pool_response.py +123 -0
  262. anyscale/client/openapi_client/models/create_machine_request.py +151 -0
  263. anyscale/client/openapi_client/models/create_machine_response.py +123 -0
  264. anyscale/client/openapi_client/models/create_metronome_webhook_notification.py +175 -0
  265. anyscale/client/openapi_client/models/create_notification_channel_record.py +146 -0
  266. anyscale/client/openapi_client/models/create_organization_configuration.py +199 -0
  267. anyscale/client/openapi_client/models/create_organization_invitation.py +121 -0
  268. anyscale/client/openapi_client/models/create_otp_return_api_model.py +148 -0
  269. anyscale/client/openapi_client/models/create_production_job_config.py +347 -0
  270. anyscale/client/openapi_client/models/create_resource_quota.py +293 -0
  271. anyscale/client/openapi_client/models/create_schedule.py +263 -0
  272. anyscale/client/openapi_client/models/create_session_from_snapshot_options.py +565 -0
  273. anyscale/client/openapi_client/models/create_session_in_db.py +434 -0
  274. anyscale/client/openapi_client/models/create_session_response.py +174 -0
  275. anyscale/client/openapi_client/models/create_user.py +439 -0
  276. anyscale/client/openapi_client/models/create_user_project_collaborator.py +148 -0
  277. anyscale/client/openapi_client/models/create_user_project_collaborator_value.py +121 -0
  278. anyscale/client/openapi_client/models/create_workspace_from_template.py +263 -0
  279. anyscale/client/openapi_client/models/createbugreportresponse_response.py +121 -0
  280. anyscale/client/openapi_client/models/createcomputetemplateconfig_response.py +121 -0
  281. anyscale/client/openapi_client/models/createmachinepoolresponse_response.py +121 -0
  282. anyscale/client/openapi_client/models/createmachineresponse_response.py +121 -0
  283. anyscale/client/openapi_client/models/createotpreturnapimodel_response.py +121 -0
  284. anyscale/client/openapi_client/models/createsessionresponse_response.py +121 -0
  285. anyscale/client/openapi_client/models/credit_card_information.py +268 -0
  286. anyscale/client/openapi_client/models/customer_alert_status.py +101 -0
  287. anyscale/client/openapi_client/models/customer_billing_type.py +101 -0
  288. anyscale/client/openapi_client/models/dataplane_services.py +102 -0
  289. anyscale/client/openapi_client/models/dataset.py +416 -0
  290. anyscale/client/openapi_client/models/dataset_list_response.py +150 -0
  291. anyscale/client/openapi_client/models/dataset_response.py +121 -0
  292. anyscale/client/openapi_client/models/dataset_upload.py +148 -0
  293. anyscale/client/openapi_client/models/datasetupload_response.py +121 -0
  294. anyscale/client/openapi_client/models/decorated_application_template.py +493 -0
  295. anyscale/client/openapi_client/models/decorated_build.py +664 -0
  296. anyscale/client/openapi_client/models/decorated_compute_template.py +446 -0
  297. anyscale/client/openapi_client/models/decorated_compute_template_config.py +490 -0
  298. anyscale/client/openapi_client/models/decorated_interactive_session.py +793 -0
  299. anyscale/client/openapi_client/models/decorated_job.py +793 -0
  300. anyscale/client/openapi_client/models/decorated_job_queue.py +639 -0
  301. anyscale/client/openapi_client/models/decorated_job_submission.py +575 -0
  302. anyscale/client/openapi_client/models/decorated_list_service_api_model.py +670 -0
  303. anyscale/client/openapi_client/models/decorated_production_job.py +805 -0
  304. anyscale/client/openapi_client/models/decorated_production_job_state_transition.py +319 -0
  305. anyscale/client/openapi_client/models/decorated_production_service_v2_api_model.py +641 -0
  306. anyscale/client/openapi_client/models/decorated_production_service_v2_version_api_model.py +437 -0
  307. anyscale/client/openapi_client/models/decorated_runtime_env.py +488 -0
  308. anyscale/client/openapi_client/models/decorated_schedule.py +552 -0
  309. anyscale/client/openapi_client/models/decorated_serve_deployment.py +711 -0
  310. anyscale/client/openapi_client/models/decorated_service_event_api_model.py +513 -0
  311. anyscale/client/openapi_client/models/decorated_session.py +1789 -0
  312. anyscale/client/openapi_client/models/decorated_support_request.py +283 -0
  313. anyscale/client/openapi_client/models/decorated_unified_job.py +466 -0
  314. anyscale/client/openapi_client/models/decoratedapplicationtemplate_list_response.py +147 -0
  315. anyscale/client/openapi_client/models/decoratedapplicationtemplate_response.py +121 -0
  316. anyscale/client/openapi_client/models/decoratedbuild_list_response.py +147 -0
  317. anyscale/client/openapi_client/models/decoratedbuild_response.py +121 -0
  318. anyscale/client/openapi_client/models/decoratedcomputetemplate_list_response.py +147 -0
  319. anyscale/client/openapi_client/models/decoratedcomputetemplate_response.py +121 -0
  320. anyscale/client/openapi_client/models/decoratedinteractivesession_list_response.py +147 -0
  321. anyscale/client/openapi_client/models/decoratedinteractivesession_response.py +121 -0
  322. anyscale/client/openapi_client/models/decoratedjob_list_response.py +147 -0
  323. anyscale/client/openapi_client/models/decoratedjob_response.py +121 -0
  324. anyscale/client/openapi_client/models/decoratedjobqueue_list_response.py +147 -0
  325. anyscale/client/openapi_client/models/decoratedjobqueue_response.py +121 -0
  326. anyscale/client/openapi_client/models/decoratedjobsubmission_list_response.py +147 -0
  327. anyscale/client/openapi_client/models/decoratedjobsubmission_response.py +121 -0
  328. anyscale/client/openapi_client/models/decoratedlistserviceapimodel_list_response.py +147 -0
  329. anyscale/client/openapi_client/models/decoratedproductionjob_list_response.py +147 -0
  330. anyscale/client/openapi_client/models/decoratedproductionjob_response.py +121 -0
  331. anyscale/client/openapi_client/models/decoratedproductionjobstatetransition_list_response.py +147 -0
  332. anyscale/client/openapi_client/models/decoratedproductionservicev2_apimodel_response.py +121 -0
  333. anyscale/client/openapi_client/models/decoratedproductionservicev2_versionapimodel_list_response.py +147 -0
  334. anyscale/client/openapi_client/models/decoratedruntimeenv_list_response.py +147 -0
  335. anyscale/client/openapi_client/models/decoratedruntimeenv_response.py +121 -0
  336. anyscale/client/openapi_client/models/decoratedschedule_list_response.py +147 -0
  337. anyscale/client/openapi_client/models/decoratedschedule_response.py +121 -0
  338. anyscale/client/openapi_client/models/decoratedservedeployment_list_response.py +147 -0
  339. anyscale/client/openapi_client/models/decoratedservedeployment_response.py +121 -0
  340. anyscale/client/openapi_client/models/decoratedserviceeventapimodel_list_response.py +147 -0
  341. anyscale/client/openapi_client/models/decoratedsession_list_response.py +147 -0
  342. anyscale/client/openapi_client/models/decoratedsession_response.py +121 -0
  343. anyscale/client/openapi_client/models/decoratedsupportrequest_list_response.py +147 -0
  344. anyscale/client/openapi_client/models/decoratedsupportrequest_response.py +121 -0
  345. anyscale/client/openapi_client/models/decoratedunifiedjob_list_response.py +147 -0
  346. anyscale/client/openapi_client/models/decoratedunifiedjob_response.py +121 -0
  347. anyscale/client/openapi_client/models/delete_machine_pool_request.py +123 -0
  348. anyscale/client/openapi_client/models/delete_machine_request.py +206 -0
  349. anyscale/client/openapi_client/models/deleted_platform_fine_tuned_model.py +148 -0
  350. anyscale/client/openapi_client/models/deletedplatformfinetunedmodel_response.py +121 -0
  351. anyscale/client/openapi_client/models/deletemachinepoolresponse_response.py +121 -0
  352. anyscale/client/openapi_client/models/detach_machine_pool_from_cloud_request.py +152 -0
  353. anyscale/client/openapi_client/models/detachmachinepoolfromcloudresponse_response.py +121 -0
  354. anyscale/client/openapi_client/models/dismissal_type.py +100 -0
  355. anyscale/client/openapi_client/models/editable_cloud_resource.py +206 -0
  356. anyscale/client/openapi_client/models/editable_cloud_resource_gcp.py +178 -0
  357. anyscale/client/openapi_client/models/error.py +174 -0
  358. anyscale/client/openapi_client/models/event_level.py +104 -0
  359. anyscale/client/openapi_client/models/execute_command_response.py +175 -0
  360. anyscale/client/openapi_client/models/execute_interactive_command_options.py +147 -0
  361. anyscale/client/openapi_client/models/execute_shell_command_options.py +121 -0
  362. anyscale/client/openapi_client/models/executecommandresponse_response.py +121 -0
  363. anyscale/client/openapi_client/models/experimental_workspace.py +748 -0
  364. anyscale/client/openapi_client/models/experimental_workspaces_sort_field.py +100 -0
  365. anyscale/client/openapi_client/models/experimentalworkspace_list_response.py +147 -0
  366. anyscale/client/openapi_client/models/experimentalworkspace_response.py +121 -0
  367. anyscale/client/openapi_client/models/external_service_status.py +147 -0
  368. anyscale/client/openapi_client/models/external_service_status_response.py +250 -0
  369. anyscale/client/openapi_client/models/external_terminal_command.py +280 -0
  370. anyscale/client/openapi_client/models/externalservicestatusresponse_response.py +121 -0
  371. anyscale/client/openapi_client/models/feature_compatibility.py +152 -0
  372. anyscale/client/openapi_client/models/feature_flag_response.py +121 -0
  373. anyscale/client/openapi_client/models/featureflagresponse_response.py +121 -0
  374. anyscale/client/openapi_client/models/fine_tune_type.py +100 -0
  375. anyscale/client/openapi_client/models/fine_tuned_model.py +412 -0
  376. anyscale/client/openapi_client/models/fine_tuning_job_status.py +103 -0
  377. anyscale/client/openapi_client/models/finetunedmodel_list_response.py +147 -0
  378. anyscale/client/openapi_client/models/finetunedmodel_response.py +121 -0
  379. anyscale/client/openapi_client/models/finish_ft_job_request.py +204 -0
  380. anyscale/client/openapi_client/models/finish_ft_job_request_v2.py +183 -0
  381. anyscale/client/openapi_client/models/gcp_file_store_config.py +175 -0
  382. anyscale/client/openapi_client/models/gcp_memorystore_instance_config.py +148 -0
  383. anyscale/client/openapi_client/models/grafana_dashboard.py +201 -0
  384. anyscale/client/openapi_client/models/grpc_protocol_config.py +178 -0
  385. anyscale/client/openapi_client/models/ha_job_error_types.py +103 -0
  386. anyscale/client/openapi_client/models/ha_job_event_level.py +101 -0
  387. anyscale/client/openapi_client/models/ha_job_event_origin.py +100 -0
  388. anyscale/client/openapi_client/models/ha_job_goal_states.py +102 -0
  389. anyscale/client/openapi_client/models/ha_job_states.py +109 -0
  390. anyscale/client/openapi_client/models/ha_job_type.py +100 -0
  391. anyscale/client/openapi_client/models/ha_jobs_sort_field.py +105 -0
  392. anyscale/client/openapi_client/models/head_ip.py +121 -0
  393. anyscale/client/openapi_client/models/headip_response.py +121 -0
  394. anyscale/client/openapi_client/models/http_protocol_config.py +150 -0
  395. anyscale/client/openapi_client/models/http_validation_error.py +120 -0
  396. anyscale/client/openapi_client/models/idle_termination_status.py +104 -0
  397. anyscale/client/openapi_client/models/import_aica_model.py +241 -0
  398. anyscale/client/openapi_client/models/instance_usage_budget.py +572 -0
  399. anyscale/client/openapi_client/models/instance_usage_budget_evaluation_period.py +100 -0
  400. anyscale/client/openapi_client/models/instanceusagebudget_list_response.py +147 -0
  401. anyscale/client/openapi_client/models/instanceusagebudget_response.py +121 -0
  402. anyscale/client/openapi_client/models/integration_details.py +120 -0
  403. anyscale/client/openapi_client/models/interactive_session_logs.py +152 -0
  404. anyscale/client/openapi_client/models/interactivesessionlogs_response.py +121 -0
  405. anyscale/client/openapi_client/models/internal_production_job.py +663 -0
  406. anyscale/client/openapi_client/models/internalproductionjob_response.py +121 -0
  407. anyscale/client/openapi_client/models/invoice.py +413 -0
  408. anyscale/client/openapi_client/models/invoice_list_response.py +147 -0
  409. anyscale/client/openapi_client/models/invoice_status.py +102 -0
  410. anyscale/client/openapi_client/models/invoices_query.py +150 -0
  411. anyscale/client/openapi_client/models/job_access.py +102 -0
  412. anyscale/client/openapi_client/models/job_queue.py +467 -0
  413. anyscale/client/openapi_client/models/job_queue_config.py +122 -0
  414. anyscale/client/openapi_client/models/job_queue_execution_mode.py +101 -0
  415. anyscale/client/openapi_client/models/job_queue_spec.py +263 -0
  416. anyscale/client/openapi_client/models/job_queue_state.py +100 -0
  417. anyscale/client/openapi_client/models/job_queues_query.py +262 -0
  418. anyscale/client/openapi_client/models/job_run_type.py +101 -0
  419. anyscale/client/openapi_client/models/job_state_log_level_types.py +100 -0
  420. anyscale/client/openapi_client/models/job_status.py +105 -0
  421. anyscale/client/openapi_client/models/job_submissions_sort_field.py +101 -0
  422. anyscale/client/openapi_client/models/jobqueue_response.py +121 -0
  423. anyscale/client/openapi_client/models/jobs_logs.py +152 -0
  424. anyscale/client/openapi_client/models/jobs_logs_query_info.py +181 -0
  425. anyscale/client/openapi_client/models/jobs_sort_field.py +104 -0
  426. anyscale/client/openapi_client/models/jobslogs_response.py +121 -0
  427. anyscale/client/openapi_client/models/jobslogsqueryinfo_response.py +121 -0
  428. anyscale/client/openapi_client/models/json_patch_operation.py +200 -0
  429. anyscale/client/openapi_client/models/kubernetes_manager_registration_request.py +123 -0
  430. anyscale/client/openapi_client/models/kubernetes_manager_registration_response.py +123 -0
  431. anyscale/client/openapi_client/models/kubernetesmanagerregistrationresponse_response.py +121 -0
  432. anyscale/client/openapi_client/models/lb_resource.py +123 -0
  433. anyscale/client/openapi_client/models/lbresource_response.py +121 -0
  434. anyscale/client/openapi_client/models/list_machine_pools_response.py +123 -0
  435. anyscale/client/openapi_client/models/list_machines_response.py +121 -0
  436. anyscale/client/openapi_client/models/list_resource_quotas_query.py +234 -0
  437. anyscale/client/openapi_client/models/list_response_metadata.py +146 -0
  438. anyscale/client/openapi_client/models/listmachinepoolsresponse_response.py +121 -0
  439. anyscale/client/openapi_client/models/listmachinesresponse_response.py +121 -0
  440. anyscale/client/openapi_client/models/log_detail.py +187 -0
  441. anyscale/client/openapi_client/models/log_details.py +151 -0
  442. anyscale/client/openapi_client/models/log_download_config.py +206 -0
  443. anyscale/client/openapi_client/models/log_download_request.py +150 -0
  444. anyscale/client/openapi_client/models/log_download_result.py +207 -0
  445. anyscale/client/openapi_client/models/log_file_chunk.py +439 -0
  446. anyscale/client/openapi_client/models/log_filter.py +430 -0
  447. anyscale/client/openapi_client/models/log_item.py +181 -0
  448. anyscale/client/openapi_client/models/log_item_batch.py +151 -0
  449. anyscale/client/openapi_client/models/log_level_types.py +100 -0
  450. anyscale/client/openapi_client/models/log_stream.py +151 -0
  451. anyscale/client/openapi_client/models/logdetails_response.py +121 -0
  452. anyscale/client/openapi_client/models/logdownloadresult_response.py +121 -0
  453. anyscale/client/openapi_client/models/login_user_params.py +205 -0
  454. anyscale/client/openapi_client/models/logitembatch_response.py +121 -0
  455. anyscale/client/openapi_client/models/logs_output.py +202 -0
  456. anyscale/client/openapi_client/models/logsoutput_response.py +121 -0
  457. anyscale/client/openapi_client/models/logstream_response.py +121 -0
  458. anyscale/client/openapi_client/models/long_running_workload.py +256 -0
  459. anyscale/client/openapi_client/models/longrunningworkload_list_response.py +147 -0
  460. anyscale/client/openapi_client/models/machine_allocation_state.py +100 -0
  461. anyscale/client/openapi_client/models/machine_connection_state.py +100 -0
  462. anyscale/client/openapi_client/models/machine_info.py +466 -0
  463. anyscale/client/openapi_client/models/machine_pool.py +266 -0
  464. anyscale/client/openapi_client/models/metronome_customer_info_model.py +148 -0
  465. anyscale/client/openapi_client/models/metronome_dashboard_type.py +101 -0
  466. anyscale/client/openapi_client/models/metronomecustomerinfomodel_list_response.py +147 -0
  467. anyscale/client/openapi_client/models/metronomecustomerinfomodel_response.py +121 -0
  468. anyscale/client/openapi_client/models/mini_build.py +267 -0
  469. anyscale/client/openapi_client/models/mini_cloud.py +321 -0
  470. anyscale/client/openapi_client/models/mini_cluster.py +148 -0
  471. anyscale/client/openapi_client/models/mini_compute_template.py +228 -0
  472. anyscale/client/openapi_client/models/mini_compute_template_config.py +121 -0
  473. anyscale/client/openapi_client/models/mini_job_run.py +599 -0
  474. anyscale/client/openapi_client/models/mini_namespace.py +148 -0
  475. anyscale/client/openapi_client/models/mini_organization.py +148 -0
  476. anyscale/client/openapi_client/models/mini_production_job.py +202 -0
  477. anyscale/client/openapi_client/models/mini_project.py +205 -0
  478. anyscale/client/openapi_client/models/mini_runtime_environment.py +147 -0
  479. anyscale/client/openapi_client/models/mini_schedule.py +180 -0
  480. anyscale/client/openapi_client/models/mini_user.py +266 -0
  481. anyscale/client/openapi_client/models/minibuild_list_response.py +147 -0
  482. anyscale/client/openapi_client/models/minicomputetemplate_list_response.py +147 -0
  483. anyscale/client/openapi_client/models/miniproject_list_response.py +147 -0
  484. anyscale/client/openapi_client/models/monitor_logs_extension.py +100 -0
  485. anyscale/client/openapi_client/models/named_entity.py +148 -0
  486. anyscale/client/openapi_client/models/nfs_mount_target.py +151 -0
  487. anyscale/client/openapi_client/models/node_registration_aws.py +152 -0
  488. anyscale/client/openapi_client/models/node_registration_gcp.py +123 -0
  489. anyscale/client/openapi_client/models/node_registration_k8_s.py +178 -0
  490. anyscale/client/openapi_client/models/node_registration_provisioned.py +150 -0
  491. anyscale/client/openapi_client/models/node_registration_v2.py +279 -0
  492. anyscale/client/openapi_client/models/node_type.py +100 -0
  493. anyscale/client/openapi_client/models/notification_channel_email_config.py +121 -0
  494. anyscale/client/openapi_client/models/notification_channel_webhook_config.py +121 -0
  495. anyscale/client/openapi_client/models/onboarding_user_cards_query.py +122 -0
  496. anyscale/client/openapi_client/models/organization.py +490 -0
  497. anyscale/client/openapi_client/models/organization_availability.py +148 -0
  498. anyscale/client/openapi_client/models/organization_collaborator.py +259 -0
  499. anyscale/client/openapi_client/models/organization_configuration.py +280 -0
  500. anyscale/client/openapi_client/models/organization_configuration_response.py +227 -0
  501. anyscale/client/openapi_client/models/organization_invitation.py +255 -0
  502. anyscale/client/openapi_client/models/organization_invitation_base.py +121 -0
  503. anyscale/client/openapi_client/models/organization_marketing_questions.py +198 -0
  504. anyscale/client/openapi_client/models/organization_permission_level.py +100 -0
  505. anyscale/client/openapi_client/models/organization_project_collaborator.py +175 -0
  506. anyscale/client/openapi_client/models/organization_project_collaborator_value.py +148 -0
  507. anyscale/client/openapi_client/models/organization_public_identifier.py +121 -0
  508. anyscale/client/openapi_client/models/organization_response.py +121 -0
  509. anyscale/client/openapi_client/models/organization_summary.py +229 -0
  510. anyscale/client/openapi_client/models/organization_usage_alert.py +210 -0
  511. anyscale/client/openapi_client/models/organization_usage_alert_severity.py +100 -0
  512. anyscale/client/openapi_client/models/organizationavailability_response.py +121 -0
  513. anyscale/client/openapi_client/models/organizationcollaborator_list_response.py +147 -0
  514. anyscale/client/openapi_client/models/organizationconfiguration_list_response.py +147 -0
  515. anyscale/client/openapi_client/models/organizationconfigurationresponse_response.py +121 -0
  516. anyscale/client/openapi_client/models/organizationinvitation_list_response.py +147 -0
  517. anyscale/client/openapi_client/models/organizationinvitation_response.py +121 -0
  518. anyscale/client/openapi_client/models/organizationinvitationbase_response.py +121 -0
  519. anyscale/client/openapi_client/models/organizationprojectcollaborator_list_response.py +147 -0
  520. anyscale/client/openapi_client/models/organizationpublicidentifier_response.py +121 -0
  521. anyscale/client/openapi_client/models/organizationusagealert_list_response.py +147 -0
  522. anyscale/client/openapi_client/models/page_query.py +153 -0
  523. anyscale/client/openapi_client/models/pause_schedule.py +123 -0
  524. anyscale/client/openapi_client/models/permission_level.py +101 -0
  525. anyscale/client/openapi_client/models/platform_fine_tuning_job.py +577 -0
  526. anyscale/client/openapi_client/models/platformfinetuningjob_list_response.py +147 -0
  527. anyscale/client/openapi_client/models/platformfinetuningjob_response.py +121 -0
  528. anyscale/client/openapi_client/models/product_autoscaler_flag.py +122 -0
  529. anyscale/client/openapi_client/models/product_type.py +100 -0
  530. anyscale/client/openapi_client/models/productautoscalerflag_response.py +121 -0
  531. anyscale/client/openapi_client/models/production_job.py +437 -0
  532. anyscale/client/openapi_client/models/production_job_config.py +348 -0
  533. anyscale/client/openapi_client/models/production_job_event.py +378 -0
  534. anyscale/client/openapi_client/models/production_job_event_scope_filter.py +101 -0
  535. anyscale/client/openapi_client/models/production_job_state_transition.py +293 -0
  536. anyscale/client/openapi_client/models/productionjob_response.py +121 -0
  537. anyscale/client/openapi_client/models/productionjobevent_list_response.py +147 -0
  538. anyscale/client/openapi_client/models/project.py +554 -0
  539. anyscale/client/openapi_client/models/project_base.py +121 -0
  540. anyscale/client/openapi_client/models/project_collaborator.py +175 -0
  541. anyscale/client/openapi_client/models/project_collaborator_value.py +175 -0
  542. anyscale/client/openapi_client/models/project_collaborators_put_message.py +121 -0
  543. anyscale/client/openapi_client/models/project_create_message.py +148 -0
  544. anyscale/client/openapi_client/models/project_default_session_name.py +121 -0
  545. anyscale/client/openapi_client/models/project_delete_message.py +121 -0
  546. anyscale/client/openapi_client/models/project_list_response.py +147 -0
  547. anyscale/client/openapi_client/models/project_patch_message.py +121 -0
  548. anyscale/client/openapi_client/models/project_response.py +121 -0
  549. anyscale/client/openapi_client/models/projectbase_response.py +121 -0
  550. anyscale/client/openapi_client/models/projectcollaborator_list_response.py +147 -0
  551. anyscale/client/openapi_client/models/projectdefaultsessionname_response.py +121 -0
  552. anyscale/client/openapi_client/models/projects_sort_field.py +101 -0
  553. anyscale/client/openapi_client/models/projects_violating_tree_hierarchy_response.py +121 -0
  554. anyscale/client/openapi_client/models/projectsviolatingtreehierarchyresponse_response.py +121 -0
  555. anyscale/client/openapi_client/models/protocols.py +150 -0
  556. anyscale/client/openapi_client/models/provider_metadata.py +205 -0
  557. anyscale/client/openapi_client/models/providermetadata_response.py +121 -0
  558. anyscale/client/openapi_client/models/python_modules.py +150 -0
  559. anyscale/client/openapi_client/models/quota.py +198 -0
  560. anyscale/client/openapi_client/models/ray_gcs_external_storage_config.py +178 -0
  561. anyscale/client/openapi_client/models/ray_runtime_env_config.py +262 -0
  562. anyscale/client/openapi_client/models/read_billing_version.py +210 -0
  563. anyscale/client/openapi_client/models/readbillingversion_list_response.py +147 -0
  564. anyscale/client/openapi_client/models/replica_details.py +152 -0
  565. anyscale/client/openapi_client/models/replica_state.py +104 -0
  566. anyscale/client/openapi_client/models/request_email_magic_link_response.py +147 -0
  567. anyscale/client/openapi_client/models/request_otp_return_api_model.py +148 -0
  568. anyscale/client/openapi_client/models/request_password_reset_params.py +147 -0
  569. anyscale/client/openapi_client/models/requestemailmagiclinkresponse_response.py +121 -0
  570. anyscale/client/openapi_client/models/requestotpreturnapimodel_response.py +121 -0
  571. anyscale/client/openapi_client/models/reset_password_params.py +148 -0
  572. anyscale/client/openapi_client/models/resource_quota.py +465 -0
  573. anyscale/client/openapi_client/models/resource_quota_status.py +123 -0
  574. anyscale/client/openapi_client/models/resourcequota_list_response.py +147 -0
  575. anyscale/client/openapi_client/models/resourcequota_response.py +121 -0
  576. anyscale/client/openapi_client/models/resources.py +234 -0
  577. anyscale/client/openapi_client/models/resubmit_ft_job_request.py +121 -0
  578. anyscale/client/openapi_client/models/rollback_service_model.py +122 -0
  579. anyscale/client/openapi_client/models/rollout_strategy.py +100 -0
  580. anyscale/client/openapi_client/models/s3_download_location.py +148 -0
  581. anyscale/client/openapi_client/models/schedule_config.py +151 -0
  582. anyscale/client/openapi_client/models/serve_deployment_grafana_dashboard_status.py +101 -0
  583. anyscale/client/openapi_client/models/serve_deployment_logs.py +152 -0
  584. anyscale/client/openapi_client/models/serve_deployment_state.py +104 -0
  585. anyscale/client/openapi_client/models/servedeploymentlogs_response.py +121 -0
  586. anyscale/client/openapi_client/models/server_session_token.py +121 -0
  587. anyscale/client/openapi_client/models/serversessiontoken_response.py +121 -0
  588. anyscale/client/openapi_client/models/service_config.py +178 -0
  589. anyscale/client/openapi_client/models/service_event_current_state.py +108 -0
  590. anyscale/client/openapi_client/models/service_event_level.py +102 -0
  591. anyscale/client/openapi_client/models/service_event_origin.py +103 -0
  592. anyscale/client/openapi_client/models/service_event_scope.py +103 -0
  593. anyscale/client/openapi_client/models/service_event_scope_filter.py +104 -0
  594. anyscale/client/openapi_client/models/service_event_type.py +125 -0
  595. anyscale/client/openapi_client/models/service_event_verbose_message_model.py +180 -0
  596. anyscale/client/openapi_client/models/service_goal_states.py +100 -0
  597. anyscale/client/openapi_client/models/service_observability_urls.py +206 -0
  598. anyscale/client/openapi_client/models/service_sort_field.py +101 -0
  599. anyscale/client/openapi_client/models/service_type.py +100 -0
  600. anyscale/client/openapi_client/models/service_usage.py +353 -0
  601. anyscale/client/openapi_client/models/service_version_state.py +106 -0
  602. anyscale/client/openapi_client/models/serviceeventverbosemessagemodel_list_response.py +147 -0
  603. anyscale/client/openapi_client/models/session.py +834 -0
  604. anyscale/client/openapi_client/models/session_access.py +102 -0
  605. anyscale/client/openapi_client/models/session_autosync_sessions_update_message.py +121 -0
  606. anyscale/client/openapi_client/models/session_command.py +413 -0
  607. anyscale/client/openapi_client/models/session_command_finish_options.py +226 -0
  608. anyscale/client/openapi_client/models/session_command_id.py +121 -0
  609. anyscale/client/openapi_client/models/session_command_types.py +100 -0
  610. anyscale/client/openapi_client/models/session_create_message.py +148 -0
  611. anyscale/client/openapi_client/models/session_delete_message.py +121 -0
  612. anyscale/client/openapi_client/models/session_describe.py +175 -0
  613. anyscale/client/openapi_client/models/session_details.py +148 -0
  614. anyscale/client/openapi_client/models/session_event.py +267 -0
  615. anyscale/client/openapi_client/models/session_event_cause.py +150 -0
  616. anyscale/client/openapi_client/models/session_event_types.py +111 -0
  617. anyscale/client/openapi_client/models/session_execute_message.py +121 -0
  618. anyscale/client/openapi_client/models/session_finish_command_message.py +175 -0
  619. anyscale/client/openapi_client/models/session_history_item.py +146 -0
  620. anyscale/client/openapi_client/models/session_kill_command_message.py +121 -0
  621. anyscale/client/openapi_client/models/session_list_response.py +147 -0
  622. anyscale/client/openapi_client/models/session_patch_message.py +121 -0
  623. anyscale/client/openapi_client/models/session_response.py +121 -0
  624. anyscale/client/openapi_client/models/session_ssh_key.py +148 -0
  625. anyscale/client/openapi_client/models/session_starting_up_data.py +146 -0
  626. anyscale/client/openapi_client/models/session_state.py +111 -0
  627. anyscale/client/openapi_client/models/session_state_change_message.py +121 -0
  628. anyscale/client/openapi_client/models/session_state_data.py +146 -0
  629. anyscale/client/openapi_client/models/session_stopping_data.py +146 -0
  630. anyscale/client/openapi_client/models/sessioncommand_list_response.py +147 -0
  631. anyscale/client/openapi_client/models/sessioncommandid_response.py +121 -0
  632. anyscale/client/openapi_client/models/sessiondescribe_response.py +121 -0
  633. anyscale/client/openapi_client/models/sessiondetails_response.py +121 -0
  634. anyscale/client/openapi_client/models/sessionevent_list_response.py +147 -0
  635. anyscale/client/openapi_client/models/sessionhistoryitem_list_response.py +147 -0
  636. anyscale/client/openapi_client/models/sessions_sort_field.py +104 -0
  637. anyscale/client/openapi_client/models/sessionsshkey_response.py +121 -0
  638. anyscale/client/openapi_client/models/setup_initialize_session_options.py +225 -0
  639. anyscale/client/openapi_client/models/show_otp_source_return_api_model.py +121 -0
  640. anyscale/client/openapi_client/models/showotpsourcereturnapimodel_response.py +121 -0
  641. anyscale/client/openapi_client/models/snapshot_create_message.py +148 -0
  642. anyscale/client/openapi_client/models/snapshot_delete_message.py +148 -0
  643. anyscale/client/openapi_client/models/snapshot_patch_message.py +148 -0
  644. anyscale/client/openapi_client/models/socket_message_schemas.py +499 -0
  645. anyscale/client/openapi_client/models/socket_message_types.py +113 -0
  646. anyscale/client/openapi_client/models/socketmessageschemas_response.py +121 -0
  647. anyscale/client/openapi_client/models/socketmessagetypes_response.py +121 -0
  648. anyscale/client/openapi_client/models/sort_order.py +100 -0
  649. anyscale/client/openapi_client/models/sso_login_info.py +151 -0
  650. anyscale/client/openapi_client/models/ssologininfo_response.py +121 -0
  651. anyscale/client/openapi_client/models/start_session_options.py +146 -0
  652. anyscale/client/openapi_client/models/stop_session_options.py +227 -0
  653. anyscale/client/openapi_client/models/stream_publish_request.py +239 -0
  654. anyscale/client/openapi_client/models/subnet_id_with_availability_zone_aws.py +148 -0
  655. anyscale/client/openapi_client/models/support_requests_query.py +178 -0
  656. anyscale/client/openapi_client/models/supportedbaseimagesenum.py +1570 -0
  657. anyscale/client/openapi_client/models/templatized_compute_configs.py +202 -0
  658. anyscale/client/openapi_client/models/templatized_decorated_application_templates.py +202 -0
  659. anyscale/client/openapi_client/models/templatizedcomputeconfigs_response.py +121 -0
  660. anyscale/client/openapi_client/models/templatizeddecoratedapplicationtemplates_response.py +121 -0
  661. anyscale/client/openapi_client/models/text_query.py +178 -0
  662. anyscale/client/openapi_client/models/timestamped_logs_output.py +148 -0
  663. anyscale/client/openapi_client/models/timestampedlogsoutput_response.py +121 -0
  664. anyscale/client/openapi_client/models/tool.py +100 -0
  665. anyscale/client/openapi_client/models/tracing_config.py +178 -0
  666. anyscale/client/openapi_client/models/try_login_email_response.py +208 -0
  667. anyscale/client/openapi_client/models/tryloginemailresponse_response.py +121 -0
  668. anyscale/client/openapi_client/models/unified_job_sort_field.py +103 -0
  669. anyscale/client/openapi_client/models/unified_job_status.py +114 -0
  670. anyscale/client/openapi_client/models/unified_job_type.py +100 -0
  671. anyscale/client/openapi_client/models/update_cloud_with_cloud_resource.py +178 -0
  672. anyscale/client/openapi_client/models/update_cloud_with_cloud_resource_gcp.py +178 -0
  673. anyscale/client/openapi_client/models/update_cluster_dns.py +152 -0
  674. anyscale/client/openapi_client/models/update_compute_template.py +146 -0
  675. anyscale/client/openapi_client/models/update_compute_template_config.py +464 -0
  676. anyscale/client/openapi_client/models/update_endpoint.py +152 -0
  677. anyscale/client/openapi_client/models/update_machine_pool_request.py +151 -0
  678. anyscale/client/openapi_client/models/update_model_deployment.py +152 -0
  679. anyscale/client/openapi_client/models/update_organization_collaborator.py +121 -0
  680. anyscale/client/openapi_client/models/update_project_collaborator.py +121 -0
  681. anyscale/client/openapi_client/models/update_resource_quota.py +122 -0
  682. anyscale/client/openapi_client/models/updatemachinepoolresponse_response.py +121 -0
  683. anyscale/client/openapi_client/models/upload_session_command_logs_locations.py +148 -0
  684. anyscale/client/openapi_client/models/uploadsessioncommandlogslocations_response.py +121 -0
  685. anyscale/client/openapi_client/models/user_info.py +569 -0
  686. anyscale/client/openapi_client/models/user_resend_email_options.py +147 -0
  687. anyscale/client/openapi_client/models/user_service_access_types.py +100 -0
  688. anyscale/client/openapi_client/models/userinfo_response.py +121 -0
  689. anyscale/client/openapi_client/models/utm_fields.py +224 -0
  690. anyscale/client/openapi_client/models/ux_instance.py +468 -0
  691. anyscale/client/openapi_client/models/validate_otp_params_api_model.py +121 -0
  692. anyscale/client/openapi_client/models/validation_error.py +175 -0
  693. anyscale/client/openapi_client/models/verify_response.py +147 -0
  694. anyscale/client/openapi_client/models/verifyresponse_response.py +121 -0
  695. anyscale/client/openapi_client/models/visibility.py +100 -0
  696. anyscale/client/openapi_client/models/waitlist_status_response.py +121 -0
  697. anyscale/client/openapi_client/models/waitlist_status_type.py +100 -0
  698. anyscale/client/openapi_client/models/waitliststatusresponse_response.py +121 -0
  699. anyscale/client/openapi_client/models/wand_b_run_details.py +147 -0
  700. anyscale/client/openapi_client/models/web_terminal.py +121 -0
  701. anyscale/client/openapi_client/models/webterminal_list_response.py +147 -0
  702. anyscale/client/openapi_client/models/webterminal_response.py +121 -0
  703. anyscale/client/openapi_client/models/worker_node_type.py +404 -0
  704. anyscale/client/openapi_client/models/workload_type.py +102 -0
  705. anyscale/client/openapi_client/models/workspace_dataplane_artifact.py +181 -0
  706. anyscale/client/openapi_client/models/workspace_dataplane_artifacts.py +123 -0
  707. anyscale/client/openapi_client/models/workspace_dataplane_proxied_artifacts.py +178 -0
  708. anyscale/client/openapi_client/models/workspace_event.py +325 -0
  709. anyscale/client/openapi_client/models/workspace_event_source.py +100 -0
  710. anyscale/client/openapi_client/models/workspace_event_source_filter.py +101 -0
  711. anyscale/client/openapi_client/models/workspace_readme.py +123 -0
  712. anyscale/client/openapi_client/models/workspace_snapshot_states.py +108 -0
  713. anyscale/client/openapi_client/models/workspace_template.py +353 -0
  714. anyscale/client/openapi_client/models/workspace_template_cluster_environment_metadata.py +178 -0
  715. anyscale/client/openapi_client/models/workspacedataplaneartifacts_response.py +121 -0
  716. anyscale/client/openapi_client/models/workspacedataplaneproxiedartifacts_response.py +121 -0
  717. anyscale/client/openapi_client/models/workspaceevent_list_response.py +147 -0
  718. anyscale/client/openapi_client/models/workspacereadme_response.py +121 -0
  719. anyscale/client/openapi_client/models/workspacetemplate_list_response.py +147 -0
  720. anyscale/client/openapi_client/models/workspacetemplateclusterenvironmentmetadata_response.py +121 -0
  721. anyscale/client/openapi_client/models/write_cloud.py +546 -0
  722. anyscale/client/openapi_client/models/write_cluster_config.py +123 -0
  723. anyscale/client/openapi_client/models/write_project.py +226 -0
  724. anyscale/client/openapi_client/models/write_session.py +147 -0
  725. anyscale/client/openapi_client/models/write_support_request.py +121 -0
  726. anyscale/client/openapi_client/rest.py +296 -0
  727. anyscale/client/requirements.txt +6 -0
  728. anyscale/client/setup.cfg +2 -0
  729. anyscale/client/setup.py +40 -0
  730. anyscale/client/test-requirements.txt +3 -0
  731. anyscale/client/tox.ini +9 -0
  732. anyscale/cloud.py +216 -0
  733. anyscale/cloud_resource.py +1032 -0
  734. anyscale/cluster.py +138 -0
  735. anyscale/cluster_compute.py +167 -0
  736. anyscale/cluster_env.py +173 -0
  737. anyscale/commands/__init__.py +0 -0
  738. anyscale/commands/aggregated_instance_usage_commands.py +86 -0
  739. anyscale/commands/anyscale_api/__init__.py +0 -0
  740. anyscale/commands/anyscale_api/api_commands.py +23 -0
  741. anyscale/commands/anyscale_api/session_commands_commands.py +80 -0
  742. anyscale/commands/anyscale_api/session_operations_commands.py +28 -0
  743. anyscale/commands/anyscale_api/sessions_commands.py +152 -0
  744. anyscale/commands/auth_commands.py +41 -0
  745. anyscale/commands/cloud_commands.py +1011 -0
  746. anyscale/commands/cloud_commands_util.py +10 -0
  747. anyscale/commands/cluster_commands.py +476 -0
  748. anyscale/commands/cluster_env_commands.py +139 -0
  749. anyscale/commands/command_examples.py +495 -0
  750. anyscale/commands/compute_config_commands.py +252 -0
  751. anyscale/commands/config_commands.py +213 -0
  752. anyscale/commands/exec_commands.py +14 -0
  753. anyscale/commands/experimental_integrations_commands.py +70 -0
  754. anyscale/commands/image_commands.py +125 -0
  755. anyscale/commands/job_commands.py +745 -0
  756. anyscale/commands/list_commands.py +85 -0
  757. anyscale/commands/llm/dataset_commands.py +269 -0
  758. anyscale/commands/llm/group.py +15 -0
  759. anyscale/commands/llm/models_commands.py +123 -0
  760. anyscale/commands/login_commands.py +79 -0
  761. anyscale/commands/logs_commands.py +312 -0
  762. anyscale/commands/machine_commands.py +116 -0
  763. anyscale/commands/machine_pool_commands.py +163 -0
  764. anyscale/commands/migrate_commands.py +84 -0
  765. anyscale/commands/project_commands.py +203 -0
  766. anyscale/commands/resource_quota_commands.py +214 -0
  767. anyscale/commands/schedule_commands.py +436 -0
  768. anyscale/commands/service_account_commands.py +72 -0
  769. anyscale/commands/service_commands.py +738 -0
  770. anyscale/commands/session_commands_hidden.py +179 -0
  771. anyscale/commands/util.py +152 -0
  772. anyscale/commands/workspace_commands.py +511 -0
  773. anyscale/commands/workspace_commands_v2.py +874 -0
  774. anyscale/component_activity_util.py +83 -0
  775. anyscale/compute_config/__init__.py +84 -0
  776. anyscale/compute_config/_private/compute_config_sdk.py +433 -0
  777. anyscale/compute_config/commands.py +122 -0
  778. anyscale/compute_config/models.py +630 -0
  779. anyscale/conf.py +23 -0
  780. anyscale/connect.py +1323 -0
  781. anyscale/connect_utils/__init__.py +0 -0
  782. anyscale/connect_utils/prepare_cluster.py +962 -0
  783. anyscale/connect_utils/project.py +298 -0
  784. anyscale/connect_utils/start_interactive_session.py +437 -0
  785. anyscale/controllers/__init__.py +0 -0
  786. anyscale/controllers/auth_controller.py +134 -0
  787. anyscale/controllers/base_controller.py +52 -0
  788. anyscale/controllers/cloud_controller.py +3609 -0
  789. anyscale/controllers/cloud_functional_verification_controller.py +858 -0
  790. anyscale/controllers/cluster_controller.py +720 -0
  791. anyscale/controllers/cluster_env_controller.py +219 -0
  792. anyscale/controllers/compute_config_controller.py +351 -0
  793. anyscale/controllers/config_controller.py +422 -0
  794. anyscale/controllers/experimental_integrations_controller.py +80 -0
  795. anyscale/controllers/job_controller.py +647 -0
  796. anyscale/controllers/jobs_bg_controller.py +0 -0
  797. anyscale/controllers/list_controller.py +290 -0
  798. anyscale/controllers/llm/__init__.py +0 -0
  799. anyscale/controllers/llm/models_controller.py +144 -0
  800. anyscale/controllers/logs_controller.py +449 -0
  801. anyscale/controllers/machine_controller.py +37 -0
  802. anyscale/controllers/machine_pool_controller.py +86 -0
  803. anyscale/controllers/project_controller.py +281 -0
  804. anyscale/controllers/resource_quota_controller.py +183 -0
  805. anyscale/controllers/schedule_controller.py +333 -0
  806. anyscale/controllers/service_account_controller.py +168 -0
  807. anyscale/controllers/service_controller.py +453 -0
  808. anyscale/controllers/workspace_controller.py +253 -0
  809. anyscale/feature_flags.py +4 -0
  810. anyscale/fingerprint.py +62 -0
  811. anyscale/formatters/__init__.py +0 -0
  812. anyscale/formatters/clouds_formatter.py +65 -0
  813. anyscale/formatters/common_formatter.py +22 -0
  814. anyscale/gcp_verification.py +792 -0
  815. anyscale/image/__init__.py +73 -0
  816. anyscale/image/_private/image_sdk.py +202 -0
  817. anyscale/image/commands.py +117 -0
  818. anyscale/image/models.py +57 -0
  819. anyscale/integrations.py +329 -0
  820. anyscale/job/__init__.py +166 -0
  821. anyscale/job/_private/job_sdk.py +497 -0
  822. anyscale/job/commands.py +267 -0
  823. anyscale/job/models.py +500 -0
  824. anyscale/links.py +4 -0
  825. anyscale/llm/__init__.py +2 -0
  826. anyscale/llm/dataset/__init__.py +2 -0
  827. anyscale/llm/dataset/_private/__init__.py +0 -0
  828. anyscale/llm/dataset/_private/docs.py +63 -0
  829. anyscale/llm/dataset/_private/models.py +71 -0
  830. anyscale/llm/dataset/_private/sdk.py +147 -0
  831. anyscale/llm/model/__init__.py +2 -0
  832. anyscale/llm/model/_private/models_sdk.py +62 -0
  833. anyscale/llm/model/commands.py +93 -0
  834. anyscale/llm/model/models.py +171 -0
  835. anyscale/llm/model/sdk.py +62 -0
  836. anyscale/llm/sdk.py +27 -0
  837. anyscale/memorydb_supported_zones.json +22 -0
  838. anyscale/models/job_model.py +457 -0
  839. anyscale/models/service_model.py +125 -0
  840. anyscale/project.py +501 -0
  841. anyscale/schedule/__init__.py +91 -0
  842. anyscale/schedule/_private/schedule_sdk.py +165 -0
  843. anyscale/schedule/commands.py +149 -0
  844. anyscale/schedule/models.py +145 -0
  845. anyscale/scripts.py +164 -0
  846. anyscale/sdk/anyscale_client/__init__.py +235 -0
  847. anyscale/sdk/anyscale_client/api/__init__.py +6 -0
  848. anyscale/sdk/anyscale_client/api/default_api.py +11625 -0
  849. anyscale/sdk/anyscale_client/api_client.py +647 -0
  850. anyscale/sdk/anyscale_client/configuration.py +373 -0
  851. anyscale/sdk/anyscale_client/exceptions.py +120 -0
  852. anyscale/sdk/anyscale_client/models/__init__.py +220 -0
  853. anyscale/sdk/anyscale_client/models/access_config.py +122 -0
  854. anyscale/sdk/anyscale_client/models/app_config.py +436 -0
  855. anyscale/sdk/anyscale_client/models/app_config_config_schema.py +235 -0
  856. anyscale/sdk/anyscale_client/models/appconfig_list_response.py +147 -0
  857. anyscale/sdk/anyscale_client/models/appconfig_response.py +121 -0
  858. anyscale/sdk/anyscale_client/models/apply_production_service_v2_model.py +490 -0
  859. anyscale/sdk/anyscale_client/models/apply_service_model.py +490 -0
  860. anyscale/sdk/anyscale_client/models/archive_status.py +101 -0
  861. anyscale/sdk/anyscale_client/models/base_job_status.py +105 -0
  862. anyscale/sdk/anyscale_client/models/baseimagesenum.py +2130 -0
  863. anyscale/sdk/anyscale_client/models/build.py +607 -0
  864. anyscale/sdk/anyscale_client/models/build_list_response.py +147 -0
  865. anyscale/sdk/anyscale_client/models/build_log_response.py +123 -0
  866. anyscale/sdk/anyscale_client/models/build_response.py +121 -0
  867. anyscale/sdk/anyscale_client/models/build_status.py +104 -0
  868. anyscale/sdk/anyscale_client/models/buildlogresponse_response.py +121 -0
  869. anyscale/sdk/anyscale_client/models/cloud.py +802 -0
  870. anyscale/sdk/anyscale_client/models/cloud_config.py +206 -0
  871. anyscale/sdk/anyscale_client/models/cloud_list_response.py +147 -0
  872. anyscale/sdk/anyscale_client/models/cloud_providers.py +103 -0
  873. anyscale/sdk/anyscale_client/models/cloud_response.py +121 -0
  874. anyscale/sdk/anyscale_client/models/cloud_state.py +104 -0
  875. anyscale/sdk/anyscale_client/models/cloud_status.py +100 -0
  876. anyscale/sdk/anyscale_client/models/cloud_type.py +100 -0
  877. anyscale/sdk/anyscale_client/models/cloud_types.py +100 -0
  878. anyscale/sdk/anyscale_client/models/cloud_version.py +100 -0
  879. anyscale/sdk/anyscale_client/models/clouds_query.py +150 -0
  880. anyscale/sdk/anyscale_client/models/cluster.py +721 -0
  881. anyscale/sdk/anyscale_client/models/cluster_compute.py +415 -0
  882. anyscale/sdk/anyscale_client/models/cluster_compute_config.py +461 -0
  883. anyscale/sdk/anyscale_client/models/cluster_computes_query.py +293 -0
  884. anyscale/sdk/anyscale_client/models/cluster_environment.py +380 -0
  885. anyscale/sdk/anyscale_client/models/cluster_environment_build.py +578 -0
  886. anyscale/sdk/anyscale_client/models/cluster_environment_build_log_response.py +123 -0
  887. anyscale/sdk/anyscale_client/models/cluster_environment_build_operation.py +237 -0
  888. anyscale/sdk/anyscale_client/models/cluster_environment_build_status.py +104 -0
  889. anyscale/sdk/anyscale_client/models/cluster_environments_query.py +290 -0
  890. anyscale/sdk/anyscale_client/models/cluster_head_node_info.py +152 -0
  891. anyscale/sdk/anyscale_client/models/cluster_list_response.py +147 -0
  892. anyscale/sdk/anyscale_client/models/cluster_management_stack_versions.py +100 -0
  893. anyscale/sdk/anyscale_client/models/cluster_operation.py +266 -0
  894. anyscale/sdk/anyscale_client/models/cluster_operation_type.py +101 -0
  895. anyscale/sdk/anyscale_client/models/cluster_response.py +121 -0
  896. anyscale/sdk/anyscale_client/models/cluster_services_urls.py +430 -0
  897. anyscale/sdk/anyscale_client/models/cluster_state.py +108 -0
  898. anyscale/sdk/anyscale_client/models/cluster_status.py +104 -0
  899. anyscale/sdk/anyscale_client/models/cluster_status_details.py +100 -0
  900. anyscale/sdk/anyscale_client/models/clustercompute_list_response.py +147 -0
  901. anyscale/sdk/anyscale_client/models/clustercompute_response.py +121 -0
  902. anyscale/sdk/anyscale_client/models/clusterenvironment_list_response.py +147 -0
  903. anyscale/sdk/anyscale_client/models/clusterenvironment_response.py +121 -0
  904. anyscale/sdk/anyscale_client/models/clusterenvironmentbuild_list_response.py +147 -0
  905. anyscale/sdk/anyscale_client/models/clusterenvironmentbuild_response.py +121 -0
  906. anyscale/sdk/anyscale_client/models/clusterenvironmentbuildlogresponse_response.py +121 -0
  907. anyscale/sdk/anyscale_client/models/clusterenvironmentbuildoperation_response.py +121 -0
  908. anyscale/sdk/anyscale_client/models/clusteroperation_response.py +121 -0
  909. anyscale/sdk/anyscale_client/models/clusters_query.py +234 -0
  910. anyscale/sdk/anyscale_client/models/compute_node_type.py +292 -0
  911. anyscale/sdk/anyscale_client/models/compute_stack.py +100 -0
  912. anyscale/sdk/anyscale_client/models/compute_template.py +415 -0
  913. anyscale/sdk/anyscale_client/models/compute_template_config.py +461 -0
  914. anyscale/sdk/anyscale_client/models/compute_template_query.py +316 -0
  915. anyscale/sdk/anyscale_client/models/computetemplate_list_response.py +147 -0
  916. anyscale/sdk/anyscale_client/models/computetemplate_response.py +121 -0
  917. anyscale/sdk/anyscale_client/models/computetemplateconfig_response.py +121 -0
  918. anyscale/sdk/anyscale_client/models/create_app_config.py +235 -0
  919. anyscale/sdk/anyscale_client/models/create_app_config_configuration_schema.py +235 -0
  920. anyscale/sdk/anyscale_client/models/create_build.py +263 -0
  921. anyscale/sdk/anyscale_client/models/create_byod_app_config_configuration_schema.py +206 -0
  922. anyscale/sdk/anyscale_client/models/create_byod_cluster_environment.py +180 -0
  923. anyscale/sdk/anyscale_client/models/create_byod_cluster_environment_build.py +152 -0
  924. anyscale/sdk/anyscale_client/models/create_byod_cluster_environment_configuration_schema.py +208 -0
  925. anyscale/sdk/anyscale_client/models/create_cloud.py +518 -0
  926. anyscale/sdk/anyscale_client/models/create_cluster.py +376 -0
  927. anyscale/sdk/anyscale_client/models/create_cluster_compute.py +229 -0
  928. anyscale/sdk/anyscale_client/models/create_cluster_compute_config.py +463 -0
  929. anyscale/sdk/anyscale_client/models/create_cluster_environment.py +235 -0
  930. anyscale/sdk/anyscale_client/models/create_cluster_environment_build.py +263 -0
  931. anyscale/sdk/anyscale_client/models/create_cluster_environment_configuration_schema.py +235 -0
  932. anyscale/sdk/anyscale_client/models/create_compute_template.py +229 -0
  933. anyscale/sdk/anyscale_client/models/create_compute_template_config.py +464 -0
  934. anyscale/sdk/anyscale_client/models/create_job_queue_config.py +206 -0
  935. anyscale/sdk/anyscale_client/models/create_production_job.py +234 -0
  936. anyscale/sdk/anyscale_client/models/create_production_job_config.py +347 -0
  937. anyscale/sdk/anyscale_client/models/create_project.py +207 -0
  938. anyscale/sdk/anyscale_client/models/create_schedule.py +263 -0
  939. anyscale/sdk/anyscale_client/models/create_session.py +432 -0
  940. anyscale/sdk/anyscale_client/models/create_session_command.py +152 -0
  941. anyscale/sdk/anyscale_client/models/create_sso_config.py +150 -0
  942. anyscale/sdk/anyscale_client/models/grpc_protocol_config.py +178 -0
  943. anyscale/sdk/anyscale_client/models/ha_job_goal_states.py +102 -0
  944. anyscale/sdk/anyscale_client/models/ha_job_states.py +109 -0
  945. anyscale/sdk/anyscale_client/models/http_protocol_config.py +150 -0
  946. anyscale/sdk/anyscale_client/models/http_validation_error.py +120 -0
  947. anyscale/sdk/anyscale_client/models/idle_termination_status.py +104 -0
  948. anyscale/sdk/anyscale_client/models/job.py +466 -0
  949. anyscale/sdk/anyscale_client/models/job_list_response.py +147 -0
  950. anyscale/sdk/anyscale_client/models/job_queue_config.py +122 -0
  951. anyscale/sdk/anyscale_client/models/job_queue_execution_mode.py +101 -0
  952. anyscale/sdk/anyscale_client/models/job_queue_spec.py +263 -0
  953. anyscale/sdk/anyscale_client/models/job_run_type.py +101 -0
  954. anyscale/sdk/anyscale_client/models/job_status.py +105 -0
  955. anyscale/sdk/anyscale_client/models/jobs_query.py +458 -0
  956. anyscale/sdk/anyscale_client/models/jobs_sort_field.py +104 -0
  957. anyscale/sdk/anyscale_client/models/list_response_metadata.py +146 -0
  958. anyscale/sdk/anyscale_client/models/list_service_model.py +347 -0
  959. anyscale/sdk/anyscale_client/models/listservicemodel_list_response.py +147 -0
  960. anyscale/sdk/anyscale_client/models/log_download_result.py +207 -0
  961. anyscale/sdk/anyscale_client/models/log_file_chunk.py +439 -0
  962. anyscale/sdk/anyscale_client/models/log_level_types.py +100 -0
  963. anyscale/sdk/anyscale_client/models/log_stream.py +151 -0
  964. anyscale/sdk/anyscale_client/models/logdownloadresult_response.py +121 -0
  965. anyscale/sdk/anyscale_client/models/logstream_response.py +121 -0
  966. anyscale/sdk/anyscale_client/models/node_type.py +100 -0
  967. anyscale/sdk/anyscale_client/models/object_storage_config.py +122 -0
  968. anyscale/sdk/anyscale_client/models/object_storage_config_s3.py +256 -0
  969. anyscale/sdk/anyscale_client/models/objectstorageconfig_response.py +121 -0
  970. anyscale/sdk/anyscale_client/models/operation_error.py +123 -0
  971. anyscale/sdk/anyscale_client/models/operation_progress.py +123 -0
  972. anyscale/sdk/anyscale_client/models/operation_result.py +150 -0
  973. anyscale/sdk/anyscale_client/models/organization.py +209 -0
  974. anyscale/sdk/anyscale_client/models/organization_response.py +121 -0
  975. anyscale/sdk/anyscale_client/models/page_query.py +153 -0
  976. anyscale/sdk/anyscale_client/models/pause_schedule.py +123 -0
  977. anyscale/sdk/anyscale_client/models/production_job.py +437 -0
  978. anyscale/sdk/anyscale_client/models/production_job_config.py +348 -0
  979. anyscale/sdk/anyscale_client/models/production_job_state_transition.py +293 -0
  980. anyscale/sdk/anyscale_client/models/production_service_v2_model.py +612 -0
  981. anyscale/sdk/anyscale_client/models/production_service_v2_version_model.py +437 -0
  982. anyscale/sdk/anyscale_client/models/productionjob_list_response.py +147 -0
  983. anyscale/sdk/anyscale_client/models/productionjob_response.py +121 -0
  984. anyscale/sdk/anyscale_client/models/productionservicev2_model_response.py +121 -0
  985. anyscale/sdk/anyscale_client/models/project.py +467 -0
  986. anyscale/sdk/anyscale_client/models/project_list_response.py +147 -0
  987. anyscale/sdk/anyscale_client/models/project_response.py +121 -0
  988. anyscale/sdk/anyscale_client/models/projects_query.py +234 -0
  989. anyscale/sdk/anyscale_client/models/protocols.py +150 -0
  990. anyscale/sdk/anyscale_client/models/python_modules.py +150 -0
  991. anyscale/sdk/anyscale_client/models/python_version.py +105 -0
  992. anyscale/sdk/anyscale_client/models/ray_gcs_external_storage_config.py +178 -0
  993. anyscale/sdk/anyscale_client/models/ray_runtime_env_config.py +262 -0
  994. anyscale/sdk/anyscale_client/models/resources.py +234 -0
  995. anyscale/sdk/anyscale_client/models/rollback_service_model.py +122 -0
  996. anyscale/sdk/anyscale_client/models/rollout_strategy.py +100 -0
  997. anyscale/sdk/anyscale_client/models/runtime_environment.py +406 -0
  998. anyscale/sdk/anyscale_client/models/runtimeenvironment_response.py +121 -0
  999. anyscale/sdk/anyscale_client/models/schedule_api_model.py +467 -0
  1000. anyscale/sdk/anyscale_client/models/schedule_config.py +151 -0
  1001. anyscale/sdk/anyscale_client/models/scheduleapimodel_list_response.py +147 -0
  1002. anyscale/sdk/anyscale_client/models/scheduleapimodel_response.py +121 -0
  1003. anyscale/sdk/anyscale_client/models/service_config.py +178 -0
  1004. anyscale/sdk/anyscale_client/models/service_event_current_state.py +108 -0
  1005. anyscale/sdk/anyscale_client/models/service_goal_states.py +100 -0
  1006. anyscale/sdk/anyscale_client/models/service_model.py +612 -0
  1007. anyscale/sdk/anyscale_client/models/service_observability_urls.py +206 -0
  1008. anyscale/sdk/anyscale_client/models/service_sort_field.py +101 -0
  1009. anyscale/sdk/anyscale_client/models/service_type.py +100 -0
  1010. anyscale/sdk/anyscale_client/models/service_version_state.py +106 -0
  1011. anyscale/sdk/anyscale_client/models/servicemodel_list_response.py +147 -0
  1012. anyscale/sdk/anyscale_client/models/servicemodel_response.py +121 -0
  1013. anyscale/sdk/anyscale_client/models/session.py +1535 -0
  1014. anyscale/sdk/anyscale_client/models/session_command.py +350 -0
  1015. anyscale/sdk/anyscale_client/models/session_command_types.py +100 -0
  1016. anyscale/sdk/anyscale_client/models/session_event.py +267 -0
  1017. anyscale/sdk/anyscale_client/models/session_event_cause.py +150 -0
  1018. anyscale/sdk/anyscale_client/models/session_event_types.py +111 -0
  1019. anyscale/sdk/anyscale_client/models/session_list_response.py +147 -0
  1020. anyscale/sdk/anyscale_client/models/session_operation.py +266 -0
  1021. anyscale/sdk/anyscale_client/models/session_operation_type.py +101 -0
  1022. anyscale/sdk/anyscale_client/models/session_response.py +121 -0
  1023. anyscale/sdk/anyscale_client/models/session_starting_up_data.py +146 -0
  1024. anyscale/sdk/anyscale_client/models/session_state.py +111 -0
  1025. anyscale/sdk/anyscale_client/models/session_state_data.py +146 -0
  1026. anyscale/sdk/anyscale_client/models/session_stopping_data.py +146 -0
  1027. anyscale/sdk/anyscale_client/models/sessioncommand_list_response.py +147 -0
  1028. anyscale/sdk/anyscale_client/models/sessioncommand_response.py +121 -0
  1029. anyscale/sdk/anyscale_client/models/sessionevent_list_response.py +147 -0
  1030. anyscale/sdk/anyscale_client/models/sessionoperation_response.py +121 -0
  1031. anyscale/sdk/anyscale_client/models/sessions_query.py +206 -0
  1032. anyscale/sdk/anyscale_client/models/sort_by_clause_jobs_sort_field.py +148 -0
  1033. anyscale/sdk/anyscale_client/models/sort_order.py +100 -0
  1034. anyscale/sdk/anyscale_client/models/sso_config.py +237 -0
  1035. anyscale/sdk/anyscale_client/models/sso_mode.py +101 -0
  1036. anyscale/sdk/anyscale_client/models/ssoconfig_response.py +121 -0
  1037. anyscale/sdk/anyscale_client/models/start_cluster_options.py +178 -0
  1038. anyscale/sdk/anyscale_client/models/start_session_options.py +206 -0
  1039. anyscale/sdk/anyscale_client/models/static_sso_config.py +210 -0
  1040. anyscale/sdk/anyscale_client/models/supportedbaseimagesenum.py +1570 -0
  1041. anyscale/sdk/anyscale_client/models/terminate_cluster_options.py +122 -0
  1042. anyscale/sdk/anyscale_client/models/terminate_session_options.py +206 -0
  1043. anyscale/sdk/anyscale_client/models/text_query.py +178 -0
  1044. anyscale/sdk/anyscale_client/models/tracing_config.py +178 -0
  1045. anyscale/sdk/anyscale_client/models/update_app_config.py +122 -0
  1046. anyscale/sdk/anyscale_client/models/update_cloud.py +150 -0
  1047. anyscale/sdk/anyscale_client/models/update_cluster.py +206 -0
  1048. anyscale/sdk/anyscale_client/models/update_compute_template.py +146 -0
  1049. anyscale/sdk/anyscale_client/models/update_compute_template_config.py +464 -0
  1050. anyscale/sdk/anyscale_client/models/update_organization.py +123 -0
  1051. anyscale/sdk/anyscale_client/models/update_project.py +150 -0
  1052. anyscale/sdk/anyscale_client/models/update_session.py +150 -0
  1053. anyscale/sdk/anyscale_client/models/user_service_access_types.py +100 -0
  1054. anyscale/sdk/anyscale_client/models/ux_instance.py +468 -0
  1055. anyscale/sdk/anyscale_client/models/validation_error.py +175 -0
  1056. anyscale/sdk/anyscale_client/models/worker_node_type.py +404 -0
  1057. anyscale/sdk/anyscale_client/rest.py +296 -0
  1058. anyscale/sdk/anyscale_client/sdk.py +634 -0
  1059. anyscale/service/__init__.py +168 -0
  1060. anyscale/service/_private/service_sdk.py +702 -0
  1061. anyscale/service/commands.py +261 -0
  1062. anyscale/service/models.py +671 -0
  1063. anyscale/shared_anyscale_utils/__init__.py +1 -0
  1064. anyscale/shared_anyscale_utils/aws.py +153 -0
  1065. anyscale/shared_anyscale_utils/bytes_util.py +10 -0
  1066. anyscale/shared_anyscale_utils/conf.py +47 -0
  1067. anyscale/shared_anyscale_utils/default_anyscale_aws.yaml +74 -0
  1068. anyscale/shared_anyscale_utils/default_anyscale_gcp.yaml +80 -0
  1069. anyscale/shared_anyscale_utils/headers.py +38 -0
  1070. anyscale/shared_anyscale_utils/latest_ray_version.py +2 -0
  1071. anyscale/shared_anyscale_utils/project.py +15 -0
  1072. anyscale/shared_anyscale_utils/test_util.py +22 -0
  1073. anyscale/shared_anyscale_utils/tests/__init__.py +1 -0
  1074. anyscale/shared_anyscale_utils/tests/test_asyncio.py +41 -0
  1075. anyscale/shared_anyscale_utils/tests/test_ray_semver.py +63 -0
  1076. anyscale/shared_anyscale_utils/util.py +50 -0
  1077. anyscale/shared_anyscale_utils/utils/__init__.py +2 -0
  1078. anyscale/shared_anyscale_utils/utils/asyncio.py +120 -0
  1079. anyscale/shared_anyscale_utils/utils/byod.py +40 -0
  1080. anyscale/shared_anyscale_utils/utils/collections.py +33 -0
  1081. anyscale/shared_anyscale_utils/utils/id_gen.py +147 -0
  1082. anyscale/shared_anyscale_utils/utils/protected_string.py +89 -0
  1083. anyscale/shared_anyscale_utils/utils/ray_semver.py +81 -0
  1084. anyscale/snapshot.py +46 -0
  1085. anyscale/tables.py +82 -0
  1086. anyscale/util.py +1155 -0
  1087. anyscale/utils/__init__.py +0 -0
  1088. anyscale/utils/cli_version_check_util.py +63 -0
  1089. anyscale/utils/cloud_update_utils.py +862 -0
  1090. anyscale/utils/cloud_utils.py +317 -0
  1091. anyscale/utils/cluster_debug.py +191 -0
  1092. anyscale/utils/connect_helpers.py +155 -0
  1093. anyscale/utils/deprecation_util.py +32 -0
  1094. anyscale/utils/entity_arg_utils.py +43 -0
  1095. anyscale/utils/env_utils.py +17 -0
  1096. anyscale/utils/gcp_managed_setup_utils.py +888 -0
  1097. anyscale/utils/gcp_utils.py +312 -0
  1098. anyscale/utils/imports/__init__.py +0 -0
  1099. anyscale/utils/imports/all.py +13 -0
  1100. anyscale/utils/imports/azure.py +14 -0
  1101. anyscale/utils/imports/gcp.py +59 -0
  1102. anyscale/utils/logs_utils.py +141 -0
  1103. anyscale/utils/name_utils.py +33 -0
  1104. anyscale/utils/network_verification.py +153 -0
  1105. anyscale/utils/ray_utils.py +128 -0
  1106. anyscale/utils/ray_version_checker.py +48 -0
  1107. anyscale/utils/ray_version_utils.py +53 -0
  1108. anyscale/utils/runtime_env.py +487 -0
  1109. anyscale/utils/s3.py +92 -0
  1110. anyscale/utils/user_utils.py +17 -0
  1111. anyscale/utils/workload_types.py +7 -0
  1112. anyscale/utils/workspace_notification.py +39 -0
  1113. anyscale/utils/workspace_utils.py +65 -0
  1114. anyscale/version.py +1 -0
  1115. anyscale/webterminal/__init__.py +0 -0
  1116. anyscale/webterminal/bash-preexec.sh +370 -0
  1117. anyscale/webterminal/command_persister.py +164 -0
  1118. anyscale/webterminal/utils.py +176 -0
  1119. anyscale/webterminal/webterminal.py +311 -0
  1120. anyscale/workspace/__init__.py +270 -0
  1121. anyscale/workspace/_private/workspace_sdk.py +737 -0
  1122. anyscale/workspace/commands.py +472 -0
  1123. anyscale/workspace/models.py +296 -0
  1124. anyscale/workspace_utils.py +35 -0
  1125. anyscale-0.24.86.dist-info/LICENSE +68 -0
  1126. anyscale-0.24.86.dist-info/METADATA +82 -0
  1127. anyscale-0.24.86.dist-info/NOTICE +6 -0
  1128. anyscale-0.24.86.dist-info/RECORD +1131 -0
  1129. anyscale-0.24.86.dist-info/WHEEL +5 -0
  1130. anyscale-0.24.86.dist-info/entry_points.txt +2 -0
  1131. anyscale-0.24.86.dist-info/top_level.txt +1 -0
@@ -0,0 +1,1847 @@
1
+ from abc import ABC, abstractmethod
2
+ import contextlib
3
+ from functools import wraps
4
+ import io
5
+ import json
6
+ import logging
7
+ import os
8
+ import pathlib
9
+ import re
10
+ import time
11
+ from typing import Any, Callable, Dict, Generator, IO, List, Optional, Tuple
12
+ from urllib.parse import urlparse
13
+
14
+ from openapi_client.exceptions import ApiException
15
+ import requests
16
+ from rich.style import Style
17
+ import smart_open
18
+
19
+ from anyscale._private.anyscale_client.common import (
20
+ AnyscaleClientInterface,
21
+ DEFAULT_PYTHON_VERSION,
22
+ DEFAULT_RAY_VERSION,
23
+ RUNTIME_ENV_PACKAGE_FORMAT,
24
+ )
25
+ from anyscale._private.models.image_uri import ImageURI
26
+ from anyscale._private.models.model_base import InternalListResponse, ListResponse
27
+ from anyscale._private.utils.progress_util import (
28
+ FileDownloadProgress,
29
+ ProgressFileReader,
30
+ )
31
+ from anyscale.api_utils.common_utils import source_cloud_id_and_project_id
32
+ from anyscale.api_utils.logs_util import _download_log_from_s3_url_sync
33
+ from anyscale.authenticate import AuthenticationBlock, get_auth_api_client
34
+ from anyscale.cli_logger import BlockLogger
35
+ from anyscale.client.openapi_client.api.default_api import DefaultApi as InternalApi
36
+ from anyscale.client.openapi_client.models import (
37
+ ArchiveStatus,
38
+ Cloud,
39
+ CloudDataBucketAccessMode,
40
+ CloudDataBucketFileType,
41
+ CloudDataBucketPresignedUrlRequest,
42
+ CloudDataBucketPresignedUrlResponse,
43
+ CloudDataBucketPresignedUrlScheme,
44
+ CloudNameOptions,
45
+ ComputeTemplate,
46
+ ComputeTemplateConfig,
47
+ ComputeTemplateQuery,
48
+ CreateComputeTemplate,
49
+ CreateDataset,
50
+ CreateExperimentalWorkspace,
51
+ CreateInternalProductionJob,
52
+ Dataset as InternalDataset,
53
+ DatasetUpload,
54
+ DecoratedComputeTemplate,
55
+ DecoratedSession,
56
+ DeletedPlatformFineTunedModel,
57
+ ExperimentalWorkspace,
58
+ FineTunedModel,
59
+ FinetunedmodelListResponse,
60
+ InternalProductionJob,
61
+ SessionSshKey,
62
+ StartSessionOptions,
63
+ StopSessionOptions,
64
+ WorkspaceDataplaneProxiedArtifacts,
65
+ )
66
+ from anyscale.client.openapi_client.models.create_schedule import CreateSchedule
67
+ from anyscale.client.openapi_client.models.decorated_schedule import DecoratedSchedule
68
+ from anyscale.client.openapi_client.models.production_job import ProductionJob
69
+ from anyscale.client.openapi_client.rest import ApiException as InternalApiException
70
+ from anyscale.cluster_compute import parse_cluster_compute_name_version
71
+ from anyscale.feature_flags import FLAG_DEFAULT_WORKING_DIR_FOR_PROJ
72
+ from anyscale.sdk.anyscale_client.api.default_api import DefaultApi as ExternalApi
73
+ from anyscale.sdk.anyscale_client.models import (
74
+ ApplyServiceModel,
75
+ Cluster,
76
+ ClusterCompute,
77
+ ClusterComputeConfig,
78
+ ClusterEnvironment,
79
+ ClusterEnvironmentBuild,
80
+ ClusterenvironmentbuildListResponse,
81
+ ClusterEnvironmentBuildStatus,
82
+ ClusterEnvironmentsQuery,
83
+ CreateBYODClusterEnvironment,
84
+ CreateBYODClusterEnvironmentConfigurationSchema,
85
+ CreateClusterEnvironment,
86
+ CreateClusterEnvironmentBuild,
87
+ Job as APIJobRun,
88
+ ProductionServiceV2VersionModel,
89
+ Project,
90
+ RollbackServiceModel,
91
+ ServiceModel,
92
+ TextQuery,
93
+ )
94
+ from anyscale.sdk.anyscale_client.models.jobs_query import JobsQuery
95
+ from anyscale.sdk.anyscale_client.models.jobs_sort_field import JobsSortField
96
+ from anyscale.sdk.anyscale_client.models.page_query import PageQuery
97
+ from anyscale.sdk.anyscale_client.models.sort_by_clause_jobs_sort_field import (
98
+ SortByClauseJobsSortField,
99
+ )
100
+ from anyscale.sdk.anyscale_client.models.sort_order import SortOrder
101
+ from anyscale.sdk.anyscale_client.models.update_cluster import UpdateCluster
102
+ from anyscale.sdk.anyscale_client.rest import ApiException as ExternalApiException
103
+ from anyscale.shared_anyscale_utils.bytes_util import Bytes
104
+ from anyscale.shared_anyscale_utils.conf import ANYSCALE_HOST
105
+ from anyscale.shared_anyscale_utils.latest_ray_version import LATEST_RAY_VERSION
106
+ from anyscale.util import (
107
+ get_cluster_model_for_current_workspace,
108
+ get_endpoint,
109
+ is_anyscale_workspace,
110
+ )
111
+ from anyscale.utils.connect_helpers import search_entities
112
+ from anyscale.utils.runtime_env import (
113
+ is_workspace_dependency_tracking_disabled,
114
+ parse_dot_env_file,
115
+ WORKSPACE_REQUIREMENTS_FILE_PATH,
116
+ zip_local_dir,
117
+ )
118
+ from anyscale.utils.workspace_notification import (
119
+ WORKSPACE_NOTIFICATION_ADDRESS,
120
+ WorkspaceNotification,
121
+ )
122
+
123
+
124
+ WORKSPACE_ID_ENV_VAR = "ANYSCALE_EXPERIMENTAL_WORKSPACE_ID"
125
+ OVERWRITE_EXISTING_CLOUD_STORAGE_FILES = (
126
+ os.environ.get("ANYSCALE_OVERWRITE_EXISTING_CLOUD_STORAGE_FILES", "0") == "1"
127
+ )
128
+
129
+ # internal_logger is used for logging internal errors or debug messages that we do not expect users to see.
130
+ internal_logger = logging.getLogger(__name__)
131
+
132
+ # A decorator to handle ApiException and raise ValueError with the error message.
133
+ def handle_api_exceptions(func):
134
+ @wraps(func)
135
+ def wrapper(*args, **kwargs):
136
+ try:
137
+ return func(*args, **kwargs)
138
+ except (ApiException, InternalApiException, ExternalApiException) as e:
139
+ if e.status >= 400 and e.status < 500:
140
+ try:
141
+ body_dict = json.loads(e.body)
142
+ msg = body_dict["error"]["detail"]
143
+ raise ValueError(msg) from None
144
+ except KeyError:
145
+ # ApiException doesn't conform to expected format, raise original error
146
+ raise e from None
147
+ raise e from None
148
+
149
+ return wrapper
150
+
151
+
152
+ @contextlib.contextmanager
153
+ def set_env(**environ):
154
+ """
155
+ Temporarily set the process environment variables.
156
+
157
+ >>> with set_env(PLUGINS_DIR='test/plugins'):
158
+ ... "PLUGINS_DIR" in os.environ
159
+ True
160
+
161
+ >>> "PLUGINS_DIR" in os.environ
162
+ False
163
+
164
+ :type environ: dict[str, unicode]
165
+ :param environ: Environment variables to set
166
+ """
167
+ old_environ = dict(os.environ)
168
+ os.environ.update(environ)
169
+ try:
170
+ yield
171
+ finally:
172
+ os.environ.clear()
173
+ os.environ.update(old_environ)
174
+
175
+
176
+ class AWSS3ClientInterface(ABC):
177
+ @abstractmethod
178
+ def download_fileobj(self, Bucket: str, Key: str, Fileobj: IO[Any],) -> None:
179
+ """Download a file from an S3 bucket to a file-like object."""
180
+ raise NotImplementedError
181
+
182
+
183
+ class GCSBlobInterface(ABC):
184
+ @abstractmethod
185
+ def download_to_file(self, fileobj: IO[Any]) -> None:
186
+ """Download the blob to a file-like object."""
187
+ raise NotImplementedError
188
+
189
+ @abstractmethod
190
+ def exists(self) -> bool:
191
+ """Check if the blob exists."""
192
+ raise NotImplementedError
193
+
194
+
195
+ class GCSBucketInterface(ABC):
196
+ @abstractmethod
197
+ def blob(self, object_name: str) -> GCSBlobInterface:
198
+ """Get a blob object for the given object name."""
199
+ raise NotImplementedError
200
+
201
+
202
+ class GCPGCSClientInterface(ABC):
203
+ @abstractmethod
204
+ def bucket(self, bucket: str) -> GCSBucketInterface:
205
+ """Get a bucket object for the given bucket name."""
206
+ raise NotImplementedError
207
+
208
+
209
+ class AnyscaleClient(AnyscaleClientInterface):
210
+ # Number of entries to fetch per request for list endpoints.
211
+ LIST_ENDPOINT_COUNT = 50
212
+
213
+ def __init__(
214
+ self,
215
+ *,
216
+ api_clients: Optional[Tuple[ExternalApi, InternalApi]] = None,
217
+ sleep: Optional[Callable[[float], None]] = None,
218
+ workspace_requirements_file_path: str = WORKSPACE_REQUIREMENTS_FILE_PATH,
219
+ logger: Optional[BlockLogger] = None,
220
+ host: Optional[str] = None,
221
+ s3_client: Optional[AWSS3ClientInterface] = None,
222
+ gcs_client: Optional[GCPGCSClientInterface] = None,
223
+ ):
224
+ if api_clients is None:
225
+ auth_block: AuthenticationBlock = get_auth_api_client(
226
+ raise_structured_exception=True
227
+ )
228
+ api_clients = (auth_block.anyscale_api_client, auth_block.api_client)
229
+
230
+ self._external_api_client, self._internal_api_client = api_clients
231
+ self._workspace_requirements_file_path = workspace_requirements_file_path
232
+ self._sleep = sleep or time.sleep
233
+ self._s3_client = s3_client
234
+ self._gcs_client = gcs_client
235
+
236
+ # Cached IDs and models to avoid duplicate lookups.
237
+ self._default_project_id_from_cloud_id: Dict[Optional[str], str] = {}
238
+ self._cloud_id_cache: Dict[Optional[str], str] = {}
239
+ self._current_workspace_cluster: Optional[Cluster] = None
240
+ self._logger = logger or BlockLogger()
241
+ self._host = host or ANYSCALE_HOST
242
+
243
+ @property
244
+ def s3_client(self) -> AWSS3ClientInterface:
245
+ if self._s3_client is None:
246
+ # initialize the s3 client lazily so that we import the boto3 library only when needed.
247
+ try:
248
+ import boto3
249
+ import botocore.config
250
+ except ImportError:
251
+ raise RuntimeError(
252
+ "Could not import the Amazon S3 Python API via `import boto3`. Please check your installation or try running `pip install boto3`."
253
+ )
254
+ self._s3_client = boto3.client( # type: ignore
255
+ "s3", config=botocore.config.Config(signature_version="s3v4")
256
+ )
257
+ return self._s3_client # type: ignore
258
+
259
+ @property
260
+ def gcs_client(self) -> GCPGCSClientInterface:
261
+ if self._gcs_client is None:
262
+ # initialize the gcs client lazily so that we import the google cloud storage library only when needed.
263
+ try:
264
+ from google.cloud import storage
265
+ except ImportError:
266
+ raise RuntimeError(
267
+ "Could not import the Google Storage Python API via `from google.cloud import storage`. Please check your installation or try running `pip install --upgrade google-cloud-storage`."
268
+ )
269
+ self._gcs_client = storage.Client()
270
+ return self._gcs_client # type: ignore
271
+
272
+ @property
273
+ def host(self) -> str:
274
+ return self._host
275
+
276
+ @property
277
+ def logger(self) -> BlockLogger:
278
+ return self._logger
279
+
280
+ def get_job_ui_url(self, job_id: str) -> str:
281
+ return get_endpoint(f"/jobs/{job_id}", host=self.host)
282
+
283
+ def get_service_ui_url(self, service_id: str) -> str:
284
+ return get_endpoint(f"/services/{service_id}", host=self.host)
285
+
286
+ def get_compute_config_ui_url(
287
+ self, compute_config_id: str, *, cloud_id: str
288
+ ) -> str:
289
+ return get_endpoint(
290
+ f"/v2/{cloud_id}/compute-configs/{compute_config_id}", host=self.host
291
+ )
292
+
293
+ def get_build_ui_url(self, cluster_env_id, build_id: str) -> str:
294
+ return get_endpoint(
295
+ f"v2/container-images/{cluster_env_id}/versions/{build_id}", host=self.host
296
+ )
297
+
298
+ def get_current_workspace_id(self) -> Optional[str]:
299
+ return os.environ.get(WORKSPACE_ID_ENV_VAR, None)
300
+
301
+ def inside_workspace(self) -> bool:
302
+ return self.get_current_workspace_id() is not None
303
+
304
+ def get_workspace_requirements_path(self) -> Optional[str]:
305
+ if (
306
+ not self.inside_workspace()
307
+ or is_workspace_dependency_tracking_disabled()
308
+ or not pathlib.Path(self._workspace_requirements_file_path).is_file()
309
+ ):
310
+ return None
311
+
312
+ return self._workspace_requirements_file_path
313
+
314
+ def _download_file_from_google_cloud_storage(
315
+ self, bucket: str, object_name: str
316
+ ) -> Optional[bytes]:
317
+ try:
318
+ bucket_obj = self.gcs_client.bucket(bucket)
319
+ blob = bucket_obj.blob(object_name)
320
+ fileobj = io.BytesIO()
321
+ if blob.exists():
322
+ blob.download_to_file(fileobj)
323
+ return fileobj.getvalue()
324
+ return None
325
+ except Exception as e: # noqa: BLE001
326
+ raise RuntimeError(
327
+ f"Failed to download the working directory from Google Cloud Storage. Error {e!r}"
328
+ "Please validate you have exported cloud credentials with the correct read permissions and the intended bucket exists in your Cloud Storage account. "
329
+ ) from e
330
+
331
+ def _download_file_from_s3(self, bucket: str, object_key: str) -> Optional[bytes]:
332
+ try:
333
+ from botocore.exceptions import ClientError
334
+ except Exception: # noqa: BLE001
335
+ raise RuntimeError(
336
+ "Could not download file from S3: Could not import the Amazon S3 Python API via `import boto3`. Please check your installation or try running `pip install boto3`."
337
+ )
338
+ try:
339
+ fileobj = io.BytesIO()
340
+ self.s3_client.download_fileobj(bucket, object_key, fileobj)
341
+ return fileobj.getvalue()
342
+ except ClientError as e:
343
+ if e.response["Error"]["Code"] == "404":
344
+ return None
345
+ raise
346
+ except Exception as e: # noqa: BLE001
347
+ raise RuntimeError(
348
+ f"Failed to download the working directory from S3. Error {e!r}"
349
+ "Please validate you have exported cloud credentials with the correct read permissions and the intended bucket exists in your S3 account. "
350
+ ) from e
351
+
352
+ def _download_file_from_remote_storage(self, remote_uri: str) -> Optional[bytes]:
353
+ parsed_uri = urlparse(remote_uri)
354
+ service = parsed_uri.scheme
355
+ bucket = parsed_uri.netloc
356
+ object_name = parsed_uri.path.lstrip("/")
357
+ if service == "s3":
358
+ return self._download_file_from_s3(bucket, object_name)
359
+ if service == "gs":
360
+ return self._download_file_from_google_cloud_storage(bucket, object_name)
361
+ return None
362
+
363
+ def get_workspace_env_vars(self) -> Optional[Dict[str, str]]:
364
+ system_storage_path = os.environ.get("ANYSCALE_INTERNAL_SYSTEM_STORAGE", "")
365
+ workspace_id = os.environ.get(WORKSPACE_ID_ENV_VAR, "")
366
+ workspace_artifact_path = (
367
+ os.path.join(
368
+ system_storage_path, "workspace_tracking_dependencies", workspace_id,
369
+ )
370
+ if workspace_id and system_storage_path
371
+ else ""
372
+ )
373
+ workspace_dot_env_path = (
374
+ os.path.join(workspace_artifact_path, ".env")
375
+ if workspace_artifact_path
376
+ else ""
377
+ )
378
+
379
+ if not self.inside_workspace() or not workspace_dot_env_path:
380
+ return None
381
+
382
+ dot_env = self._download_file_from_remote_storage(workspace_dot_env_path)
383
+ if dot_env:
384
+ parsed_dot_env = parse_dot_env_file(dot_env)
385
+ if parsed_dot_env:
386
+ self.logger.info(
387
+ f"Using workspace runtime dependencies env vars: {parsed_dot_env}."
388
+ )
389
+ return parsed_dot_env
390
+ return None
391
+
392
+ @handle_api_exceptions
393
+ def get_current_workspace_cluster(self) -> Optional[Cluster]:
394
+ # Checks for the existence of the ANYSCALE_EXPERIMENTAL_WORKSPACE_ID env var.
395
+ if not is_anyscale_workspace():
396
+ return None
397
+
398
+ if self._current_workspace_cluster is None:
399
+ # Picks up the cluster ID from the ANYSCALE_SESSION_ID env var.
400
+ self._current_workspace_cluster = get_cluster_model_for_current_workspace(
401
+ self._external_api_client
402
+ )
403
+
404
+ return self._current_workspace_cluster
405
+
406
+ def _get_project_id_by_name(
407
+ self, *, parent_cloud_id: Optional[str] = None, name: Optional[str] = None
408
+ ) -> str:
409
+ """Resolves `name`, a project name, to a project ID.
410
+
411
+ Args:
412
+ parent_cloud_id: If specified, return the project that has this `parent_cloud_id`. \
413
+ Else (`None`), return the first project with the given `name`. \
414
+ Defaults to `None`.
415
+ name: The name of the project.
416
+ """
417
+ # Find if project with name already exists
418
+ matching_projects = self._internal_api_client.find_project_by_project_name_api_v2_projects_find_by_name_get(
419
+ name
420
+ ).results
421
+ if len(matching_projects) == 0:
422
+ raise ValueError(f"Project '{name}' was not found.")
423
+ else:
424
+ for project in matching_projects:
425
+ if (
426
+ parent_cloud_id is None
427
+ or project.parent_cloud_id == parent_cloud_id
428
+ ):
429
+ return project.id
430
+ raise ValueError(
431
+ f"{len(matching_projects)} project(s) found with name '{name}' and none matched cloud_id '{parent_cloud_id}'"
432
+ )
433
+
434
+ def _get_project_id_by_cloud_id(
435
+ self, *, parent_cloud_id: Optional[str] = None,
436
+ ) -> str:
437
+ workspace_cluster = self.get_current_workspace_cluster()
438
+ if workspace_cluster is not None:
439
+ if (
440
+ workspace_cluster.cluster_compute_config is not None
441
+ and workspace_cluster.cluster_compute_config.cloud_id == parent_cloud_id
442
+ ):
443
+ return workspace_cluster.project_id
444
+ elif workspace_cluster.cluster_compute_id is not None:
445
+ workspace_cluster_compute = self.get_compute_config(
446
+ workspace_cluster.cluster_compute_id
447
+ )
448
+ if (
449
+ workspace_cluster_compute is not None
450
+ and workspace_cluster_compute.config is not None
451
+ and workspace_cluster_compute.config.cloud_id == parent_cloud_id
452
+ ):
453
+ return workspace_cluster.project_id
454
+
455
+ if self._default_project_id_from_cloud_id.get(parent_cloud_id) is None:
456
+ # Cloud isolation organizations follow the permissions model in https://docs.anyscale.com/organization-and-user-account/access-controls
457
+ # TODO(nikita): Remove this FF check after completing the cloud isolation migration in Q2 2024
458
+ cloud_isolation_ff_on = self._internal_api_client.check_is_feature_flag_on_api_v2_userinfo_check_is_feature_flag_on_get(
459
+ "cloud-isolation-phase-1"
460
+ ).result.is_on
461
+ default_project: Project = self._external_api_client.get_default_project(
462
+ parent_cloud_id=(parent_cloud_id if cloud_isolation_ff_on else None)
463
+ ).result
464
+ self._default_project_id_from_cloud_id[parent_cloud_id] = default_project.id
465
+
466
+ return self._default_project_id_from_cloud_id[parent_cloud_id]
467
+
468
+ @handle_api_exceptions
469
+ def get_project_id(
470
+ self, *, parent_cloud_id: Optional[str] = None, name: Optional[str] = None
471
+ ) -> str:
472
+ if name is not None:
473
+ return self._get_project_id_by_name(
474
+ parent_cloud_id=parent_cloud_id, name=name
475
+ )
476
+ else:
477
+ return self._get_project_id_by_cloud_id(parent_cloud_id=parent_cloud_id)
478
+
479
+ def _get_cloud_id_for_compute_config_id(self, compute_config_id: str) -> str:
480
+ cluster_compute: ClusterCompute = self._external_api_client.get_cluster_compute(
481
+ compute_config_id
482
+ ).result
483
+ cluster_compute_config: ClusterComputeConfig = cluster_compute.config
484
+ return cluster_compute_config.cloud_id
485
+
486
+ def _get_cloud_id_by_name(self, cloud_name: str) -> Optional[str]:
487
+ try:
488
+ return self._internal_api_client.find_cloud_by_name_api_v2_clouds_find_by_name_post(
489
+ CloudNameOptions(name=cloud_name),
490
+ ).result.id
491
+ except InternalApiException as e:
492
+ if e.status == 404:
493
+ return None
494
+
495
+ raise e from None
496
+
497
+ @handle_api_exceptions
498
+ def get_cloud_id(
499
+ self, cloud_name: Optional[str] = None, compute_config_id: Optional[str] = None
500
+ ) -> str:
501
+ if cloud_name is not None and compute_config_id is not None:
502
+ raise ValueError(
503
+ "Only one of cloud_name or compute_config_id should be provided."
504
+ )
505
+
506
+ if compute_config_id is not None:
507
+ return self._get_cloud_id_for_compute_config_id(compute_config_id)
508
+
509
+ if cloud_name in self._cloud_id_cache:
510
+ return self._cloud_id_cache[cloud_name]
511
+
512
+ if cloud_name is not None:
513
+ cloud_id = self._get_cloud_id_by_name(cloud_name)
514
+ if cloud_id is None:
515
+ raise RuntimeError(f"Cloud '{cloud_name}' not found.")
516
+ elif self.inside_workspace():
517
+ workspace_cluster = self.get_current_workspace_cluster()
518
+ assert workspace_cluster is not None
519
+ # NOTE(edoakes): the Cluster model has a compute_config_config model that includes
520
+ # its cloud ID, but it's not always populated.
521
+ # TODO(edoakes): add cloud_id to the Cluster model to avoid a second RTT.
522
+ cloud_id = self._get_cloud_id_for_compute_config_id(
523
+ workspace_cluster.cluster_compute_id
524
+ )
525
+ else:
526
+ cloud_id = self._external_api_client.get_default_cloud().result.id
527
+
528
+ assert cloud_id is not None
529
+ self._cloud_id_cache[cloud_name] = cloud_id
530
+ return cloud_id
531
+
532
+ @handle_api_exceptions
533
+ def get_cloud(self, *, cloud_id: str) -> Optional[Cloud]:
534
+ try:
535
+ cloud: Cloud = self._internal_api_client.get_cloud_api_v2_clouds_cloud_id_get(
536
+ cloud_id
537
+ ).result
538
+ return cloud
539
+ except InternalApiException as e:
540
+ if e.status == 404:
541
+ return None
542
+
543
+ raise e from None
544
+
545
+ @handle_api_exceptions
546
+ def create_compute_config(
547
+ self, config: ComputeTemplateConfig, *, name: Optional[str] = None
548
+ ) -> Tuple[str, str]:
549
+ result: ComputeTemplate = self._internal_api_client.create_compute_template_api_v2_compute_templates_post(
550
+ create_compute_template=CreateComputeTemplate(
551
+ config=config, name=name, anonymous=name is None, new_version=True
552
+ )
553
+ ).result
554
+ return f"{result.name}:{result.version}", result.id
555
+
556
+ @handle_api_exceptions
557
+ def get_compute_config(
558
+ self, compute_config_id: str
559
+ ) -> Optional[DecoratedComputeTemplate]:
560
+ try:
561
+ return self._internal_api_client.get_compute_template_api_v2_compute_templates_template_id_get(
562
+ compute_config_id
563
+ ).result
564
+ except InternalApiException as e:
565
+ if e.status == 404:
566
+ return None
567
+
568
+ raise e from None
569
+
570
+ @handle_api_exceptions
571
+ def get_compute_config_id(
572
+ self,
573
+ compute_config_name: Optional[str] = None,
574
+ *,
575
+ include_archived: bool = False,
576
+ ) -> Optional[str]:
577
+ if compute_config_name is not None:
578
+ name, version = parse_cluster_compute_name_version(compute_config_name)
579
+ if version is None:
580
+ # Setting `version=-1` will return only the latest version if there are multiple.
581
+ version = -1
582
+ cluster_computes = self._internal_api_client.search_compute_templates_api_v2_compute_templates_search_post(
583
+ ComputeTemplateQuery(
584
+ orgwide=True,
585
+ name={"equals": name},
586
+ include_anonymous=True,
587
+ archive_status=ArchiveStatus.ALL
588
+ if include_archived
589
+ else ArchiveStatus.NOT_ARCHIVED,
590
+ version=version,
591
+ )
592
+ ).results
593
+
594
+ if len(cluster_computes) == 0:
595
+ return None
596
+
597
+ compute_template: DecoratedComputeTemplate = cluster_computes[0]
598
+ return compute_template.id
599
+
600
+ # If the compute config name is not provided, we pick an appropriate default.
601
+ #
602
+ # - If running in a workspace:
603
+ # * If auto_select_worker_config enabled: we switch over to a standardized
604
+ # default compute config (copying over any cluster-level attributes, e.g.
605
+ # max-gpus).
606
+ # * Otherwise, we use the workspace's compute config.
607
+ #
608
+ # - Otherwise, we use the default compute config provided by the API.
609
+
610
+ workspace_cluster = self.get_current_workspace_cluster()
611
+ if workspace_cluster is not None:
612
+ workspace_compute_config: DecoratedComputeTemplate = self.get_compute_config(
613
+ workspace_cluster.cluster_compute_id
614
+ )
615
+ workspace_config: ClusterComputeConfig = workspace_compute_config.config
616
+ if workspace_config.auto_select_worker_config:
617
+ standard_template = self._build_standard_compute_template_from_existing_auto_config(
618
+ workspace_config
619
+ )
620
+ _, compute_config_id = self.create_compute_config(standard_template)
621
+ return compute_config_id
622
+ else:
623
+ return workspace_cluster.cluster_compute_id
624
+
625
+ return self.get_default_compute_config(cloud_id=self.get_cloud_id()).id
626
+
627
+ @handle_api_exceptions
628
+ def archive_compute_config(self, *, compute_config_id):
629
+ self._internal_api_client.archive_compute_template_api_v2_compute_templates_compute_template_id_archive_post(
630
+ compute_config_id
631
+ )
632
+
633
+ @handle_api_exceptions
634
+ def get_default_compute_config(self, *, cloud_id: str) -> ClusterCompute:
635
+ return self._external_api_client.get_default_cluster_compute(
636
+ cloud_id=cloud_id,
637
+ ).result
638
+
639
+ def _build_standard_compute_template_from_existing_auto_config(
640
+ self, compute_config: ClusterComputeConfig
641
+ ) -> ComputeTemplateConfig:
642
+ """
643
+ Build a standard compute template config from an existing compute config.
644
+
645
+ 1. Pull the default compute template config.
646
+ 2. Disable scheduling on the head node.
647
+ 3. Enable auto_select_worker_config.
648
+ 4. Copy any cluster-level flags from the provided compute config to the template.
649
+ """
650
+ # Retrieve the default cluster compute config for the cloud.
651
+ default_compute_template: DecoratedComputeTemplate = self._external_api_client.get_default_cluster_compute(
652
+ cloud_id=compute_config.cloud_id,
653
+ ).result.config
654
+
655
+ # Disable head node scheduling.
656
+ if default_compute_template.head_node_type.resources is None:
657
+ default_compute_template.head_node_type.resources = {}
658
+ default_compute_template.head_node_type.resources["CPU"] = 0
659
+
660
+ # Ensure auto_select_worker_config is enabled.
661
+ default_compute_template.auto_select_worker_config = True
662
+
663
+ # Copy flags set at a cluster level over to the workspace.
664
+ #
665
+ # NOTE (shomilj): If there are more attributes we want to
666
+ # persist from the provided compute config --> the compute
667
+ # config used for deploying the service, we should copy them
668
+ # over here.
669
+ default_compute_template.flags = compute_config.flags
670
+
671
+ return default_compute_template
672
+
673
+ @handle_api_exceptions
674
+ def get_cluster_env_build(self, build_id: str) -> Optional[ClusterEnvironmentBuild]:
675
+ return self._external_api_client.get_cluster_environment_build(build_id).result
676
+
677
+ @handle_api_exceptions
678
+ def get_cluster_env_build_image_uri(
679
+ self, cluster_env_build_id: str, use_image_alias: bool = False
680
+ ) -> Optional[ImageURI]:
681
+ try:
682
+ build: ClusterEnvironmentBuild = self._external_api_client.get_cluster_environment_build(
683
+ cluster_env_build_id
684
+ ).result
685
+ cluster_env = self._external_api_client.get_cluster_environment(
686
+ build.cluster_environment_id
687
+ ).result
688
+ return ImageURI.from_cluster_env_build(cluster_env, build, use_image_alias)
689
+ except ExternalApiException as e:
690
+ if e.status == 404:
691
+ return None
692
+
693
+ raise e from None
694
+
695
+ @handle_api_exceptions
696
+ def get_default_build_id(self) -> str:
697
+ workspace_cluster = self.get_current_workspace_cluster()
698
+ if workspace_cluster is not None:
699
+ return workspace_cluster.cluster_environment_build_id
700
+ result: ClusterEnvironmentBuild = self._external_api_client.get_default_cluster_environment_build(
701
+ DEFAULT_PYTHON_VERSION, DEFAULT_RAY_VERSION,
702
+ ).result
703
+ return result.id
704
+
705
+ @handle_api_exceptions
706
+ def get_cluster_env_by_name(self, name: str) -> Optional[ClusterEnvironment]:
707
+ resp = self._external_api_client.search_cluster_environments(
708
+ ClusterEnvironmentsQuery(
709
+ name=TextQuery(equals=name), # pyright: ignore reportGeneralTypeIssues
710
+ paging=PageQuery(count=1),
711
+ include_anonymous=True,
712
+ )
713
+ )
714
+ if resp.results:
715
+ return resp.results[0]
716
+ return None
717
+
718
+ @handle_api_exceptions
719
+ def list_cluster_env_builds(
720
+ self, cluster_env_id: str,
721
+ ) -> Generator[ClusterEnvironmentBuild, None, None]:
722
+ paging_token = None
723
+ while True:
724
+ resp: ClusterenvironmentbuildListResponse = self._external_api_client.list_cluster_environment_builds(
725
+ cluster_environment_id=cluster_env_id,
726
+ count=self.LIST_ENDPOINT_COUNT,
727
+ paging_token=paging_token,
728
+ desc=True,
729
+ )
730
+ for build in resp.results:
731
+ yield build
732
+
733
+ if resp.metadata.next_paging_token is None:
734
+ break
735
+ paging_token = resp.metadata.next_paging_token
736
+
737
+ def _wait_for_build_to_succeed(
738
+ self, build_id: str, poll_interval_seconds=3, timeout_secs=3600,
739
+ ):
740
+ """Periodically check the status of the build operation until it completes.
741
+ Raise a RuntimeError if the build fails or cancelled.
742
+ Raise a TimeoutError if the build does not complete within the timeout.
743
+ """
744
+ elapsed_secs = 0
745
+ while elapsed_secs < timeout_secs:
746
+ build = self._external_api_client.get_cluster_environment_build(
747
+ build_id
748
+ ).result
749
+ if build.status == ClusterEnvironmentBuildStatus.SUCCEEDED:
750
+ self.logger.info("")
751
+ return
752
+ elif build.status == ClusterEnvironmentBuildStatus.FAILED:
753
+ raise RuntimeError(f"Image build {build_id} failed.")
754
+ elif build.status == ClusterEnvironmentBuildStatus.CANCELED:
755
+ raise RuntimeError(f"Image build {build_id} unexpectedly cancelled.")
756
+
757
+ elapsed_secs += poll_interval_seconds
758
+ self.logger.info(
759
+ f"Waiting for image build to complete. Elapsed time: {elapsed_secs} seconds.",
760
+ end="\r",
761
+ )
762
+ self._sleep(poll_interval_seconds)
763
+ raise TimeoutError(
764
+ f"Timed out waiting for image build {build_id} to complete after {timeout_secs}s."
765
+ )
766
+
767
+ def _find_or_create_cluster_env(
768
+ self,
769
+ cluster_env_name: str,
770
+ anonymous: bool,
771
+ *,
772
+ image_uri: Optional[str] = None,
773
+ registry_login_secret: Optional[str] = None,
774
+ ray_version: Optional[str] = None,
775
+ ) -> ClusterEnvironment:
776
+ """
777
+ Find or create a cluster environment with the given name.
778
+
779
+ There're two possible race conditions:
780
+ 1) A tries to create a cluster env with the same name as B, but B has already created it.
781
+ -> A will get a 409 conflict error and should retry to get the existing cluster env.
782
+ 2) A and B creates two identical builds under the same cluster env. This would cause job queue to
783
+ reject the job submission.
784
+ -> Cluster env and BYOD build are created within the same transaction, so the latter one will fail
785
+ with a 409 conflict error. The former one will succeed and the latter one should retry to get the
786
+ existing cluster env.
787
+ """
788
+ existing_cluster_env = self.get_cluster_env_by_name(cluster_env_name)
789
+ if existing_cluster_env is not None:
790
+ return existing_cluster_env
791
+
792
+ try:
793
+ if image_uri:
794
+ # For BYOD builds, we should create a build along with the cluster env.
795
+ cluster_environment = self._external_api_client.create_byod_cluster_environment(
796
+ CreateBYODClusterEnvironment(
797
+ name=cluster_env_name,
798
+ config_json=CreateBYODClusterEnvironmentConfigurationSchema(
799
+ docker_image=image_uri,
800
+ ray_version=ray_version
801
+ if ray_version
802
+ else LATEST_RAY_VERSION,
803
+ registry_login_secret=registry_login_secret,
804
+ ),
805
+ anonymous=anonymous,
806
+ )
807
+ ).result
808
+ else:
809
+ cluster_environment = self._external_api_client.create_cluster_environment(
810
+ CreateClusterEnvironment(name=cluster_env_name, anonymous=anonymous)
811
+ ).result
812
+ return cluster_environment
813
+ except ExternalApiException as e:
814
+ if e.status != 409:
815
+ raise e from None
816
+ # Retry to get the existing cluster env because it might be created by another process.
817
+ existing_cluster_env = self.get_cluster_env_by_name(cluster_env_name)
818
+ if existing_cluster_env is None:
819
+ raise e from None
820
+ return existing_cluster_env
821
+
822
+ @handle_api_exceptions
823
+ def get_cluster_env_build_id_from_containerfile(
824
+ self,
825
+ cluster_env_name: str,
826
+ containerfile: str,
827
+ anonymous: bool = True,
828
+ ray_version: Optional[str] = None,
829
+ ) -> str:
830
+ cluster_env = self._find_or_create_cluster_env(
831
+ cluster_env_name, anonymous=anonymous
832
+ )
833
+ for build in self.list_cluster_env_builds(cluster_env.id):
834
+ if (
835
+ build.status == ClusterEnvironmentBuildStatus.SUCCEEDED
836
+ and build.containerfile == containerfile
837
+ # we don't need to check the ray_version because checking the containerfile is enough.
838
+ ):
839
+ return build.id
840
+
841
+ try:
842
+ build_op = self._external_api_client.create_cluster_environment_build(
843
+ CreateClusterEnvironmentBuild(
844
+ cluster_environment_id=cluster_env.id,
845
+ containerfile=containerfile,
846
+ ray_version=ray_version, # we don't use the latest version here if ray_version is Noneb/c the backend will try to parse the base image to decide the ray version.
847
+ )
848
+ ).result
849
+ except ExternalApiException as e:
850
+ if e.status == 400:
851
+ raise RuntimeError(
852
+ "Invalid containerfile. Please check the syntax and try again.",
853
+ e.body,
854
+ ) from None
855
+
856
+ build_url = self.get_build_ui_url(
857
+ cluster_env.id, build_op.cluster_environment_build_id
858
+ )
859
+ self.logger.info(f"Building image. View it in the UI: {build_url}")
860
+ self._wait_for_build_to_succeed(build_op.cluster_environment_build_id)
861
+ self.logger.info("Image build succeeded.")
862
+
863
+ return build_op.cluster_environment_build_id
864
+
865
+ @handle_api_exceptions
866
+ def get_cluster_env_build_id_from_image_uri(
867
+ self,
868
+ image_uri: ImageURI,
869
+ registry_login_secret: Optional[str] = None,
870
+ ray_version: Optional[str] = None,
871
+ name: Optional[str] = None,
872
+ ) -> str:
873
+ if image_uri.is_cluster_env_image():
874
+ identifier = image_uri.to_cluster_env_identifier()
875
+ try:
876
+ build = self._external_api_client.find_cluster_environment_build_by_identifier(
877
+ identifier=identifier
878
+ ).result
879
+ if build.status == ClusterEnvironmentBuildStatus.SUCCEEDED:
880
+ return build.id
881
+ else:
882
+ raise RuntimeError(
883
+ f"Legacy cluster environment build '{identifier}' is not a successful build."
884
+ )
885
+ except ExternalApiException as e:
886
+ if e.status == 404:
887
+ raise RuntimeError(
888
+ f"Legacy cluster environment '{identifier}' is not found."
889
+ )
890
+ elif image_uri.is_default_image():
891
+ # Default image
892
+ cluster_envs = self._internal_api_client.list_application_templates_api_v2_application_templates_get(
893
+ image_name_contains=image_uri.image_uri
894
+ ).results
895
+ for cluster_env in cluster_envs:
896
+ if (
897
+ cluster_env.latest_build is not None
898
+ and cluster_env.latest_build.docker_image_name
899
+ == image_uri.image_uri
900
+ ):
901
+ return cluster_env.latest_build.id
902
+ raise RuntimeError(f"Default image '{image_uri.image_uri}' is not found.")
903
+
904
+ # BYOD image
905
+ cluster_env_name = name if name else image_uri.to_cluster_env_name()
906
+ image_uri_str = str(image_uri)
907
+ cluster_env = self._find_or_create_cluster_env(
908
+ cluster_env_name,
909
+ anonymous=not name,
910
+ image_uri=image_uri_str,
911
+ registry_login_secret=registry_login_secret,
912
+ ray_version=ray_version,
913
+ )
914
+ for build in self.list_cluster_env_builds(cluster_env.id):
915
+ if (
916
+ build.docker_image_name == image_uri_str
917
+ and build.registry_login_secret == registry_login_secret
918
+ and build.status == ClusterEnvironmentBuildStatus.SUCCEEDED
919
+ and (ray_version is None or build.ray_version == ray_version)
920
+ ):
921
+ return build.id
922
+
923
+ # Still create a new build if the cluster env already exists but the build does not match the image_uri.
924
+ result = self._external_api_client.create_cluster_environment_build(
925
+ CreateClusterEnvironmentBuild(
926
+ # For historical reasons, we have to use docker_image_name instead of image_uri; but it is just a URI to the image.
927
+ cluster_environment_id=cluster_env.id,
928
+ docker_image_name=image_uri_str,
929
+ registry_login_secret=registry_login_secret,
930
+ ray_version=ray_version if ray_version else LATEST_RAY_VERSION,
931
+ )
932
+ ).result
933
+
934
+ assert result.completed
935
+ return result.cluster_environment_build_id
936
+
937
+ @handle_api_exceptions
938
+ def send_workspace_notification(
939
+ self, notification: WorkspaceNotification,
940
+ ):
941
+ if not self.inside_workspace():
942
+ return
943
+
944
+ try:
945
+ r = requests.post(WORKSPACE_NOTIFICATION_ADDRESS, json=notification.dict())
946
+ r.raise_for_status()
947
+ except Exception:
948
+ internal_logger.exception(
949
+ "Failed to send workspace notification. "
950
+ "This should not happen, so please contact Anyscale support."
951
+ )
952
+
953
+ @handle_api_exceptions
954
+ def get_service(
955
+ self, name: str, *, cloud: Optional[str], project: Optional[str]
956
+ ) -> Optional[ServiceModel]:
957
+ # TODO(edoakes): this endpoint is very slow and there's no reason we should need
958
+ # to use this complex list endpoint just to fetch a service by name.
959
+ paging_token = None
960
+ cloud_id = self.get_cloud_id(cloud_name=cloud)
961
+ project_id = self.get_project_id(parent_cloud_id=cloud_id, name=project)
962
+ service: Optional[ServiceModel] = None
963
+ while True:
964
+ resp = self._external_api_client.list_services(
965
+ project_id=project_id,
966
+ name=name,
967
+ count=self.LIST_ENDPOINT_COUNT,
968
+ paging_token=paging_token,
969
+ )
970
+ for result in resp.results:
971
+ if result.name == name:
972
+ service = result
973
+ break
974
+
975
+ paging_token = resp.metadata.next_paging_token
976
+ if service is not None or paging_token is None:
977
+ break
978
+
979
+ return service
980
+
981
+ @handle_api_exceptions
982
+ def get_project(self, project_id: str) -> Optional[Project]:
983
+ return self._internal_api_client.get_project_api_v2_projects_project_id_get(
984
+ project_id
985
+ ).result
986
+
987
+ @handle_api_exceptions
988
+ def get_job(
989
+ self,
990
+ *,
991
+ name: Optional[str],
992
+ job_id: Optional[str],
993
+ cloud: Optional[str],
994
+ project: Optional[str],
995
+ ) -> Optional[ProductionJob]:
996
+ if job_id is not None:
997
+ try:
998
+ return self._external_api_client.get_production_job(job_id).result
999
+ except ExternalApiException as e:
1000
+ if e.status == 404:
1001
+ return None
1002
+ raise e from None
1003
+ else:
1004
+ paging_token = None
1005
+ cloud_id = self.get_cloud_id(cloud_name=cloud)
1006
+ project_id = self.get_project_id(parent_cloud_id=cloud_id, name=project)
1007
+ result: Optional[ProductionJob] = None
1008
+ while True:
1009
+ resp = self._external_api_client.list_production_jobs(
1010
+ project_id=project_id,
1011
+ name=name,
1012
+ count=self.LIST_ENDPOINT_COUNT,
1013
+ paging_token=paging_token,
1014
+ )
1015
+ for job in resp.results:
1016
+ if (
1017
+ job is not None
1018
+ and job.name == name
1019
+ and (result is None or job.created_at > result.created_at)
1020
+ ):
1021
+ result = job
1022
+
1023
+ paging_token = resp.metadata.next_paging_token
1024
+ if paging_token is None:
1025
+ break
1026
+
1027
+ return result
1028
+
1029
+ @handle_api_exceptions
1030
+ def get_job_runs(self, job_id: str) -> List[APIJobRun]:
1031
+ job_runs: List[APIJobRun] = search_entities(
1032
+ self._external_api_client.search_jobs,
1033
+ JobsQuery(
1034
+ ha_job_id=job_id,
1035
+ show_ray_client_runs_only=False,
1036
+ sort_by_clauses=[
1037
+ SortByClauseJobsSortField(
1038
+ sort_field=JobsSortField.CREATED_AT, sort_order=SortOrder.ASC,
1039
+ )
1040
+ ],
1041
+ paging=PageQuery(),
1042
+ ),
1043
+ )
1044
+ return job_runs
1045
+
1046
+ @handle_api_exceptions
1047
+ def rollout_service(self, model: ApplyServiceModel) -> ServiceModel:
1048
+ result: ServiceModel = self._external_api_client.rollout_service(model).result
1049
+ return result
1050
+
1051
+ @handle_api_exceptions
1052
+ def rollback_service(
1053
+ self, service_id: str, *, max_surge_percent: Optional[int] = None
1054
+ ) -> ServiceModel:
1055
+ result: ServiceModel = self._external_api_client.rollback_service(
1056
+ service_id,
1057
+ rollback_service_model=RollbackServiceModel(
1058
+ max_surge_percent=max_surge_percent
1059
+ ),
1060
+ )
1061
+ return result
1062
+
1063
+ @handle_api_exceptions
1064
+ def terminate_service(self, service_id: str) -> ServiceModel:
1065
+ result: ServiceModel = self._external_api_client.terminate_service(service_id)
1066
+ return result
1067
+
1068
+ @handle_api_exceptions
1069
+ def submit_job(self, model: CreateInternalProductionJob) -> InternalProductionJob:
1070
+ job: InternalProductionJob = self._internal_api_client.create_job_api_v2_decorated_ha_jobs_create_post(
1071
+ model,
1072
+ ).result
1073
+ return job
1074
+
1075
+ @handle_api_exceptions
1076
+ def terminate_job(self, job_id: str):
1077
+ self._external_api_client.terminate_job(job_id)
1078
+
1079
+ @handle_api_exceptions
1080
+ def archive_job(self, job_id: str):
1081
+ self._internal_api_client.archive_job_api_v2_decorated_ha_jobs_production_job_id_archive_post(
1082
+ job_id
1083
+ )
1084
+
1085
+ @handle_api_exceptions
1086
+ def upload_local_dir_to_cloud_storage(
1087
+ self,
1088
+ local_dir: str,
1089
+ *,
1090
+ cloud_id: str,
1091
+ excludes: Optional[List[str]] = None,
1092
+ overwrite_existing_file: bool = OVERWRITE_EXISTING_CLOUD_STORAGE_FILES,
1093
+ ) -> str:
1094
+ if not pathlib.Path(local_dir).is_dir():
1095
+ raise RuntimeError(f"Path '{local_dir}' is not a valid directory.")
1096
+
1097
+ with zip_local_dir(local_dir, excludes=excludes) as (
1098
+ _,
1099
+ zip_file_bytes,
1100
+ content_hash,
1101
+ ):
1102
+ file_name = RUNTIME_ENV_PACKAGE_FORMAT.format(content_hash=content_hash)
1103
+ request = CloudDataBucketPresignedUrlRequest(
1104
+ file_type=CloudDataBucketFileType.RUNTIME_ENV_PACKAGES,
1105
+ file_name=file_name,
1106
+ access_mode=CloudDataBucketAccessMode.WRITE,
1107
+ )
1108
+ info: CloudDataBucketPresignedUrlResponse = self._internal_api_client.generate_cloud_data_bucket_presigned_url_api_v2_clouds_cloud_id_generate_cloud_data_bucket_presigned_url_post(
1109
+ cloud_id, request
1110
+ ).result
1111
+
1112
+ # Skip the upload entirely if the file already exists.
1113
+ if info.file_exists and not overwrite_existing_file:
1114
+ internal_logger.debug(
1115
+ f"Skipping file upload for '{file_name}' because it already exists in cloud storage."
1116
+ )
1117
+ return info.file_uri
1118
+
1119
+ if info.url_scheme == CloudDataBucketPresignedUrlScheme.SMART_OPEN:
1120
+ # If the presigned URL scheme is SMART_OPEN, upload to cloud storage using the provided bucket name, path, & environment, and the smart_open library.
1121
+ bucket_name = info.bucket_name
1122
+ bucket_path = info.bucket_path
1123
+ file_uri = info.file_uri
1124
+
1125
+ if file_uri and file_uri.startswith("azure"):
1126
+
1127
+ from anyscale.utils.imports.azure import (
1128
+ try_import_azure_storage_blob_BlobServiceClient,
1129
+ )
1130
+
1131
+ # Smartopen needs transport_params to be passed in for Azure.
1132
+ blob_service_client = (
1133
+ try_import_azure_storage_blob_BlobServiceClient()
1134
+ )
1135
+
1136
+ transport_params = {
1137
+ "client": blob_service_client.from_connection_string(info.url),
1138
+ }
1139
+ with smart_open.open(
1140
+ f"{file_uri}", "wb", transport_params=transport_params,
1141
+ ) as fout:
1142
+ fout.write(zip_file_bytes)
1143
+ else:
1144
+ env_vars: Dict[str, str] = {
1145
+ "AWS_ENDPOINT_URL": info.url,
1146
+ }
1147
+ with set_env(**env_vars), smart_open.open(
1148
+ f"{bucket_name}/{bucket_path}", "wb",
1149
+ ) as fout:
1150
+ fout.write(zip_file_bytes)
1151
+
1152
+ else:
1153
+ # Default to HTTP PUT.
1154
+ internal_logger.debug(f"Uploading file '{file_name}' to cloud storage.")
1155
+ requests.put(info.url, data=zip_file_bytes).raise_for_status()
1156
+
1157
+ return info.file_uri
1158
+
1159
+ def _fetch_log_chunks(self, job_run_id: str) -> Tuple[List[str], Any]:
1160
+ all_log_chunk_urls = []
1161
+ MAX_PAGE_SIZE = 1000
1162
+ next_page_token = None
1163
+ bearer_token = None
1164
+ while True:
1165
+ log_download_result = self._internal_api_client.get_job_logs_download_v2_api_v2_logs_job_logs_download_v2_job_id_get(
1166
+ job_id=job_run_id,
1167
+ next_page_token=next_page_token,
1168
+ page_size=MAX_PAGE_SIZE,
1169
+ ).result
1170
+
1171
+ if bearer_token is None:
1172
+ bearer_token = log_download_result.bearer_token
1173
+
1174
+ all_log_chunk_urls.extend(
1175
+ [chunk.chunk_url for chunk in log_download_result.log_chunks]
1176
+ )
1177
+
1178
+ next_page_token = log_download_result.next_page_token
1179
+ if next_page_token is None:
1180
+ break
1181
+
1182
+ return all_log_chunk_urls, bearer_token
1183
+
1184
+ def _fetch_log_chunks_for_controller_logs(
1185
+ self, cluster_id: str
1186
+ ) -> Tuple[List[str], Any]:
1187
+ all_log_chunk_urls = []
1188
+ MAX_PAGE_SIZE = 1000
1189
+ next_page_token = None
1190
+ bearer_token = None
1191
+ while True:
1192
+ log_download_result = self._internal_api_client.get_serve_logs_download_api_v2_logs_serve_logs_download_cluster_id_get(
1193
+ cluster_id=cluster_id,
1194
+ next_page_token=next_page_token,
1195
+ page_size=MAX_PAGE_SIZE,
1196
+ ).result
1197
+
1198
+ if bearer_token is None:
1199
+ bearer_token = log_download_result.bearer_token
1200
+
1201
+ all_log_chunk_urls.extend(
1202
+ [chunk.chunk_url for chunk in log_download_result.log_chunks]
1203
+ )
1204
+
1205
+ next_page_token = log_download_result.next_page_token
1206
+ if next_page_token is None:
1207
+ break
1208
+
1209
+ return all_log_chunk_urls, bearer_token
1210
+
1211
+ def _read_log_lines(
1212
+ self,
1213
+ log_chunk_urls: List[str],
1214
+ head: bool,
1215
+ bearer_token: Any,
1216
+ max_lines: Optional[int],
1217
+ parse_json: Optional[bool] = None,
1218
+ ) -> str:
1219
+ # TODO(mowen): Would be nice to return some placeholder here to allow all new
1220
+ # logs to be read from a particular point onwards.
1221
+ # TODO(aguo): Change this to be a generator to avoid loading all logs into memory at once
1222
+ # and to gradually load logs as needed.
1223
+
1224
+ def parse_json_line(line: str) -> str:
1225
+ json_line = json.loads(line)
1226
+ # This is the default schema for ray core logger but users
1227
+ # could technically use any schema they want for structured logs.
1228
+ # Fall back to spitting out the json in the worst-case scenario.
1229
+ if "asctime" in json_line and "message" in json_line:
1230
+ return f"{json_line['asctime']} {json_line['message']}"
1231
+ elif "message" in json_line:
1232
+ return json_line["message"]
1233
+ # This is the worst-case scenario but very unlikely. Users would
1234
+ # not likely be changing "message" to something-else.
1235
+ return line
1236
+
1237
+ result_lines: List[str] = []
1238
+ step = 1 if head else -1
1239
+ line_count = 0
1240
+ for chunk_url in log_chunk_urls[::step]:
1241
+ log_lines = _download_log_from_s3_url_sync(
1242
+ chunk_url, bearer_token=bearer_token
1243
+ ).splitlines()
1244
+
1245
+ if max_lines is not None:
1246
+ num_lines_to_add = min(len(log_lines), max_lines - line_count)
1247
+ else:
1248
+ num_lines_to_add = len(log_lines)
1249
+ line_count += num_lines_to_add
1250
+
1251
+ if head:
1252
+ lines_to_add = log_lines[:num_lines_to_add]
1253
+ else:
1254
+ lines_to_add = log_lines[-1 * num_lines_to_add :]
1255
+
1256
+ if parse_json is not False:
1257
+ try:
1258
+ lines_to_add = [parse_json_line(line) for line in lines_to_add]
1259
+ except json.JSONDecodeError:
1260
+ if parse_json is True:
1261
+ raise ValueError(
1262
+ "Failed to parse logs as JSON. Logs are not all in JSON format."
1263
+ )
1264
+ # If we fail to parse_json, we should always just use plain text going forward.
1265
+ parse_json = False
1266
+ # lines_to_add should already be plain text, so continue on...
1267
+
1268
+ if head:
1269
+ result_lines = result_lines + lines_to_add
1270
+ else:
1271
+ result_lines = lines_to_add + result_lines
1272
+
1273
+ if line_count == max_lines:
1274
+ break
1275
+
1276
+ return "\n".join(result_lines) + "\n"
1277
+
1278
+ @handle_api_exceptions
1279
+ def logs_for_job_run(
1280
+ self,
1281
+ job_run_id: str,
1282
+ head: bool = False,
1283
+ max_lines: Optional[int] = None,
1284
+ parse_json: Optional[bool] = None,
1285
+ ) -> str:
1286
+ """
1287
+ Retrieves logs from the streaming job logs folder in S3/GCS
1288
+ Args:
1289
+ - parse_json: If true, we will always attempt to parse the logs as JSON.
1290
+ If false, we will always attempt to parse the logs as text. If None, we
1291
+ will attempt to parse the logs as JSON and fall back to text if parsing
1292
+ fails.
1293
+ """
1294
+
1295
+ all_log_chunk_urls, bearer_token = self._fetch_log_chunks(job_run_id)
1296
+
1297
+ logs = self._read_log_lines(
1298
+ all_log_chunk_urls, head, bearer_token, max_lines, parse_json=parse_json
1299
+ )
1300
+ return logs
1301
+
1302
+ @handle_api_exceptions
1303
+ def controller_logs_for_service_version(
1304
+ self,
1305
+ service_version: ProductionServiceV2VersionModel,
1306
+ head: bool = False,
1307
+ max_lines: Optional[int] = None,
1308
+ parse_json: Optional[bool] = None,
1309
+ ) -> str:
1310
+ """
1311
+ Returns the controller logs associated with a particular service version.
1312
+
1313
+ Args:
1314
+ - parse_json: If true, we will always attempt to parse the logs as JSON.
1315
+ If false, we will always attempt to parse the logs as text. If None, we
1316
+ will attempt to parse the logs as JSON and fall back to text if parsing
1317
+ fails.
1318
+ """
1319
+ service_version_id = service_version.id[-8:]
1320
+ if not len(service_version.production_job_ids):
1321
+ raise ValueError(
1322
+ f"Service version '{service_version_id}' canary version is not ready. Please try again later..."
1323
+ )
1324
+
1325
+ job = self._internal_api_client.get_job_api_v2_decorated_ha_jobs_production_job_id_get(
1326
+ service_version.production_job_ids[0]
1327
+ ).result
1328
+
1329
+ if not job:
1330
+ raise ValueError(
1331
+ f"Service version '{service_version_id}' canary version is not ready. Please try again later..."
1332
+ )
1333
+
1334
+ if not job.state.cluster:
1335
+ raise ValueError(
1336
+ f"Service version '{service_version_id}' canary version is not ready. Please try again later..."
1337
+ )
1338
+
1339
+ cluster_id = job.state.cluster.id
1340
+
1341
+ all_log_chunk_urls, bearer_token = self._fetch_log_chunks_for_controller_logs(
1342
+ cluster_id
1343
+ )
1344
+
1345
+ logs = self._read_log_lines(
1346
+ all_log_chunk_urls, head, bearer_token, max_lines, parse_json=parse_json
1347
+ )
1348
+ return logs
1349
+
1350
+ @handle_api_exceptions
1351
+ def apply_schedule(self, model: CreateSchedule) -> DecoratedSchedule:
1352
+ return self._internal_api_client.create_or_update_job_api_v2_experimental_cron_jobs_put(
1353
+ model
1354
+ ).result
1355
+
1356
+ @handle_api_exceptions
1357
+ def get_schedule(
1358
+ self,
1359
+ *,
1360
+ name: Optional[str],
1361
+ id: Optional[str], # noqa: A002
1362
+ cloud: Optional[str],
1363
+ project: Optional[str],
1364
+ ) -> Optional[DecoratedSchedule]:
1365
+ if id is not None:
1366
+ try:
1367
+ return self._internal_api_client.get_cron_job_api_v2_experimental_cron_jobs_cron_job_id_get(
1368
+ id
1369
+ ).result
1370
+ except ExternalApiException as e:
1371
+ if e.status == 404:
1372
+ return None
1373
+ raise e from None
1374
+ else:
1375
+ paging_token = None
1376
+ cloud_id = self.get_cloud_id(cloud_name=cloud)
1377
+ project_id = self.get_project_id(parent_cloud_id=cloud_id, name=project)
1378
+ result: Optional[DecoratedSchedule] = None
1379
+ while True:
1380
+ resp = self._internal_api_client.list_cron_jobs_api_v2_experimental_cron_jobs_get(
1381
+ project_id=project_id,
1382
+ name=name,
1383
+ count=self.LIST_ENDPOINT_COUNT,
1384
+ paging_token=paging_token,
1385
+ )
1386
+ for schedule in resp.results:
1387
+ if schedule is not None and schedule.name == name:
1388
+ result = schedule
1389
+ break
1390
+
1391
+ paging_token = resp.metadata.next_paging_token
1392
+ if paging_token is None:
1393
+ break
1394
+
1395
+ return result
1396
+
1397
+ @handle_api_exceptions
1398
+ def set_schedule_state(self, id: str, is_paused: bool): # noqa: A002
1399
+ self._internal_api_client.pause_cron_job_api_v2_experimental_cron_jobs_cron_job_id_pause_post(
1400
+ id, {"is_paused": is_paused}
1401
+ ).result
1402
+
1403
+ @handle_api_exceptions
1404
+ def trigger_schedule(self, id: str): # noqa: A002
1405
+ self._internal_api_client.trigger_cron_job_api_v2_experimental_cron_jobs_cron_job_id_trigger_post(
1406
+ id
1407
+ )
1408
+
1409
+ @handle_api_exceptions
1410
+ def get_dataset(self, name: str, version: Optional[int], project: Optional[str]):
1411
+ project_id = self._source_project_id(project)
1412
+ internal_dataset = self._internal_api_client.find_dataset_api_v2_datasets_find_get(
1413
+ name=name, version=version, project_id=project_id
1414
+ ).result
1415
+ from anyscale.llm.dataset._private.models import Dataset
1416
+
1417
+ dataset = Dataset.parse_from_internal_model(internal_dataset)
1418
+ return dataset
1419
+
1420
+ def upload_dataset(
1421
+ self,
1422
+ dataset_file: str,
1423
+ name: Optional[str],
1424
+ description: Optional[str],
1425
+ cloud: Optional[str],
1426
+ project: Optional[str],
1427
+ ):
1428
+ # Resolve `~/.../file` to `/home/user/.../file`
1429
+ dataset_file = os.path.expanduser(dataset_file)
1430
+
1431
+ if not os.path.isfile(dataset_file):
1432
+ raise ValueError(f"Path '{dataset_file}' is not a valid file.")
1433
+ dataset_file_size = os.path.getsize(dataset_file)
1434
+ if dataset_file_size > 5 * Bytes.GB:
1435
+ raise ValueError(
1436
+ f"File '{dataset_file}' is too large to upload. The maximum size is 5 GB."
1437
+ )
1438
+ project_id = self._get_project_id_by_name(name=project) if project else None
1439
+ cloud_id = self.get_cloud_id(cloud_name=cloud) if cloud else None
1440
+
1441
+ with FileDownloadProgress() as progress:
1442
+ task_id = progress.add_task(
1443
+ description=f"Creating an upload request for '{dataset_file}'",
1444
+ total=dataset_file_size,
1445
+ )
1446
+ _, project_id = source_cloud_id_and_project_id(
1447
+ internal_api=self._internal_api_client,
1448
+ external_api=self._external_api_client,
1449
+ cloud_id=cloud_id,
1450
+ project_id=project_id,
1451
+ )
1452
+ dataset_upload: DatasetUpload = self._internal_api_client.create_dataset_upload_api_v2_datasets_upload_post(
1453
+ create_dataset=CreateDataset(
1454
+ filename=os.path.basename(dataset_file),
1455
+ description=description,
1456
+ name=name,
1457
+ project_id=project_id,
1458
+ )
1459
+ ).result
1460
+
1461
+ progress.update(task_id, description=f"Uploading '{dataset_file}'")
1462
+
1463
+ with open(dataset_file, "rb") as file_reader:
1464
+ progress_reader = ProgressFileReader(file_reader, progress, task_id)
1465
+ response = requests.put(
1466
+ dataset_upload.upload_url, data=progress_reader,
1467
+ )
1468
+ response.raise_for_status()
1469
+
1470
+ progress.update(task_id, completed=os.path.getsize(dataset_file))
1471
+ progress.console.print(
1472
+ "Upload complete!", style=Style(bold=True, color="green")
1473
+ )
1474
+ internal_dataset = dataset_upload.dataset
1475
+ from anyscale.llm.dataset._private.models import Dataset
1476
+
1477
+ dataset = Dataset.parse_from_internal_model(internal_dataset)
1478
+ return dataset
1479
+
1480
+ @handle_api_exceptions
1481
+ def download_dataset(
1482
+ self, name: str, version: Optional[int], project: Optional[str]
1483
+ ) -> bytes:
1484
+ project_id = self._source_project_id(project)
1485
+ with FileDownloadProgress() as progress:
1486
+ task_id = progress.add_task(
1487
+ description=f"Getting download info for '{name}'",
1488
+ )
1489
+ download_url: str = self._internal_api_client.get_dataset_download_url_api_v2_datasets_download_get(
1490
+ name, version=version, project_id=project_id,
1491
+ )
1492
+ progress.update(task_id, description=f"Downloading '{name}'")
1493
+ response = requests.get(download_url, stream=True)
1494
+ total_size = int(response.headers.get("content-length", 0))
1495
+ progress.update(task_id, total=total_size)
1496
+
1497
+ # For CLI, consider writing to disk instead of loading the entire file into memory.
1498
+ dataset_bytes = b""
1499
+ for data in response.iter_content(Bytes.MB):
1500
+ dataset_bytes += data
1501
+ progress.update(task_id, advance=len(data))
1502
+
1503
+ progress.update(task_id, completed=total_size)
1504
+ progress.console.print(
1505
+ "Download complete!", style=Style(bold=True, color="green")
1506
+ )
1507
+
1508
+ return dataset_bytes
1509
+
1510
+ @handle_api_exceptions
1511
+ def list_datasets(
1512
+ self,
1513
+ limit: Optional[int] = None,
1514
+ after: Optional[str] = None, # Unique ID to start listing after
1515
+ name_contains: Optional[str] = None,
1516
+ cloud: Optional[str] = None,
1517
+ project: Optional[str] = None,
1518
+ ):
1519
+ project_id = self._source_project_id(project)
1520
+ cloud_id = self.get_cloud_id(cloud_name=cloud) if cloud else None
1521
+
1522
+ def get_next_page(
1523
+ after_id: Optional[str],
1524
+ ) -> InternalListResponse[InternalDataset]:
1525
+ internal_datasets: InternalListResponse = self._internal_api_client.list_datasets_api_v2_datasets_get(
1526
+ project_id=project_id,
1527
+ cloud_id=cloud_id,
1528
+ name_contains=name_contains,
1529
+ after=after_id,
1530
+ )
1531
+ return internal_datasets
1532
+
1533
+ from anyscale.llm.dataset._private.models import Dataset
1534
+
1535
+ list_response = ListResponse(
1536
+ after=after, limit=limit, get_next_page=get_next_page, cls=Dataset,
1537
+ )
1538
+ return list_response
1539
+
1540
+ def _source_project_id(self, project_name: Optional[str]) -> Optional[str]:
1541
+ """Sources a optional project ID from an optionally-provided project name."""
1542
+ if project_name:
1543
+ project_id = self._get_project_id_by_name(name=project_name)
1544
+ else:
1545
+ project_id = None
1546
+ return project_id
1547
+
1548
+ @handle_api_exceptions
1549
+ def get_finetuned_model(
1550
+ self, model_id: Optional[str], job_id: Optional[str]
1551
+ ) -> FineTunedModel:
1552
+ if model_id:
1553
+ return self._internal_api_client.get_model_api_v2_llm_models_model_id_get(
1554
+ model_id
1555
+ ).result
1556
+ elif job_id:
1557
+ return self._internal_api_client.get_model_by_job_id_api_v2_llm_models_get_by_job_id_job_id_get(
1558
+ job_id
1559
+ ).result
1560
+ else:
1561
+ raise ValueError("Atleast one of `model_id` or `job_id` must be provided")
1562
+
1563
+ @handle_api_exceptions
1564
+ def create_workspace(self, model: CreateExperimentalWorkspace) -> str:
1565
+ return self._internal_api_client.create_workspace_api_v2_experimental_workspaces_post(
1566
+ create_experimental_workspace=model,
1567
+ ).result.id
1568
+
1569
+ @handle_api_exceptions
1570
+ def get_workspace(
1571
+ self,
1572
+ *,
1573
+ id: Optional[str] = None, # noqa: A002
1574
+ name: Optional[str] = None,
1575
+ cloud: Optional[str] = None,
1576
+ project: Optional[str] = None,
1577
+ ) -> Optional[ExperimentalWorkspace]:
1578
+ """Get a workspace by either name or id. Filter by cloud and project.
1579
+
1580
+ Returns None if not found.
1581
+ """
1582
+ if id is not None:
1583
+ try:
1584
+ return self._internal_api_client.get_workspace_api_v2_experimental_workspaces_workspace_id_get(
1585
+ id
1586
+ ).result
1587
+ except ExternalApiException as e:
1588
+ if e.status == 404:
1589
+ return None
1590
+ raise e from None
1591
+ else:
1592
+ paging_token = None
1593
+ cloud_id = self.get_cloud_id(cloud_name=cloud)
1594
+ project_id = self.get_project_id(parent_cloud_id=cloud_id, name=project)
1595
+ resp = self._internal_api_client.list_workspaces_api_v2_experimental_workspaces_get(
1596
+ project_id=project_id,
1597
+ name=name,
1598
+ count=self.LIST_ENDPOINT_COUNT,
1599
+ paging_token=paging_token,
1600
+ )
1601
+
1602
+ if len(resp.results) == 0:
1603
+ return None
1604
+
1605
+ workspace = resp.results[0]
1606
+ return workspace
1607
+
1608
+ @handle_api_exceptions
1609
+ def update_workspace(
1610
+ self,
1611
+ *,
1612
+ workspace_id: str,
1613
+ name: Optional[str] = None,
1614
+ compute_config_id: Optional[str] = None,
1615
+ cluster_environment_build_id: Optional[str] = None,
1616
+ idle_timeout_minutes: Optional[int] = None,
1617
+ ):
1618
+ workspace = self.get_workspace(id=workspace_id)
1619
+ if not workspace:
1620
+ raise ValueError(f"Workspace '{workspace_id}' not found.")
1621
+
1622
+ if name:
1623
+ # Update the workspace name with workspaces patch API
1624
+ self._internal_api_client.patch_workspace_api_v2_experimental_workspaces_workspace_id_patch(
1625
+ workspace_id=workspace_id,
1626
+ json_patch_operation=[
1627
+ {"op": "replace", "path": "/name", "value": name,},
1628
+ ],
1629
+ )
1630
+
1631
+ if compute_config_id or cluster_environment_build_id or idle_timeout_minutes:
1632
+ # Update cluster with external cluster API
1633
+ self._external_api_client.update_cluster(
1634
+ cluster_id=workspace.cluster_id,
1635
+ update_cluster=UpdateCluster(
1636
+ idle_timeout_minutes=idle_timeout_minutes,
1637
+ cluster_environment_build_id=cluster_environment_build_id,
1638
+ cluster_compute_id=compute_config_id,
1639
+ ),
1640
+ )
1641
+
1642
+ @handle_api_exceptions
1643
+ def update_workspace_dependencies_offline_only(
1644
+ self, workspace_id: str, requirements: List[str]
1645
+ ):
1646
+ return self._internal_api_client.put_workspace_proxied_dataplane_artifacts_api_v2_experimental_workspaces_workspace_id_proxied_dataplane_artifacts_put(
1647
+ workspace_id=workspace_id,
1648
+ workspace_dataplane_proxied_artifacts={
1649
+ "requirements": "\n".join(requirements),
1650
+ },
1651
+ )
1652
+
1653
+ @handle_api_exceptions
1654
+ def update_workspace_env_vars_offline_only(
1655
+ self, workspace_id: str, env_vars: Dict[str, str]
1656
+ ):
1657
+ return self._internal_api_client.put_workspace_proxied_dataplane_artifacts_api_v2_experimental_workspaces_workspace_id_proxied_dataplane_artifacts_put(
1658
+ workspace_id=workspace_id,
1659
+ workspace_dataplane_proxied_artifacts={
1660
+ "environment_variables": [
1661
+ f"{key}={value}" for key, value in env_vars.items()
1662
+ ],
1663
+ },
1664
+ )
1665
+
1666
+ @handle_api_exceptions
1667
+ def get_workspace_proxied_dataplane_artifacts(
1668
+ self, workspace_id: str
1669
+ ) -> WorkspaceDataplaneProxiedArtifacts:
1670
+ return self._internal_api_client.get_workspace_proxied_dataplane_artifacts_api_v2_experimental_workspaces_workspace_id_proxied_dataplane_artifacts_get(
1671
+ workspace_id
1672
+ ).result
1673
+
1674
+ @handle_api_exceptions
1675
+ def start_workspace(self, workspace_id: str):
1676
+ """Start a workspace."""
1677
+ workspace_model = self.get_workspace(id=workspace_id)
1678
+ if workspace_model is None:
1679
+ raise ValueError(f"Workspace '{workspace_id}' not found.")
1680
+
1681
+ return self._internal_api_client.start_session_api_v2_sessions_session_id_start_post(
1682
+ session_id=workspace_model.cluster_id,
1683
+ start_session_options=StartSessionOptions(),
1684
+ )
1685
+
1686
+ @handle_api_exceptions
1687
+ def terminate_workspace(self, workspace_id: str):
1688
+ """Terminate a workspace."""
1689
+ workspace_model = self.get_workspace(id=workspace_id)
1690
+ if workspace_model is None:
1691
+ raise ValueError(f"Workspace '{workspace_id}' not found.")
1692
+
1693
+ options = StopSessionOptions(
1694
+ terminate=True,
1695
+ workers_only=False,
1696
+ keep_min_workers=False,
1697
+ take_snapshot=False,
1698
+ )
1699
+ return self._internal_api_client.stop_session_api_v2_sessions_session_id_stop_post(
1700
+ session_id=workspace_model.cluster_id, stop_session_options=options,
1701
+ )
1702
+
1703
+ @handle_api_exceptions
1704
+ def get_workspace_cluster(self, workspace_id: str) -> Optional[DecoratedSession]:
1705
+ workspace = self.get_workspace(id=workspace_id)
1706
+ if not workspace:
1707
+ raise ValueError(f"Workspace '{workspace_id}' not found.")
1708
+
1709
+ result = self._internal_api_client.get_decorated_cluster_api_v2_decorated_sessions_cluster_id_get(
1710
+ workspace.cluster_id
1711
+ )
1712
+ return result.result
1713
+
1714
+ @handle_api_exceptions
1715
+ def get_cluster_head_node_ip(self, cluster_id: str) -> str:
1716
+ head_ip = self._internal_api_client.get_session_head_ip_api_v2_sessions_session_id_head_ip_get(
1717
+ cluster_id
1718
+ ).result.head_ip
1719
+ return head_ip
1720
+
1721
+ @handle_api_exceptions
1722
+ def get_cluster_ssh_key(self, cluster_id: str) -> SessionSshKey:
1723
+ return self._internal_api_client.get_session_ssh_key_api_v2_sessions_session_id_ssh_key_get(
1724
+ cluster_id
1725
+ ).result
1726
+
1727
+ @handle_api_exceptions
1728
+ def get_workspace_default_dir_name(self, workspace_id) -> str:
1729
+ workspace = self.get_workspace(id=workspace_id)
1730
+ assert workspace, f"Workspace '{workspace_id}' not found."
1731
+ project = self._internal_api_client.get_project_api_v2_projects_project_id_get(
1732
+ workspace.project_id
1733
+ ).result
1734
+ if self._internal_api_client.check_is_feature_flag_on_api_v2_userinfo_check_is_feature_flag_on_get(
1735
+ FLAG_DEFAULT_WORKING_DIR_FOR_PROJ
1736
+ ).result.is_on:
1737
+ return project.directory_name
1738
+ else:
1739
+ return project.name
1740
+
1741
+ @handle_api_exceptions
1742
+ def delete_finetuned_model(self, model_id: str) -> DeletedPlatformFineTunedModel:
1743
+ deleted_model = self._internal_api_client.delete_model_api_v2_llm_models_model_id_delete(
1744
+ model_id
1745
+ ).result
1746
+ return deleted_model
1747
+
1748
+ @handle_api_exceptions
1749
+ def list_finetuned_models(
1750
+ self, cloud_id: Optional[str], project_id: Optional[str], max_items: int,
1751
+ ) -> List[FineTunedModel]:
1752
+ if self.inside_workspace():
1753
+ # Resolve `cloud_id` and `project_id`. If not provided and if this is being run in a workspace,
1754
+ # we use the `cloud_id` and `project_id` of the workspace
1755
+ cloud_id, project_id = source_cloud_id_and_project_id(
1756
+ internal_api=self._internal_api_client,
1757
+ external_api=self._external_api_client,
1758
+ cloud_id=cloud_id,
1759
+ project_id=project_id,
1760
+ )
1761
+
1762
+ paging_token = None
1763
+ results = []
1764
+ while True:
1765
+ count = min(self.LIST_ENDPOINT_COUNT, max_items)
1766
+ resp: FinetunedmodelListResponse = self._internal_api_client.list_models_api_v2_llm_models_get(
1767
+ cloud_id=cloud_id,
1768
+ project_id=project_id,
1769
+ paging_token=paging_token,
1770
+ count=count,
1771
+ )
1772
+ models = resp.results
1773
+ results.extend(models)
1774
+ if not len(models) or not resp.metadata.next_paging_token:
1775
+ break
1776
+
1777
+ if max_items and len(results) >= max_items:
1778
+ break
1779
+ paging_token = resp.metadata.next_paging_token
1780
+
1781
+ return results[:max_items] if max_items else results
1782
+
1783
+ @handle_api_exceptions
1784
+ def download_aggregated_instance_usage_csv(
1785
+ self,
1786
+ start_date,
1787
+ end_date,
1788
+ cloud_id=None,
1789
+ project_id=None,
1790
+ directory=None,
1791
+ hide_progress_bar=False,
1792
+ ) -> str:
1793
+ with FileDownloadProgress() as progress:
1794
+ task_id = progress.add_task(
1795
+ description="Preparing aggregated instance usage CSV",
1796
+ visible=not hide_progress_bar,
1797
+ )
1798
+
1799
+ resp = self._internal_api_client.download_aggregated_instance_usage_csv_api_v2_aggregated_instance_usage_download_csv_get(
1800
+ start_date=start_date,
1801
+ end_date=end_date,
1802
+ cloud_id=cloud_id,
1803
+ project_id=project_id,
1804
+ _preload_content=False,
1805
+ )
1806
+
1807
+ progress.update(
1808
+ task_id, description="Downloading aggregated instance usage CSV"
1809
+ )
1810
+
1811
+ # Set the total size of the download for the progress bar
1812
+ total_size = int(resp.headers.get("content-length", 0))
1813
+ progress.update(task_id, total=total_size)
1814
+
1815
+ # Construct the filepath to save the downloaded file
1816
+ content_disposition = resp.headers.get("content-disposition", "")
1817
+ filename_regex = re.search(
1818
+ r'filename="?(?P<filename>[^"]+)"?', content_disposition
1819
+ )
1820
+
1821
+ if not filename_regex:
1822
+ filename = f"aggregated_instance_usage_{start_date}_{end_date}.zip"
1823
+ else:
1824
+ filename = filename_regex.group("filename")
1825
+
1826
+ if directory:
1827
+ filepath = os.path.join(directory, filename)
1828
+ else:
1829
+ filepath = filename
1830
+
1831
+ # Download the file
1832
+ try:
1833
+ with open(filepath, "wb") as f:
1834
+ for chunk in resp.stream(Bytes.MB):
1835
+ if chunk:
1836
+ f.write(chunk)
1837
+ progress.update(task_id, advance=len(chunk))
1838
+ except Exception as e: # noqa: BLE001
1839
+ raise ValueError(f"Failed to download to '{filepath}': {e}") from None
1840
+
1841
+ progress.update(task_id, completed=total_size)
1842
+ progress.console.print(
1843
+ f"Download complete! File saved to '{filepath}'",
1844
+ style=Style(bold=True, color="green"),
1845
+ )
1846
+
1847
+ return filepath