anyscale 0.24.87__py3-none-any.whl → 0.24.91__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 (120) hide show
  1. anyscale/__init__.py +56 -0
  2. anyscale/_private/anyscale_client/anyscale_client.py +158 -28
  3. anyscale/_private/anyscale_client/common.py +82 -0
  4. anyscale/_private/anyscale_client/fake_anyscale_client.py +193 -1
  5. anyscale/_private/docgen/README.md +1 -1
  6. anyscale/_private/docgen/__main__.py +74 -19
  7. anyscale/_private/docgen/api.md +0 -20
  8. anyscale/_private/docgen/generator.py +4 -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 +19 -23
  15. anyscale/client/openapi_client/__init__.py +13 -15
  16. anyscale/client/openapi_client/api/default_api.py +825 -962
  17. anyscale/client/openapi_client/models/__init__.py +13 -15
  18. anyscale/client/openapi_client/models/admin_create_user.py +255 -0
  19. anyscale/client/openapi_client/models/admin_created_user.py +281 -0
  20. anyscale/client/openapi_client/models/{sessionevent_list_response.py → admincreateduser_list_response.py} +15 -15
  21. anyscale/client/openapi_client/models/aggregated_usage_query.py +1 -29
  22. anyscale/client/openapi_client/models/{session_event_types.py → cloud_deployment_config.py} +35 -24
  23. anyscale/client/openapi_client/models/{platformfinetuningjob_response.py → clouddeploymentconfig_response.py} +11 -11
  24. anyscale/client/openapi_client/models/{company_size.py → cluster_size.py} +10 -10
  25. anyscale/client/openapi_client/models/cluster_status_details.py +2 -1
  26. anyscale/client/openapi_client/models/create_experimental_workspace.py +29 -1
  27. anyscale/client/openapi_client/models/{resubmit_ft_job_request.py → describe_machine_pool_request.py} +21 -20
  28. anyscale/client/openapi_client/models/describe_machine_pool_response.py +123 -0
  29. anyscale/client/openapi_client/models/{fine_tuning_job_status.py → describemachinepoolresponse_response.py} +34 -16
  30. anyscale/client/openapi_client/models/machine_allocation_state.py +3 -1
  31. anyscale/client/openapi_client/models/machine_state_info.py +326 -0
  32. anyscale/client/openapi_client/models/organization_marketing_questions.py +80 -54
  33. anyscale/client/openapi_client/models/request_state_info.py +210 -0
  34. anyscale/client/openapi_client/models/{platformfinetuningjob_list_response.py → scheduler_info.py} +43 -38
  35. anyscale/client/openapi_client/models/usage_by_cluster.py +28 -1
  36. anyscale/client/openapi_client/models/usage_by_user.py +30 -3
  37. anyscale/client/openapi_client/models/workload_info.py +210 -0
  38. anyscale/cloud/__init__.py +83 -0
  39. anyscale/cloud/_private/cloud_sdk.py +25 -0
  40. anyscale/cloud/commands.py +45 -0
  41. anyscale/cloud/models.py +91 -0
  42. anyscale/cluster_compute.py +1 -1
  43. anyscale/commands/aggregated_instance_usage_commands.py +4 -4
  44. anyscale/commands/cloud_commands.py +38 -2
  45. anyscale/commands/command_examples.py +67 -0
  46. anyscale/commands/job_commands.py +15 -3
  47. anyscale/commands/machine_pool_commands.py +113 -1
  48. anyscale/commands/organization_invitation_commands.py +98 -0
  49. anyscale/commands/project_commands.py +52 -2
  50. anyscale/commands/resource_quota_commands.py +98 -11
  51. anyscale/commands/service_commands.py +1 -1
  52. anyscale/commands/session_commands_hidden.py +5 -1
  53. anyscale/commands/user_commands.py +49 -0
  54. anyscale/commands/util.py +1 -1
  55. anyscale/commands/workspace_commands.py +1 -1
  56. anyscale/connect.py +1 -1
  57. anyscale/connect_utils/project.py +7 -4
  58. anyscale/controllers/cloud_controller.py +6 -6
  59. anyscale/controllers/cloud_functional_verification_controller.py +1 -1
  60. anyscale/controllers/cluster_controller.py +2 -2
  61. anyscale/controllers/compute_config_controller.py +1 -1
  62. anyscale/controllers/experimental_integrations_controller.py +1 -1
  63. anyscale/controllers/job_controller.py +8 -3
  64. anyscale/controllers/list_controller.py +2 -2
  65. anyscale/controllers/machine_pool_controller.py +12 -1
  66. anyscale/controllers/project_controller.py +4 -3
  67. anyscale/controllers/schedule_controller.py +1 -1
  68. anyscale/controllers/service_controller.py +1 -1
  69. anyscale/controllers/workspace_controller.py +1 -1
  70. anyscale/models/job_model.py +1 -1
  71. anyscale/organization_invitation/__init__.py +61 -0
  72. anyscale/organization_invitation/_private/organization_invitation_sdk.py +24 -0
  73. anyscale/organization_invitation/commands.py +84 -0
  74. anyscale/organization_invitation/models.py +45 -0
  75. anyscale/project/__init__.py +35 -0
  76. anyscale/project/_private/project_sdk.py +27 -0
  77. anyscale/project/commands.py +56 -0
  78. anyscale/project/models.py +91 -0
  79. anyscale/{project.py → project_utils.py} +3 -4
  80. anyscale/resource_quota/__init__.py +99 -0
  81. anyscale/resource_quota/_private/resource_quota_sdk.py +111 -0
  82. anyscale/resource_quota/commands.py +150 -0
  83. anyscale/resource_quota/models.py +303 -0
  84. anyscale/scripts.py +6 -0
  85. anyscale/sdk/anyscale_client/__init__.py +0 -5
  86. anyscale/sdk/anyscale_client/api/default_api.py +0 -150
  87. anyscale/sdk/anyscale_client/models/__init__.py +0 -5
  88. anyscale/sdk/anyscale_client/models/cluster_status_details.py +2 -1
  89. anyscale/sdk/anyscale_client/sdk.py +1 -1
  90. anyscale/user/__init__.py +35 -0
  91. anyscale/user/_private/user_sdk.py +32 -0
  92. anyscale/user/commands.py +42 -0
  93. anyscale/user/models.py +201 -0
  94. anyscale/util.py +15 -0
  95. anyscale/utils/cloud_utils.py +1 -1
  96. anyscale/version.py +1 -1
  97. anyscale/workspace_utils.py +1 -1
  98. {anyscale-0.24.87.dist-info → anyscale-0.24.91.dist-info}/METADATA +1 -5
  99. {anyscale-0.24.87.dist-info → anyscale-0.24.91.dist-info}/RECORD +105 -92
  100. anyscale/client/openapi_client/models/create_fine_tuning_hyperparameters.py +0 -156
  101. anyscale/client/openapi_client/models/create_fine_tuning_job_product_request.py +0 -353
  102. anyscale/client/openapi_client/models/finish_ft_job_request.py +0 -204
  103. anyscale/client/openapi_client/models/log_level_types.py +0 -100
  104. anyscale/client/openapi_client/models/paging_context.py +0 -172
  105. anyscale/client/openapi_client/models/platform_fine_tuning_job.py +0 -577
  106. anyscale/client/openapi_client/models/session_event.py +0 -267
  107. anyscale/client/openapi_client/models/session_event_cause.py +0 -150
  108. anyscale/controllers/resource_quota_controller.py +0 -183
  109. anyscale/sdk/anyscale_client/models/log_level_types.py +0 -100
  110. anyscale/sdk/anyscale_client/models/session_event.py +0 -267
  111. anyscale/sdk/anyscale_client/models/session_event_cause.py +0 -150
  112. anyscale/sdk/anyscale_client/models/session_event_types.py +0 -111
  113. anyscale/sdk/anyscale_client/models/sessionevent_list_response.py +0 -147
  114. anyscale/utils/imports/azure.py +0 -14
  115. /anyscale/{cloud.py → cloud_utils.py} +0 -0
  116. {anyscale-0.24.87.dist-info → anyscale-0.24.91.dist-info}/LICENSE +0 -0
  117. {anyscale-0.24.87.dist-info → anyscale-0.24.91.dist-info}/NOTICE +0 -0
  118. {anyscale-0.24.87.dist-info → anyscale-0.24.91.dist-info}/WHEEL +0 -0
  119. {anyscale-0.24.87.dist-info → anyscale-0.24.91.dist-info}/entry_points.txt +0 -0
  120. {anyscale-0.24.87.dist-info → anyscale-0.24.91.dist-info}/top_level.txt +0 -0
