anyscale 0.24.88__py3-none-any.whl → 0.25.0__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 (115) hide show
  1. anyscale/__init__.py +46 -0
  2. anyscale/_private/anyscale_client/anyscale_client.py +148 -28
  3. anyscale/_private/anyscale_client/common.py +74 -1
  4. anyscale/_private/anyscale_client/fake_anyscale_client.py +165 -1
  5. anyscale/_private/docgen/README.md +1 -1
  6. anyscale/_private/docgen/__main__.py +62 -19
  7. anyscale/_private/docgen/api.md +0 -20
  8. anyscale/_private/docgen/generator.py +3 -2
  9. anyscale/_private/docgen/models.md +1 -46
  10. anyscale/_private/workload/workload_config.py +1 -1
  11. anyscale/aggregated_instance_usage/__init__.py +1 -1
  12. anyscale/aggregated_instance_usage/commands.py +2 -4
  13. anyscale/aggregated_instance_usage/models.py +8 -8
  14. anyscale/client/README.md +15 -22
  15. anyscale/client/openapi_client/__init__.py +10 -14
  16. anyscale/client/openapi_client/api/default_api.py +634 -957
  17. anyscale/client/openapi_client/models/__init__.py +10 -14
  18. anyscale/client/openapi_client/models/{session_event_types.py → cloud_deployment_config.py} +35 -24
  19. anyscale/client/openapi_client/models/{platformfinetuningjob_response.py → clouddeploymentconfig_response.py} +11 -11
  20. anyscale/client/openapi_client/models/{company_size.py → cluster_size.py} +10 -10
  21. anyscale/client/openapi_client/models/cluster_status_details.py +2 -1
  22. anyscale/client/openapi_client/models/create_experimental_workspace.py +29 -1
  23. anyscale/client/openapi_client/models/{resubmit_ft_job_request.py → describe_machine_pool_request.py} +21 -20
  24. anyscale/client/openapi_client/models/describe_machine_pool_response.py +123 -0
  25. anyscale/client/openapi_client/models/{fine_tuning_job_status.py → describemachinepoolresponse_response.py} +34 -16
  26. anyscale/client/openapi_client/models/machine_allocation_state.py +3 -1
  27. anyscale/client/openapi_client/models/machine_state_info.py +326 -0
  28. anyscale/client/openapi_client/models/organization_marketing_questions.py +80 -54
  29. anyscale/client/openapi_client/models/request_state_info.py +210 -0
  30. anyscale/client/openapi_client/models/{sessionevent_list_response.py → scheduler_info.py} +43 -38
  31. anyscale/client/openapi_client/models/usage_by_cluster.py +28 -1
  32. anyscale/client/openapi_client/models/usage_by_user.py +30 -3
  33. anyscale/client/openapi_client/models/workload_info.py +210 -0
  34. anyscale/cloud/__init__.py +83 -0
  35. anyscale/cloud/_private/cloud_sdk.py +25 -0
  36. anyscale/cloud/commands.py +45 -0
  37. anyscale/cloud/models.py +91 -0
  38. anyscale/cluster_compute.py +1 -1
  39. anyscale/commands/aggregated_instance_usage_commands.py +4 -4
  40. anyscale/commands/cloud_commands.py +38 -2
  41. anyscale/commands/command_examples.py +61 -0
  42. anyscale/commands/job_commands.py +15 -3
  43. anyscale/commands/machine_pool_commands.py +113 -1
  44. anyscale/commands/organization_invitation_commands.py +98 -0
  45. anyscale/commands/project_commands.py +52 -2
  46. anyscale/commands/resource_quota_commands.py +98 -11
  47. anyscale/commands/service_commands.py +1 -1
  48. anyscale/commands/session_commands_hidden.py +5 -1
  49. anyscale/commands/user_commands.py +1 -1
  50. anyscale/commands/util.py +2 -2
  51. anyscale/commands/workspace_commands.py +1 -1
  52. anyscale/connect.py +1 -1
  53. anyscale/connect_utils/project.py +7 -4
  54. anyscale/controllers/cloud_controller.py +6 -6
  55. anyscale/controllers/cloud_functional_verification_controller.py +1 -1
  56. anyscale/controllers/cluster_controller.py +2 -2
  57. anyscale/controllers/compute_config_controller.py +1 -1
  58. anyscale/controllers/experimental_integrations_controller.py +1 -1
  59. anyscale/controllers/job_controller.py +8 -3
  60. anyscale/controllers/list_controller.py +2 -2
  61. anyscale/controllers/machine_pool_controller.py +12 -1
  62. anyscale/controllers/project_controller.py +4 -3
  63. anyscale/controllers/schedule_controller.py +1 -1
  64. anyscale/controllers/service_controller.py +1 -1
  65. anyscale/controllers/workspace_controller.py +1 -1
  66. anyscale/models/job_model.py +1 -1
  67. anyscale/organization_invitation/__init__.py +61 -0
  68. anyscale/organization_invitation/_private/organization_invitation_sdk.py +24 -0
  69. anyscale/organization_invitation/commands.py +84 -0
  70. anyscale/organization_invitation/models.py +45 -0
  71. anyscale/project/__init__.py +35 -0
  72. anyscale/project/_private/project_sdk.py +27 -0
  73. anyscale/project/commands.py +56 -0
  74. anyscale/project/models.py +91 -0
  75. anyscale/{project.py → project_utils.py} +3 -4
  76. anyscale/resource_quota/__init__.py +99 -0
  77. anyscale/resource_quota/_private/resource_quota_sdk.py +111 -0
  78. anyscale/resource_quota/commands.py +150 -0
  79. anyscale/resource_quota/models.py +303 -0
  80. anyscale/scripts.py +4 -0
  81. anyscale/sdk/anyscale_client/__init__.py +0 -5
  82. anyscale/sdk/anyscale_client/api/default_api.py +0 -150
  83. anyscale/sdk/anyscale_client/models/__init__.py +0 -5
  84. anyscale/sdk/anyscale_client/models/cluster_status_details.py +2 -1
  85. anyscale/sdk/anyscale_client/sdk.py +1 -1
  86. anyscale/user/__init__.py +1 -1
  87. anyscale/user/commands.py +1 -1
  88. anyscale/user/models.py +25 -15
  89. anyscale/util.py +15 -0
  90. anyscale/utils/cloud_utils.py +1 -1
  91. anyscale/version.py +1 -1
  92. anyscale/workspace_utils.py +1 -1
  93. {anyscale-0.24.88.dist-info → anyscale-0.25.0.dist-info}/METADATA +1 -5
  94. {anyscale-0.24.88.dist-info → anyscale-0.25.0.dist-info}/RECORD +100 -94
  95. anyscale/client/openapi_client/models/create_fine_tuning_hyperparameters.py +0 -156
  96. anyscale/client/openapi_client/models/create_fine_tuning_job_product_request.py +0 -353
  97. anyscale/client/openapi_client/models/finish_ft_job_request.py +0 -204
  98. anyscale/client/openapi_client/models/log_level_types.py +0 -100
  99. anyscale/client/openapi_client/models/platform_fine_tuning_job.py +0 -577
  100. anyscale/client/openapi_client/models/platformfinetuningjob_list_response.py +0 -147
  101. anyscale/client/openapi_client/models/session_event.py +0 -267
  102. anyscale/client/openapi_client/models/session_event_cause.py +0 -150
  103. anyscale/controllers/resource_quota_controller.py +0 -183
  104. anyscale/sdk/anyscale_client/models/log_level_types.py +0 -100
  105. anyscale/sdk/anyscale_client/models/session_event.py +0 -267
  106. anyscale/sdk/anyscale_client/models/session_event_cause.py +0 -150
  107. anyscale/sdk/anyscale_client/models/session_event_types.py +0 -111
  108. anyscale/sdk/anyscale_client/models/sessionevent_list_response.py +0 -147
  109. anyscale/utils/imports/azure.py +0 -14
  110. /anyscale/{cloud.py → cloud_utils.py} +0 -0
  111. {anyscale-0.24.88.dist-info → anyscale-0.25.0.dist-info}/LICENSE +0 -0
  112. {anyscale-0.24.88.dist-info → anyscale-0.25.0.dist-info}/NOTICE +0 -0
  113. {anyscale-0.24.88.dist-info → anyscale-0.25.0.dist-info}/WHEEL +0 -0
  114. {anyscale-0.24.88.dist-info → anyscale-0.25.0.dist-info}/entry_points.txt +0 -0
  115. {anyscale-0.24.88.dist-info → anyscale-0.25.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,99 @@
1
+ from typing import List, Optional
2
+
3
+ from anyscale._private.anyscale_client import AnyscaleClientInterface
4
+ from anyscale._private.sdk import sdk_docs
5
+ from anyscale._private.sdk.base_sdk import Timer
6
+ from anyscale.cli_logger import BlockLogger
7
+ from anyscale.resource_quota._private.resource_quota_sdk import PrivateResourceQuotaSDK
8
+ from anyscale.resource_quota.commands import (
9
+ _CREATE_DOCSTRINGS,
10
+ _CREATE_EXAMPLE,
11
+ _DELETE_DOCSTRINGS,
12
+ _DELETE_EXAMPLE,
13
+ _DISABLE_DOCSTRINGS,
14
+ _DISABLE_EXAMPLE,
15
+ _ENABLE_DOCSTRINGS,
16
+ _ENABLE_EXAMPLE,
17
+ _LIST_DOCSTRINGS,
18
+ _LIST_EXAMPLE,
19
+ create,
20
+ delete,
21
+ disable,
22
+ enable,
23
+ list,
24
+ )
25
+ from anyscale.resource_quota.models import CreateResourceQuota, ResourceQuota
26
+
27
+
28
+ class ResourceQuotaSDK:
29
+ def __init__(
30
+ self,
31
+ *,
32
+ client: Optional[AnyscaleClientInterface] = None,
33
+ logger: Optional[BlockLogger] = None,
34
+ timer: Optional[Timer] = None,
35
+ ):
36
+ self._private_sdk = PrivateResourceQuotaSDK(
37
+ client=client, logger=logger, timer=timer
38
+ )
39
+
40
+ @sdk_docs(
41
+ doc_py_example=_CREATE_EXAMPLE, arg_docstrings=_CREATE_DOCSTRINGS,
42
+ )
43
+ def create( # noqa: F811
44
+ self, create_resource_quota: CreateResourceQuota,
45
+ ) -> ResourceQuota:
46
+ """Create a resource quota.
47
+ """
48
+ return self._private_sdk.create(create_resource_quota)
49
+
50
+ @sdk_docs(
51
+ doc_py_example=_LIST_EXAMPLE, arg_docstrings=_LIST_DOCSTRINGS,
52
+ )
53
+ def list( # noqa: F811
54
+ self,
55
+ name: Optional[str] = None,
56
+ cloud: Optional[str] = None,
57
+ creator_id: Optional[str] = None,
58
+ is_enabled: Optional[bool] = None,
59
+ max_items: int = 20,
60
+ ) -> List[ResourceQuota]:
61
+ """List resource quotas.
62
+ """
63
+ return self._private_sdk.list(
64
+ name=name,
65
+ cloud=cloud,
66
+ creator_id=creator_id,
67
+ is_enabled=is_enabled,
68
+ max_items=max_items,
69
+ )
70
+
71
+ @sdk_docs(
72
+ doc_py_example=_DELETE_EXAMPLE, arg_docstrings=_DELETE_DOCSTRINGS,
73
+ )
74
+ def delete( # noqa: F811
75
+ self, resource_quota_id: str,
76
+ ):
77
+ """Delete a resource quota.
78
+ """
79
+ return self._private_sdk.delete(resource_quota_id)
80
+
81
+ @sdk_docs(
82
+ doc_py_example=_ENABLE_EXAMPLE, arg_docstrings=_ENABLE_DOCSTRINGS,
83
+ )
84
+ def enable( # noqa: F811
85
+ self, resource_quota_id: str,
86
+ ):
87
+ """Enable a resource quota.
88
+ """
89
+ return self._private_sdk.set_status(resource_quota_id, True)
90
+
91
+ @sdk_docs(
92
+ doc_py_example=_DISABLE_EXAMPLE, arg_docstrings=_DISABLE_DOCSTRINGS,
93
+ )
94
+ def disable( # noqa: F811
95
+ self, resource_quota_id: str,
96
+ ):
97
+ """Disable a resource quota.
98
+ """
99
+ return self._private_sdk.set_status(resource_quota_id, False)
@@ -0,0 +1,111 @@
1
+ from typing import List, Optional
2
+
3
+ from anyscale._private.sdk.base_sdk import BaseSDK
4
+ from anyscale.client.openapi_client.models.create_resource_quota import (
5
+ CreateResourceQuota as CreateResourceQuotaModel,
6
+ )
7
+ from anyscale.client.openapi_client.models.quota import Quota as QuotaModel
8
+ from anyscale.resource_quota.models import CreateResourceQuota, Quota, ResourceQuota
9
+
10
+
11
+ class PrivateResourceQuotaSDK(BaseSDK):
12
+ def create(self, create_resource_quota: CreateResourceQuota) -> ResourceQuota:
13
+ cloud_id = self.client.get_cloud_id(
14
+ cloud_name=create_resource_quota.cloud, compute_config_id=None
15
+ )
16
+
17
+ project_id = (
18
+ self.client.get_project_id(
19
+ parent_cloud_id=cloud_id, name=create_resource_quota.project
20
+ )
21
+ if create_resource_quota.project
22
+ else None
23
+ )
24
+
25
+ user_id = (
26
+ self.client.get_organization_collaborator(
27
+ email=create_resource_quota.user_email
28
+ ).user_id
29
+ if create_resource_quota.user_email
30
+ else None
31
+ )
32
+
33
+ create_resource_quota_model = CreateResourceQuotaModel(
34
+ name=create_resource_quota.name,
35
+ cloud_id=cloud_id,
36
+ project_id=project_id,
37
+ user_id=user_id,
38
+ quota=QuotaModel(
39
+ num_cpus=create_resource_quota.num_cpus,
40
+ num_instances=create_resource_quota.num_instances,
41
+ num_gpus=create_resource_quota.num_gpus,
42
+ num_accelerators=create_resource_quota.num_accelerators,
43
+ ),
44
+ )
45
+
46
+ resource_quota = self.client.create_resource_quota(
47
+ create_resource_quota=create_resource_quota_model
48
+ )
49
+
50
+ return ResourceQuota(
51
+ id=resource_quota.id,
52
+ name=resource_quota.name,
53
+ cloud_id=resource_quota.cloud_id,
54
+ project_id=resource_quota.project_id,
55
+ user_id=resource_quota.user_id,
56
+ is_enabled=resource_quota.is_enabled,
57
+ created_at=resource_quota.created_at,
58
+ deleted_at=resource_quota.deleted_at,
59
+ quota=Quota(
60
+ num_cpus=resource_quota.quota.num_cpus,
61
+ num_instances=resource_quota.quota.num_instances,
62
+ num_gpus=resource_quota.quota.num_gpus,
63
+ num_accelerators=resource_quota.quota.num_accelerators,
64
+ ),
65
+ )
66
+
67
+ def list(
68
+ self,
69
+ name: Optional[str] = None,
70
+ cloud: Optional[str] = None,
71
+ creator_id: Optional[str] = None,
72
+ is_enabled: Optional[bool] = None,
73
+ max_items: int = 20,
74
+ ) -> List[ResourceQuota]:
75
+ cloud_id = (
76
+ self.client.get_cloud_id(cloud_name=cloud, compute_config_id=None)
77
+ if cloud
78
+ else None
79
+ )
80
+
81
+ resource_quotas = self.client.list_resource_quotas(
82
+ name, cloud_id, creator_id, is_enabled, max_items,
83
+ )
84
+
85
+ return [
86
+ ResourceQuota(
87
+ id=resource_quota.id,
88
+ name=resource_quota.name,
89
+ cloud_id=resource_quota.cloud_id,
90
+ project_id=resource_quota.project_id,
91
+ user_id=resource_quota.user_id,
92
+ is_enabled=resource_quota.is_enabled,
93
+ created_at=resource_quota.created_at,
94
+ deleted_at=resource_quota.deleted_at,
95
+ quota=Quota(
96
+ num_cpus=resource_quota.quota.num_cpus,
97
+ num_instances=resource_quota.quota.num_instances,
98
+ num_gpus=resource_quota.quota.num_gpus,
99
+ num_accelerators=resource_quota.quota.num_accelerators,
100
+ ),
101
+ )
102
+ for resource_quota in resource_quotas
103
+ ]
104
+
105
+ def delete(self, resource_quota_id: str) -> None:
106
+ self.client.delete_resource_quota(resource_quota_id=resource_quota_id)
107
+
108
+ def set_status(self, resource_quota_id: str, is_enabled: bool) -> None:
109
+ self.client.set_resource_quota_status(
110
+ resource_quota_id=resource_quota_id, is_enabled=is_enabled
111
+ )
@@ -0,0 +1,150 @@
1
+ from typing import List, Optional
2
+
3
+ from anyscale._private.sdk import sdk_command
4
+ from anyscale.resource_quota._private.resource_quota_sdk import PrivateResourceQuotaSDK
5
+ from anyscale.resource_quota.models import CreateResourceQuota, ResourceQuota
6
+
7
+
8
+ _RESOURCE_QUOTA_SDK_SINGLETON_KEY = "resource_quota_sdk"
9
+
10
+ _CREATE_EXAMPLE = """
11
+ import anyscale
12
+ from anyscale.resource_quota.models import CreateResourceQuota
13
+
14
+ anyscale.resource_quota.create(
15
+ ResourceQuota(
16
+ name="my-resource-quota",
17
+ cloud="my-cloud",
18
+ project="my-project",
19
+ num_cpus=2,
20
+ ),
21
+ )
22
+ """
23
+
24
+ _CREATE_DOCSTRINGS = {"create_resource_quota": "The resource quota to be created."}
25
+
26
+ _LIST_EXAMPLE = """
27
+ import anyscale
28
+ from anyscale.resource_quota.models import CreateResourceQuota
29
+
30
+ anyscale.resource_quota.list(
31
+ name="my-resource-quota",
32
+ cloud="my-cloud",
33
+ creator_id="usr_123",
34
+ is_enabled=True,
35
+ max_items=20,
36
+ )
37
+ """
38
+
39
+ _LIST_DOCSTRINGS = {
40
+ "name": "Name of the resource quota.",
41
+ "cloud": "Name of the cloud that this resource quota applies to.",
42
+ "creator_id": "ID of the creator of the resource quota.",
43
+ "is_enabled": "Whether the resource quota is enabled.",
44
+ "max_items": "Maximum number of items to return.",
45
+ }
46
+
47
+ _DELETE_EXAMPLE = """
48
+ import anyscale
49
+
50
+ anyscale.resource_quota.delete(
51
+ resource_quota_id="rq_123",
52
+ )
53
+ """
54
+
55
+ _DELETE_DOCSTRINGS = {
56
+ "resource_quota_id": "ID of the resource quota to delete.",
57
+ }
58
+
59
+ _ENABLE_EXAMPLE = """
60
+ import anyscale
61
+
62
+ anyscale.resource_quota.enable(
63
+ resource_quota_id="rq_123",
64
+ )
65
+ """
66
+
67
+ _ENABLE_DOCSTRINGS = {
68
+ "resource_quota_id": "ID of the resource quota to enable.",
69
+ }
70
+
71
+ _DISABLE_EXAMPLE = """
72
+ import anyscale
73
+
74
+ anyscale.resource_quota.disable(
75
+ resource_quota_id="rq_123",
76
+ )
77
+ """
78
+
79
+ _DISABLE_DOCSTRINGS = {
80
+ "resource_quota_id": "ID of the resource quota to disable.",
81
+ }
82
+
83
+
84
+ @sdk_command(
85
+ _RESOURCE_QUOTA_SDK_SINGLETON_KEY,
86
+ PrivateResourceQuotaSDK,
87
+ doc_py_example=_CREATE_EXAMPLE,
88
+ arg_docstrings=_CREATE_DOCSTRINGS,
89
+ )
90
+ def create(
91
+ create_resource_quota: CreateResourceQuota, *, _sdk: PrivateResourceQuotaSDK
92
+ ) -> ResourceQuota:
93
+ """Create a resource quota.
94
+ """
95
+ return _sdk.create(create_resource_quota)
96
+
97
+
98
+ @sdk_command(
99
+ _RESOURCE_QUOTA_SDK_SINGLETON_KEY,
100
+ PrivateResourceQuotaSDK,
101
+ doc_py_example=_LIST_EXAMPLE,
102
+ arg_docstrings=_LIST_DOCSTRINGS,
103
+ )
104
+ def list( # noqa: A001
105
+ name: Optional[str] = None,
106
+ cloud: Optional[str] = None,
107
+ creator_id: Optional[str] = None,
108
+ is_enabled: Optional[bool] = None,
109
+ max_items: int = 20,
110
+ *,
111
+ _sdk: PrivateResourceQuotaSDK
112
+ ) -> List[ResourceQuota]:
113
+ """List resource quotas. """
114
+ return _sdk.list(name, cloud, creator_id, is_enabled, max_items,)
115
+
116
+
117
+ @sdk_command(
118
+ _RESOURCE_QUOTA_SDK_SINGLETON_KEY,
119
+ PrivateResourceQuotaSDK,
120
+ doc_py_example=_DELETE_EXAMPLE,
121
+ arg_docstrings=_DELETE_DOCSTRINGS,
122
+ )
123
+ def delete(resource_quota_id: str, *, _sdk: PrivateResourceQuotaSDK):
124
+ """Delete a resource quota.
125
+ """
126
+ return _sdk.delete(resource_quota_id)
127
+
128
+
129
+ @sdk_command(
130
+ _RESOURCE_QUOTA_SDK_SINGLETON_KEY,
131
+ PrivateResourceQuotaSDK,
132
+ doc_py_example=_ENABLE_EXAMPLE,
133
+ arg_docstrings=_ENABLE_DOCSTRINGS,
134
+ )
135
+ def enable(resource_quota_id: str, *, _sdk: PrivateResourceQuotaSDK):
136
+ """Enable a resource quota.
137
+ """
138
+ return _sdk.set_status(resource_quota_id, True)
139
+
140
+
141
+ @sdk_command(
142
+ _RESOURCE_QUOTA_SDK_SINGLETON_KEY,
143
+ PrivateResourceQuotaSDK,
144
+ doc_py_example=_DISABLE_EXAMPLE,
145
+ arg_docstrings=_DISABLE_DOCSTRINGS,
146
+ )
147
+ def disable(resource_quota_id: str, *, _sdk: PrivateResourceQuotaSDK):
148
+ """Disable a resource quota.
149
+ """
150
+ return _sdk.set_status(resource_quota_id, False)
@@ -0,0 +1,303 @@
1
+ from dataclasses import dataclass, field
2
+ from datetime import datetime
3
+ from typing import Dict, Optional
4
+
5
+ from anyscale._private.models import ModelBase
6
+
7
+
8
+ @dataclass(frozen=True)
9
+ class CreateResourceQuota(ModelBase):
10
+ """Resource quota creation model.
11
+ """
12
+
13
+ __doc_py_example__ = """\
14
+ import anyscale
15
+ from anyscale.resource_quota.models import CreateResourceQuota
16
+
17
+ create_resource_quota = CreateResourceQuota(
18
+ # Name of the resource quota to create
19
+ name="resource_quota_name",
20
+ # Name of the cloud that this resource quota applies to
21
+ cloud="cloud_name",
22
+ # Name of the project that this resource quota applies to (optional)
23
+ project="project_name",
24
+ # Email of the user that this resource quota applies to (optional)
25
+ user_email="test@anyscale.com",
26
+ # The quota limit for the number of CPUs (optional)
27
+ num_cpus=50,
28
+ # The quota limit for the number of instances (optional)
29
+ num_instances=100,
30
+ # The quota limit for the total number of GPUs (optional)
31
+ num_gpus=30,
32
+ # The quota limit for the number of accelerators (optional)
33
+ num_accelerators={"A100-80G": 10, "T4": 20},
34
+ )
35
+ """
36
+
37
+ name: str = field(metadata={"docstring": "Name of the resource quota to create."})
38
+
39
+ def _validate_name(self, name: str):
40
+ if not isinstance(name, str):
41
+ raise TypeError("name must be a string.")
42
+
43
+ cloud: str = field(
44
+ metadata={"docstring": "Name of the cloud that this resource quota applies to."}
45
+ )
46
+
47
+ def _validate_cloud(self, cloud: str):
48
+ if not isinstance(cloud, str):
49
+ raise TypeError("cloud must be a string.")
50
+
51
+ project: Optional[str] = field(
52
+ default=None,
53
+ metadata={
54
+ "docstring": "Name of the project that this resource quota applies to (optional)."
55
+ },
56
+ )
57
+
58
+ def _validate_project(self, project: Optional[str]):
59
+ if project is not None and not isinstance(project, str):
60
+ raise TypeError("project must be a string.")
61
+
62
+ user_email: Optional[str] = field(
63
+ default=None,
64
+ metadata={
65
+ "docstring": "Email of the user that this resource quota applies to (optional)."
66
+ },
67
+ )
68
+
69
+ def _validate_user_email(self, user_email: Optional[str]):
70
+ if user_email is not None and not isinstance(user_email, str):
71
+ raise TypeError("user_email must be a string.")
72
+
73
+ num_cpus: Optional[int] = field(
74
+ default=None,
75
+ metadata={"docstring": "The quota limit for the number of CPUs (optional)."},
76
+ )
77
+
78
+ def _validate_num_cpus(self, num_cpus: Optional[int]):
79
+ if num_cpus is not None and not isinstance(num_cpus, int):
80
+ raise TypeError("num_cpus must be an integer.")
81
+
82
+ num_instances: Optional[int] = field(
83
+ default=None,
84
+ metadata={
85
+ "docstring": "The quota limit for the number of instances. (optional)."
86
+ },
87
+ )
88
+
89
+ def _validate_num_instances(self, num_instances: Optional[int]):
90
+ if num_instances is not None and not isinstance(num_instances, int):
91
+ raise TypeError("num_instances must be an integer.")
92
+
93
+ num_gpus: Optional[int] = field(
94
+ default=None,
95
+ metadata={
96
+ "docstring": "The quota limit for the total number of GPUs (optional)."
97
+ },
98
+ )
99
+
100
+ def _validate_num_gpus(self, num_gpus: Optional[int]):
101
+ if num_gpus is not None and not isinstance(num_gpus, int):
102
+ raise TypeError("num_gpus must be an integer.")
103
+
104
+ num_accelerators: Optional[Dict[str, int]] = field(
105
+ default=None,
106
+ metadata={
107
+ "docstring": "The quota limit for the number of accelerators (optional)."
108
+ },
109
+ )
110
+
111
+ def _validate_num_accelerators(self, num_accelerators: Optional[Dict[str, int]]):
112
+ if num_accelerators is not None and not isinstance(num_accelerators, dict):
113
+ raise TypeError("num_accelerators must be a dictionary.")
114
+ if num_accelerators is not None:
115
+ for key, value in num_accelerators.items():
116
+ if not isinstance(key, str):
117
+ raise TypeError("num_accelerators keys must be strings.")
118
+ if not isinstance(value, int):
119
+ raise TypeError("num_accelerators values must be integers.")
120
+
121
+
122
+ @dataclass(frozen=True)
123
+ class Quota(ModelBase):
124
+ """Resource quota limit
125
+ """
126
+
127
+ __doc_py_example__ = """\
128
+ import anyscale
129
+ from anyscale.resource_quota.models import CreateResourceQuota, ResourceQuota, Quota
130
+
131
+ create_resource_quota = CreateResourceQuota(
132
+ # Name of the resource quota to create
133
+ name="resource_quota_name",
134
+ # Name of the cloud that this resource quota applies to
135
+ cloud="cloud_name",
136
+ # Name of the project that this resource quota applies to (optional)
137
+ project="project_name",
138
+ # Email of the user that this resource quota applies to (optional)
139
+ user_email="test@anyscale.com",
140
+ # The quota limit for the number of CPUs (optional)
141
+ num_cpus=50,
142
+ # The quota limit for the number of instances (optional)
143
+ num_instances=100,
144
+ # The quota limit for the total number of GPUs (optional)
145
+ num_gpus=30,
146
+ # The quota limit for the number of accelerators (optional)
147
+ num_accelerators={"A100-80G": 10, "T4": 20},
148
+ )
149
+
150
+ resource_quota: ResourceQuota = anyscale.resource_quota.create(create_resource_quota)
151
+
152
+ quota: Quota = resource_quota.quota
153
+ """
154
+ num_cpus: Optional[int] = field(
155
+ default=None,
156
+ metadata={"docstring": "The quota limit for the number of CPUs (optional)."},
157
+ )
158
+
159
+ def _validate_num_cpus(self, num_cpus: Optional[int]):
160
+ if num_cpus is not None and not isinstance(num_cpus, int):
161
+ raise TypeError("num_cpus must be an integer.")
162
+
163
+ num_instances: Optional[int] = field(
164
+ default=None,
165
+ metadata={
166
+ "docstring": "The quota limit for the number of instances. (optional)."
167
+ },
168
+ )
169
+
170
+ def _validate_num_instances(self, num_instances: Optional[int]):
171
+ if num_instances is not None and not isinstance(num_instances, int):
172
+ raise TypeError("num_instances must be an integer.")
173
+
174
+ num_gpus: Optional[int] = field(
175
+ default=None,
176
+ metadata={
177
+ "docstring": "The quota limit for the total number of GPUs (optional)."
178
+ },
179
+ )
180
+
181
+ def _validate_num_gpus(self, num_gpus: Optional[int]):
182
+ if num_gpus is not None and not isinstance(num_gpus, int):
183
+ raise TypeError("num_gpus must be an integer.")
184
+
185
+ num_accelerators: Optional[Dict[str, int]] = field(
186
+ default=None,
187
+ metadata={
188
+ "docstring": "The quota limit for the number of accelerators (optional)."
189
+ },
190
+ )
191
+
192
+ def _validate_num_accelerators(self, num_accelerators: Optional[Dict[str, int]]):
193
+ if num_accelerators is not None and not isinstance(num_accelerators, dict):
194
+ raise TypeError("num_accelerators must be a dictionary.")
195
+ if num_accelerators is not None:
196
+ for key, value in num_accelerators.items():
197
+ if not isinstance(key, str):
198
+ raise TypeError("num_accelerators keys must be strings.")
199
+ if not isinstance(value, int):
200
+ raise TypeError("num_accelerators values must be integers.")
201
+
202
+
203
+ @dataclass(frozen=True)
204
+ class ResourceQuota(ModelBase):
205
+ """Resource quota
206
+ """
207
+
208
+ __doc_py_example__ = """\
209
+ import anyscale
210
+ from anyscale.resource_quota.models import CreateResourceQuota, ResourceQuota
211
+
212
+ create_resource_quota = CreateResourceQuota(
213
+ # Name of the resource quota to create
214
+ name="resource_quota_name",
215
+ # Name of the cloud that this resource quota applies to
216
+ cloud="cloud_name",
217
+ # Name of the project that this resource quota applies to (optional)
218
+ project="project_name",
219
+ # Email of the user that this resource quota applies to (optional)
220
+ user_email="test@anyscale.com",
221
+ # The quota limit for the number of CPUs (optional)
222
+ num_cpus=50,
223
+ # The quota limit for the number of instances (optional)
224
+ num_instances=100,
225
+ # The quota limit for the total number of GPUs (optional)
226
+ num_gpus=30,
227
+ # The quota limit for the number of accelerators (optional)
228
+ num_accelerators={"A100-80G": 10, "T4": 20},
229
+ )
230
+ resource_quota: ResourceQuota = anyscale.resource_quota.create(create_resource_quota)
231
+ """
232
+ id: str = field(metadata={"docstring": "The ID of the resource quota."})
233
+
234
+ def _validate_id(self, id: str): # noqa: A002
235
+ if not isinstance(id, str):
236
+ raise TypeError("id must be a string.")
237
+
238
+ name: str = field(metadata={"docstring": "Name of the resource quota."})
239
+
240
+ def _validate_name(self, name: str):
241
+ if not isinstance(name, str):
242
+ raise TypeError("name must be a string.")
243
+
244
+ quota: Quota = field(metadata={"docstring": "The quota limit."})
245
+
246
+ def _validate_quota(self, quota: Quota):
247
+ if not isinstance(quota, Quota):
248
+ raise TypeError("quota must be a Quota.")
249
+
250
+ created_at: datetime = field(
251
+ metadata={"docstring": "The timestamp when this resource quota was created."}
252
+ )
253
+
254
+ def _validate_created_at(self, created_at: datetime):
255
+ if not isinstance(created_at, datetime):
256
+ raise TypeError("created_at must be a datetime.")
257
+
258
+ cloud_id: str = field(
259
+ metadata={"docstring": "ID of the cloud that this resource quota applies to."}
260
+ )
261
+
262
+ def _validate_cloud_id(self, cloud_id: str):
263
+ if not isinstance(cloud_id, str):
264
+ raise TypeError("cloud_id must be a string.")
265
+
266
+ project_id: Optional[str] = field(
267
+ default=None,
268
+ metadata={
269
+ "docstring": "ID of the project that this resource quota applies to (optional)."
270
+ },
271
+ )
272
+
273
+ def _validate_project_id(self, project_id: Optional[str]):
274
+ if project_id is not None and not isinstance(project_id, str):
275
+ raise TypeError("project_id must be a string.")
276
+
277
+ user_id: Optional[str] = field(
278
+ default=None,
279
+ metadata={
280
+ "docstring": "ID of the user that this resource quota applies to (optional)."
281
+ },
282
+ )
283
+
284
+ def _validate_user_id(self, user_id: Optional[str]):
285
+ if user_id is not None and not isinstance(user_id, str):
286
+ raise TypeError("user_id must be a string.")
287
+
288
+ is_enabled: bool = field(
289
+ default=True, metadata={"docstring": "Whether the resource quota is enabled."}
290
+ )
291
+
292
+ def _validate_is_enabled(self, is_enabled: bool):
293
+ if not isinstance(is_enabled, bool):
294
+ raise TypeError("is_enabled must be a boolean.")
295
+
296
+ deleted_at: Optional[datetime] = field(
297
+ default=None,
298
+ metadata={"docstring": "The timestamp when this resource quota was deleted."},
299
+ )
300
+
301
+ def _validate_deleted_at(self, deleted_at: Optional[datetime]):
302
+ if deleted_at is not None and not isinstance(deleted_at, datetime):
303
+ raise TypeError("deleted_at must be a datetime.")
anyscale/scripts.py CHANGED
@@ -29,6 +29,9 @@ from anyscale.commands.logs_commands import log_cli
29
29
  from anyscale.commands.machine_commands import machine_cli
30
30
  from anyscale.commands.machine_pool_commands import machine_pool_cli
31
31
  from anyscale.commands.migrate_commands import migrate_cli
32
+ from anyscale.commands.organization_invitation_commands import (
33
+ organization_invitation_cli,
34
+ )
32
35
  from anyscale.commands.project_commands import anyscale_init, project_cli
33
36
  from anyscale.commands.resource_quota_commands import resource_quota_cli
34
37
  from anyscale.commands.schedule_commands import schedule_cli
@@ -144,6 +147,7 @@ cli.add_command(service_account_cli)
144
147
  cli.add_command(resource_quota_cli)
145
148
  cli.add_command(aggregated_instance_usage_cli)
146
149
  cli.add_command(user_cli)
150
+ cli.add_command(organization_invitation_cli)
147
151
 
148
152
  ALIASES = {
149
153
  "h": anyscale_help,