anyscale/commands/util.py CHANGED
@@ -125,7 +125,7 @@ def convert_kv_strings_to_dict(strings: Tuple[str]) -> Dict[str, str]:
125
125
  """
126
126
  ret_dict = {}
127
127
  for s in strings:
128
- split = s.split("=")
128
+ split = s.split("=", maxsplit=1)
129
129
  if len(split) != 2:
130
130
  raise click.ClickException(
131
131
  f"Invalid key-value string '{s}'. Must be of the form 'key=value'."
@@ -15,7 +15,7 @@ from anyscale.commands import workspace_commands_v2
15
15
  from anyscale.commands.util import LegacyAnyscaleCommand
16
16
  from anyscale.controllers.cluster_controller import ClusterController
17
17
  from anyscale.controllers.workspace_controller import WorkspaceController
18
- from anyscale.project import find_project_root
18
+ from anyscale.project_utils import find_project_root
19
19
  from anyscale.shared_anyscale_utils.utils.byod import BYODInfo
20
20
  from anyscale.util import get_endpoint
21
21
  from anyscale.workspace_utils import (
anyscale/connect.py CHANGED
@@ -48,7 +48,7 @@ from anyscale.connect_utils.start_interactive_session import ( # pylint:disable
48
48
  _get_interactive_shell_frame,
49
49
  start_interactive_session_block,
50
50
  )
51
- import anyscale.project
51
+ import anyscale.project_utils
52
52
  from anyscale.sdk.anyscale_client.sdk import AnyscaleSDK
53
53
  from anyscale.shared_anyscale_utils.util import slugify
54
54
  from anyscale.util import PROJECT_NAME_ENV_VAR
@@ -7,13 +7,14 @@ import yaml
7
7
  import anyscale
8
8
  from anyscale.authenticate import get_auth_api_client
9
9
  from anyscale.cli_logger import BlockLogger
10
- from anyscale.cloud import (
10
+ from anyscale.cloud_utils import (
11
11
  get_cloud_id_and_name,
12
12
  get_last_used_cloud,
13
13
  get_organization_default_cloud,
14
14
  )
15
15
  from anyscale.cluster_compute import get_cluster_compute_from_name
16
16
  import anyscale.conf
17
+ import anyscale.project_utils
17
18
  from anyscale.sdk.anyscale_client import ComputeTemplateConfig
18
19
  from anyscale.utils.connect_helpers import find_project_id
19
20
 
@@ -70,7 +71,7 @@ class ProjectBlock:
70
71
  self.log.open_block(self.block_label, block_title="Choosing a project")
71
72
 
72
73
  if self.project_dir is None and project_name is None:
73
- self.project_dir = anyscale.project.find_project_root(os.getcwd())
74
+ self.project_dir = anyscale.project_utils.find_project_root(os.getcwd())
74
75
 
75
76
  parent_cloud_id = self._get_parent_cloud_id(
76
77
  self.cloud_name, self.cluster_compute_name, self.cluster_compute_dict,
@@ -186,8 +187,10 @@ class ProjectBlock:
186
187
  project_yaml = os.path.join(project_dir, ".anyscale.yaml")
187
188
  if os.path.exists(project_yaml):
188
189
  # Validate format of project yaml and get project id
189
- proj_def = anyscale.project.ProjectDefinition(project_dir)
190
- project_id: Optional[str] = anyscale.project.get_project_id(proj_def.root)
190
+ proj_def = anyscale.project_utils.ProjectDefinition(project_dir)
191
+ project_id: Optional[str] = anyscale.project_utils.get_project_id(
192
+ proj_def.root
193
+ )
191
194
  if not project_id:
192
195
  raise click.ClickException(
193
196
  f"{project_yaml} is not correctly formatted. Please attach to a different "
@@ -43,12 +43,6 @@ from anyscale.client.openapi_client.models import (
43
43
  from anyscale.client.openapi_client.models.gcp_file_store_config import (
44
44
  GCPFileStoreConfig,
45
45
  )
46
- from anyscale.cloud import (
47
- get_cloud_id_and_name,
48
- get_cloud_json_from_id,
49
- get_cloud_resource_by_cloud_id,
50
- get_organization_id,
51
- )
52
46
  from anyscale.cloud_resource import (
53
47
  associate_aws_subnets_with_azs,
54
48
  GCS_STORAGE_PREFIX,
@@ -63,6 +57,12 @@ from anyscale.cloud_resource import (
63
57
  verify_aws_subnets,
64
58
  verify_aws_vpc,
65
59
  )
60
+ from anyscale.cloud_utils import (
61
+ get_cloud_id_and_name,
62
+ get_cloud_json_from_id,
63
+ get_cloud_resource_by_cloud_id,
64
+ get_organization_id,
65
+ )
66
66
  from anyscale.conf import ANYSCALE_IAM_ROLE_NAME
67
67
  from anyscale.controllers.base_controller import BaseController
68
68
  from anyscale.controllers.cloud_functional_verification_controller import (
@@ -30,7 +30,7 @@ from anyscale.client.openapi_client.models import (
30
30
  SessionState,
31
31
  )
32
32
  from anyscale.controllers.base_controller import BaseController
33
- from anyscale.project import get_default_project
33
+ from anyscale.project_utils import get_default_project
34
34
  from anyscale.sdk.anyscale_client.models import (
35
35
  ComputeNodeType,
36
36
  ComputeTemplateQuery,
@@ -7,7 +7,7 @@ import tabulate
7
7
  import yaml
8
8
 
9
9
  from anyscale.cli_logger import BlockLogger
10
- from anyscale.cloud import get_cloud_id_and_name, get_last_used_cloud
10
+ from anyscale.cloud_utils import get_cloud_id_and_name, get_last_used_cloud
11
11
  from anyscale.cluster_compute import (
12
12
  get_cluster_compute_from_name,
13
13
  get_default_cluster_compute,
@@ -18,7 +18,7 @@ from anyscale.cluster_env import (
18
18
  get_default_cluster_env_build,
19
19
  )
20
20
  from anyscale.controllers.base_controller import BaseController
21
- from anyscale.project import (
21
+ from anyscale.project_utils import (
22
22
  get_and_validate_project_id,
23
23
  get_proj_id_from_name,
24
24
  get_project_id,
@@ -14,7 +14,7 @@ from anyscale.anyscale_pydantic import (
14
14
  validator,
15
15
  )
16
16
  from anyscale.cli_logger import BlockLogger
17
- from anyscale.cloud import get_cloud_id_and_name
17
+ from anyscale.cloud_utils import get_cloud_id_and_name
18
18
  from anyscale.cluster_compute import get_cluster_compute_from_name
19
19
  from anyscale.conf import IDLE_TIMEOUT_DEFAULT_MINUTES
20
20
  from anyscale.controllers.base_controller import BaseController
@@ -3,7 +3,7 @@ from typing import Optional
3
3
  import click
4
4
 
5
5
  from anyscale.cli_logger import BlockLogger
6
- from anyscale.cloud import get_cloud_id_and_name
6
+ from anyscale.cloud_utils import get_cloud_id_and_name
7
7
  from anyscale.controllers.base_controller import BaseController
8
8
 
9
9
 
@@ -29,7 +29,7 @@ from anyscale.client.openapi_client.models.decorated_production_job import (
29
29
  from anyscale.client.openapi_client.models.ha_job_states import HaJobStates
30
30
  from anyscale.controllers.base_controller import BaseController
31
31
  from anyscale.models.job_model import JobConfig
32
- from anyscale.project import infer_project_id
32
+ from anyscale.project_utils import infer_project_id
33
33
  from anyscale.sdk.anyscale_client.models.job import Job
34
34
  from anyscale.sdk.anyscale_client.models.jobs_query import JobsQuery
35
35
  from anyscale.sdk.anyscale_client.models.jobs_sort_field import JobsSortField
@@ -65,6 +65,8 @@ _PENDING_STATES = {
65
65
  HaJobStates.RESTARTING,
66
66
  }
67
67
 
68
+ DEFAULT_PAGE_LIMIT = 500
69
+
68
70
 
69
71
  class MiniJobRun(BaseModel):
70
72
  last_job_run_id: str
@@ -292,6 +294,7 @@ class JobController(BaseController):
292
294
  project_id: Optional[str],
293
295
  include_archived: bool,
294
296
  max_items: int,
297
+ states: List[str],
295
298
  ) -> None:
296
299
  """
297
300
  This function will list jobs.
@@ -342,7 +345,8 @@ class JobController(BaseController):
342
345
  creator_id=creator_id,
343
346
  type_filter="BATCH_JOB",
344
347
  archive_status="ALL" if include_archived else "NOT_ARCHIVED",
345
- count=10,
348
+ count=DEFAULT_PAGE_LIMIT,
349
+ state_filter=states,
346
350
  )
347
351
  jobs_list.extend(resp.results)
348
352
  paging_token = resp.metadata.next_paging_token
@@ -354,8 +358,9 @@ class JobController(BaseController):
354
358
  creator_id=creator_id,
355
359
  type_filter="BATCH_JOB",
356
360
  archive_status="ALL" if include_archived else "NOT_ARCHIVED",
357
- count=10,
361
+ count=DEFAULT_PAGE_LIMIT,
358
362
  paging_token=paging_token,
363
+ state_filter=states,
359
364
  )
360
365
  jobs_list.extend(resp.results)
361
366
  paging_token = resp.metadata.next_paging_token
@@ -9,10 +9,10 @@ from typing import Any, Dict, List, Optional, Tuple
9
9
  import tabulate
10
10
 
11
11
  from anyscale.cli_logger import BlockLogger
12
- from anyscale.cloud import get_cloud_json_from_id
12
+ from anyscale.cloud_utils import get_cloud_json_from_id
13
13
  from anyscale.controllers.base_controller import BaseController
14
14
  from anyscale.formatters import clouds_formatter
15
- from anyscale.project import (
15
+ from anyscale.project_utils import (
16
16
  get_project_id,
17
17
  load_project_or_throw,
18
18
  )
@@ -10,11 +10,13 @@ from anyscale.client.openapi_client.models import (
10
10
  CreateMachinePoolRequest,
11
11
  CreateMachinePoolResponse,
12
12
  DeleteMachinePoolRequest,
13
+ DescribeMachinePoolRequest,
14
+ DescribeMachinePoolResponse,
13
15
  DetachMachinePoolFromCloudRequest,
14
16
  ListMachinePoolsResponse,
15
17
  UpdateMachinePoolRequest,
16
18
  )
17
- from anyscale.cloud import get_cloud_id_and_name
19
+ from anyscale.cloud_utils import get_cloud_id_and_name
18
20
  from anyscale.controllers.base_controller import BaseController
19
21
 
20
22
 
@@ -65,6 +67,15 @@ class MachinePoolController(BaseController):
65
67
  UpdateMachinePoolRequest(machine_pool_name=machine_pool_name, spec=spec,)
66
68
  )
67
69
 
70
+ def describe_machine_pool(
71
+ self, machine_pool_name: str,
72
+ ) -> DescribeMachinePoolResponse:
73
+ return self.api_client.describe_machine_pool_api_v2_machine_pools_describe_post(
74
+ describe_machine_pool_request=DescribeMachinePoolRequest(
75
+ machine_pool_name=machine_pool_name,
76
+ )
77
+ ).result
78
+
68
79
  def list_machine_pools(self,) -> ListMachinePoolsResponse:
69
80
  response = self.api_client.list_machine_pools_api_v2_machine_pools_get().result
70
81
  return response
@@ -8,9 +8,10 @@ import tabulate
8
8
 
9
9
  import anyscale
10
10
  from anyscale.cli_logger import BlockLogger
11
- from anyscale.cloud import get_cloud_id_and_name
11
+ from anyscale.cloud_utils import get_cloud_id_and_name
12
12
  from anyscale.controllers.base_controller import BaseController
13
- from anyscale.project import ( # pylint:disable=private-import
13
+ import anyscale.project_utils
14
+ from anyscale.project_utils import ( # pylint:disable=private-import
14
15
  attach_to_project_with_id,
15
16
  create_new_proj_def,
16
17
  get_proj_id_from_name,
@@ -102,7 +103,7 @@ class ProjectController(BaseController):
102
103
  "and compute configs."
103
104
  )
104
105
  self.log.warning(message)
105
- project_id_path = anyscale.project.ANYSCALE_PROJECT_FILE
106
+ project_id_path = anyscale.project_utils.ANYSCALE_PROJECT_FILE
106
107
 
107
108
  if project_id:
108
109
  # Exactly one of project_id or name must be provided
@@ -22,7 +22,7 @@ from anyscale.client.openapi_client.models.schedule_config import (
22
22
  )
23
23
  from anyscale.controllers.base_controller import BaseController
24
24
  from anyscale.models.job_model import JobConfig
25
- from anyscale.project import infer_project_id
25
+ from anyscale.project_utils import infer_project_id
26
26
  from anyscale.tables import SchedulesTable
27
27
  from anyscale.util import (
28
28
  AnyscaleEndpointFormatter,
@@ -19,7 +19,7 @@ from anyscale.client.openapi_client.models.decorated_production_service_v2_api_m
19
19
  )
20
20
  from anyscale.controllers.base_controller import BaseController
21
21
  from anyscale.models.service_model import ServiceConfig
22
- from anyscale.project import infer_project_id
22
+ from anyscale.project_utils import infer_project_id
23
23
  from anyscale.sdk.anyscale_client.models import (
24
24
  ApplyServiceModel,
25
25
  RollbackServiceModel,
@@ -15,7 +15,7 @@ from anyscale.client.openapi_client.models.experimental_workspace import (
15
15
  )
16
16
  from anyscale.controllers.base_controller import BaseController
17
17
  from anyscale.feature_flags import FLAG_DEFAULT_WORKING_DIR_FOR_PROJ
18
- from anyscale.project import get_default_project
18
+ from anyscale.project_utils import get_default_project
19
19
  from anyscale.util import get_endpoint
20
20
  from anyscale.utils.workspace_utils import (
21
21
  extract_workspace_parameters,
@@ -23,7 +23,7 @@ from anyscale.cluster_env import (
23
23
  get_default_cluster_env_build,
24
24
  validate_successful_build,
25
25
  )
26
- from anyscale.project import (
26
+ from anyscale.project_utils import (
27
27
  get_parent_cloud_id_and_name_of_project,
28
28
  get_proj_id_from_name,
29
29
  )
@@ -0,0 +1,61 @@
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.organization_invitation._private.organization_invitation_sdk import (
8
+ PrivateOrganizationInvitationSDK,
9
+ )
10
+ from anyscale.organization_invitation.commands import (
11
+ _CREATE_ARG_DOCSTRINGS,
12
+ _CREATE_EXAMPLE,
13
+ _DELETE_ARG_DOCSTRINGS,
14
+ _DELETE_EXAMPLE,
15
+ _LIST_ARG_DOCSTRINGS,
16
+ _LIST_EXAMPLE,
17
+ create,
18
+ delete,
19
+ list,
20
+ )
21
+
22
+
23
+ class OrganizationInvitationSDK:
24
+ def __init__(
25
+ self,
26
+ *,
27
+ client: Optional[AnyscaleClientInterface] = None,
28
+ logger: Optional[BlockLogger] = None,
29
+ timer: Optional[Timer] = None,
30
+ ):
31
+ self._private_sdk = PrivateOrganizationInvitationSDK(
32
+ client=client, logger=logger, timer=timer
33
+ )
34
+
35
+ @sdk_docs(
36
+ doc_py_example=_CREATE_EXAMPLE, arg_docstrings=_CREATE_ARG_DOCSTRINGS,
37
+ )
38
+ def create( # noqa: F811
39
+ self, emails: List[str],
40
+ ):
41
+ """Creates organization invitations for the provided emails
42
+ """
43
+ return self._private_sdk.create(emails=emails)
44
+
45
+ @sdk_docs(
46
+ doc_py_example=_LIST_EXAMPLE, arg_docstrings=_LIST_ARG_DOCSTRINGS,
47
+ )
48
+ def list(self): # noqa: F811
49
+ """Lists organization invitations
50
+ """
51
+ return self._private_sdk.list()
52
+
53
+ @sdk_docs(
54
+ doc_py_example=_DELETE_EXAMPLE, arg_docstrings=_DELETE_ARG_DOCSTRINGS,
55
+ )
56
+ def delete( # noqa: F811
57
+ self, email: str,
58
+ ):
59
+ """Deletes an organization invitation
60
+ """
61
+ return self._private_sdk.delete(email=email)
@@ -0,0 +1,24 @@
1
+ from typing import List, Tuple
2
+
3
+ from anyscale._private.sdk.base_sdk import BaseSDK
4
+ from anyscale.organization_invitation.models import OrganizationInvitation
5
+
6
+
7
+ class PrivateOrganizationInvitationSDK(BaseSDK):
8
+ def create(self, emails: List[str]) -> Tuple[List[str], List[str]]:
9
+ return self.client.create_organization_invitations(emails=emails)
10
+
11
+ def list(self) -> List[OrganizationInvitation]:
12
+ invitations = self.client.list_organization_invitations()
13
+ return [
14
+ OrganizationInvitation(
15
+ id=invitation.id,
16
+ email=invitation.email,
17
+ created_at=invitation.created_at,
18
+ expires_at=invitation.expires_at,
19
+ )
20
+ for invitation in invitations
21
+ ]
22
+
23
+ def delete(self, email: str) -> str:
24
+ return self.client.delete_organization_invitation(email=email).email
@@ -0,0 +1,84 @@
1
+ from typing import Dict, List, Tuple
2
+
3
+ from anyscale._private.sdk import sdk_command
4
+ from anyscale.organization_invitation._private.organization_invitation_sdk import (
5
+ PrivateOrganizationInvitationSDK,
6
+ )
7
+ from anyscale.organization_invitation.models import OrganizationInvitation
8
+
9
+
10
+ _ORGANIZATION_INVITATION_SDK_SINGLETON_KEY = "organization_invitation_sdk"
11
+
12
+ _CREATE_EXAMPLE = """
13
+ import anyscale
14
+
15
+ anyscale.organization_invitation.create(emails=["test1@anyscale.com","test2@anyscale.com"])
16
+ """
17
+
18
+ _CREATE_ARG_DOCSTRINGS = {
19
+ "emails": "The emails to send the organization invitations to."
20
+ }
21
+
22
+ _LIST_EXAMPLE = """
23
+ import anyscale
24
+
25
+ anyscale.organization_invitation.list()
26
+ """
27
+
28
+ _LIST_ARG_DOCSTRINGS: Dict[str, str] = {}
29
+
30
+ _DELETE_EXAMPLE = """
31
+ import anyscale
32
+
33
+ anyscale.organization_invitation.delete(email="test@anyscale.com")
34
+ """
35
+
36
+ _DELETE_ARG_DOCSTRINGS = {
37
+ "email": "The email of the organization invitation to delete."
38
+ }
39
+
40
+
41
+ @sdk_command(
42
+ _ORGANIZATION_INVITATION_SDK_SINGLETON_KEY,
43
+ PrivateOrganizationInvitationSDK,
44
+ doc_py_example=_CREATE_EXAMPLE,
45
+ arg_docstrings=_CREATE_ARG_DOCSTRINGS,
46
+ )
47
+ def create(
48
+ emails: List[str], *, _sdk: PrivateOrganizationInvitationSDK
49
+ ) -> Tuple[List[str], List[str]]:
50
+ """Creates organization invitations for the provided emails.
51
+
52
+ Returns a tuple of successful emails and error messages.
53
+ """
54
+ return _sdk.create(emails=emails)
55
+
56
+
57
+ @sdk_command(
58
+ _ORGANIZATION_INVITATION_SDK_SINGLETON_KEY,
59
+ PrivateOrganizationInvitationSDK,
60
+ doc_py_example=_LIST_EXAMPLE,
61
+ arg_docstrings=_LIST_ARG_DOCSTRINGS,
62
+ )
63
+ def list( # noqa: A001
64
+ *, _sdk: PrivateOrganizationInvitationSDK
65
+ ) -> List[OrganizationInvitation]:
66
+ """Lists organization invitations.
67
+
68
+ Returns a list of organization invitations.
69
+ """
70
+ return _sdk.list()
71
+
72
+
73
+ @sdk_command(
74
+ _ORGANIZATION_INVITATION_SDK_SINGLETON_KEY,
75
+ PrivateOrganizationInvitationSDK,
76
+ doc_py_example=_DELETE_EXAMPLE,
77
+ arg_docstrings=_DELETE_ARG_DOCSTRINGS,
78
+ )
79
+ def delete(email: str, *, _sdk: PrivateOrganizationInvitationSDK) -> str:
80
+ """Deletes an organization invitation.
81
+
82
+ Returns the email of the deleted organization invitation.
83
+ """
84
+ return _sdk.delete(email)
@@ -0,0 +1,45 @@
1
+ from dataclasses import dataclass, field
2
+ from datetime import datetime
3
+
4
+ from anyscale._private.models import ModelBase
5
+
6
+
7
+ @dataclass(frozen=True)
8
+ class OrganizationInvitation(ModelBase):
9
+ """Organization invitation model.
10
+ """
11
+
12
+ __doc_py_example__ = """\
13
+ import anyscale
14
+ from anyscale.organization_invitation.models import OrganizationInvitation
15
+
16
+ organization_invitations: List[OrganizationInvitation] = anyscale.organization_invitation.list()
17
+ """
18
+
19
+ id: str = field(metadata={"docstring": "ID of the organization invitation."},)
20
+
21
+ def _validate_id(self, id: str): # noqa: A002
22
+ if not isinstance(id, str):
23
+ raise TypeError("id must be a string.")
24
+
25
+ email: str = field(metadata={"docstring": "Email of the organization invitation."})
26
+
27
+ def _validate_email(self, email: str):
28
+ if not isinstance(email, str):
29
+ raise TypeError("email must be a string.")
30
+
31
+ created_at: datetime = field(
32
+ metadata={"docstring": "Creation time of the organization invitation."},
33
+ )
34
+
35
+ def _validate_created_at(self, created_at: datetime):
36
+ if not isinstance(created_at, datetime):
37
+ raise TypeError("created_at must be a datetime.")
38
+
39
+ expires_at: datetime = field(
40
+ metadata={"docstring": "Expiration time of the organization invitation."},
41
+ )
42
+
43
+ def _validate_expires_at(self, expires_at: datetime):
44
+ if not isinstance(expires_at, datetime):
45
+ raise TypeError("expires_at must be a datetime.")
@@ -0,0 +1,35 @@
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.project._private.project_sdk import PrivateProjectSDK
8
+ from anyscale.project.commands import (
9
+ _ADD_COLLABORATORS_DOCSTRINGS,
10
+ _ADD_COLLABORATORS_EXAMPLE,
11
+ add_collaborators,
12
+ )
13
+ from anyscale.project.models import CreateProjectCollaborator
14
+
15
+
16
+ class ProjectSDK:
17
+ def __init__(
18
+ self,
19
+ *,
20
+ client: Optional[AnyscaleClientInterface] = None,
21
+ logger: Optional[BlockLogger] = None,
22
+ timer: Optional[Timer] = None,
23
+ ):
24
+ self._private_sdk = PrivateProjectSDK(client=client, logger=logger, timer=timer)
25
+
26
+ @sdk_docs(
27
+ doc_py_example=_ADD_COLLABORATORS_EXAMPLE,
28
+ arg_docstrings=_ADD_COLLABORATORS_DOCSTRINGS,
29
+ )
30
+ def add_collaborators( # noqa: F811
31
+ self, cloud: str, project: str, collaborators: List[CreateProjectCollaborator],
32
+ ) -> str:
33
+ """Batch add collaborators to a project.
34
+ """
35
+ return self._private_sdk.add_collaborators(cloud, project, collaborators)
@@ -0,0 +1,27 @@
1
+ from typing import List
2
+
3
+ from anyscale._private.sdk.base_sdk import BaseSDK
4
+ from anyscale.client.openapi_client import (
5
+ CreateUserProjectCollaborator,
6
+ CreateUserProjectCollaboratorValue,
7
+ )
8
+ from anyscale.project.models import CreateProjectCollaborator
9
+
10
+
11
+ class PrivateProjectSDK(BaseSDK):
12
+ def add_collaborators(
13
+ self, cloud: str, project: str, collaborators: List[CreateProjectCollaborator]
14
+ ) -> str:
15
+ cloud_id = self.client.get_cloud_id(cloud_name=cloud, compute_config_id=None)
16
+ project_id = self.client.get_project_id(parent_cloud_id=cloud_id, name=project)
17
+
18
+ return self.client.add_project_collaborators(
19
+ project_id=project_id,
20
+ collaborators=[
21
+ CreateUserProjectCollaborator(
22
+ value=CreateUserProjectCollaboratorValue(email=collaborator.email),
23
+ permission_level=collaborator.permission_level.lower(),
24
+ )
25
+ for collaborator in collaborators
26
+ ],
27
+ )
@@ -0,0 +1,56 @@
1
+ from typing import List
2
+
3
+ from anyscale._private.sdk import sdk_command
4
+ from anyscale.project._private.project_sdk import PrivateProjectSDK
5
+ from anyscale.project.models import CreateProjectCollaborator
6
+
7
+
8
+ _PROJECT_SDK_SINGLETON_KEY = "project_sdk"
9
+
10
+ _ADD_COLLABORATORS_EXAMPLE = """
11
+ import anyscale
12
+ from anyscale.project.models import CreateProjectCollaborator, ProjectPermissionLevel
13
+
14
+ anyscale.project.add_collaborators(
15
+ cloud="cloud_name",
16
+ project="project_name",
17
+ collaborators=[
18
+ CreateProjectCollaborator(
19
+ email="test1@anyscale.com",
20
+ permission_level=ProjectPermissionLevel.OWNER,
21
+ ),
22
+ CreateProjectCollaborator(
23
+ email="test2@anyscale.com",
24
+ permission_level=ProjectPermissionLevel.WRITE,
25
+ ),
26
+ CreateProjectCollaborator(
27
+ email="test3@anyscale.com",
28
+ permission_level=ProjectPermissionLevel.READONLY,
29
+ ),
30
+ ],
31
+ )
32
+ """
33
+
34
+ _ADD_COLLABORATORS_DOCSTRINGS = {
35
+ "cloud": "The cloud that the project belongs to.",
36
+ "project": "The project to add users to.",
37
+ "collaborators": "The list of collaborators to add to the project.",
38
+ }
39
+
40
+
41
+ @sdk_command(
42
+ _PROJECT_SDK_SINGLETON_KEY,
43
+ PrivateProjectSDK,
44
+ doc_py_example=_ADD_COLLABORATORS_EXAMPLE,
45
+ arg_docstrings=_ADD_COLLABORATORS_DOCSTRINGS,
46
+ )
47
+ def add_collaborators(
48
+ cloud: str,
49
+ project: str,
50
+ collaborators: List[CreateProjectCollaborator],
51
+ *,
52
+ _sdk: PrivateProjectSDK
53
+ ) -> str:
54
+ """Batch add collaborators to a project.
55
+ """
56
+ return _sdk.add_collaborators(cloud, project, collaborators)