anyscale 0.24.88__py3-none-any.whl → 0.25.5__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- anyscale/__init__.py +56 -0
- anyscale/_private/anyscale_client/anyscale_client.py +179 -28
- anyscale/_private/anyscale_client/common.py +109 -2
- anyscale/_private/anyscale_client/fake_anyscale_client.py +239 -1
- anyscale/_private/docgen/README.md +1 -1
- anyscale/_private/docgen/__main__.py +71 -21
- anyscale/_private/docgen/api.md +13 -20
- anyscale/_private/docgen/generator.py +3 -2
- anyscale/_private/docgen/models.md +4 -49
- anyscale/_private/workload/workload_config.py +21 -7
- anyscale/aggregated_instance_usage/__init__.py +1 -1
- anyscale/aggregated_instance_usage/commands.py +2 -4
- anyscale/aggregated_instance_usage/models.py +8 -8
- anyscale/client/README.md +25 -22
- anyscale/client/openapi_client/__init__.py +16 -14
- anyscale/client/openapi_client/api/default_api.py +1139 -959
- anyscale/client/openapi_client/models/__init__.py +16 -14
- anyscale/client/openapi_client/models/baseimagesenum.py +43 -1
- anyscale/client/openapi_client/models/{session_event_types.py → cloud_deployment_config.py} +35 -24
- anyscale/client/openapi_client/models/{platformfinetuningjob_response.py → clouddeploymentconfig_response.py} +11 -11
- anyscale/client/openapi_client/models/{log_level_types.py → cluster_event_source.py} +12 -7
- anyscale/client/openapi_client/models/{company_size.py → cluster_size.py} +10 -10
- anyscale/client/openapi_client/models/cluster_status_details.py +2 -1
- anyscale/client/openapi_client/models/{sessionevent_list_response.py → clusterevent_list_response.py} +15 -15
- anyscale/client/openapi_client/models/create_experimental_workspace.py +29 -1
- anyscale/client/openapi_client/models/create_notification_channel_record.py +29 -3
- anyscale/client/openapi_client/models/decorated_interactive_session.py +1 -57
- anyscale/client/openapi_client/models/decorated_job.py +1 -57
- anyscale/client/openapi_client/models/decorated_job_submission.py +1 -29
- anyscale/client/openapi_client/models/decorated_production_job.py +1 -29
- anyscale/client/openapi_client/models/decorated_session.py +1 -57
- anyscale/client/openapi_client/models/decorated_unified_job.py +1 -30
- anyscale/client/openapi_client/models/{resubmit_ft_job_request.py → describe_machine_pool_request.py} +21 -20
- anyscale/client/openapi_client/models/describe_machine_pool_response.py +123 -0
- anyscale/client/openapi_client/models/describemachinepoolresponse_response.py +121 -0
- anyscale/client/openapi_client/models/ha_jobs_sort_field.py +1 -2
- anyscale/client/openapi_client/models/internal_production_job.py +1 -29
- anyscale/client/openapi_client/models/jobs_sort_field.py +1 -2
- anyscale/client/openapi_client/models/machine_allocation_state.py +3 -1
- anyscale/client/openapi_client/models/machine_state_info.py +326 -0
- anyscale/client/openapi_client/models/{fine_tuning_job_status.py → notification_channel_slack_config.py} +34 -16
- anyscale/client/openapi_client/models/organization_marketing_questions.py +80 -54
- anyscale/client/openapi_client/models/request_state_info.py +210 -0
- anyscale/client/openapi_client/models/{platformfinetuningjob_list_response.py → scheduler_info.py} +43 -38
- anyscale/client/openapi_client/models/serve_deployment_fast_api_docs_status.py +123 -0
- anyscale/client/openapi_client/models/serve_deployment_state.py +2 -1
- anyscale/client/openapi_client/models/servedeploymentfastapidocsstatus_response.py +121 -0
- anyscale/client/openapi_client/models/sessions_sort_field.py +1 -2
- anyscale/client/openapi_client/models/supportedbaseimagesenum.py +43 -1
- anyscale/client/openapi_client/models/unified_job_sort_field.py +1 -2
- anyscale/client/openapi_client/models/update_cloud_collaborator.py +121 -0
- anyscale/client/openapi_client/models/usage_by_cluster.py +28 -1
- anyscale/client/openapi_client/models/usage_by_user.py +30 -3
- anyscale/client/openapi_client/models/workload_info.py +210 -0
- anyscale/cloud/__init__.py +83 -0
- anyscale/cloud/_private/cloud_sdk.py +25 -0
- anyscale/cloud/commands.py +45 -0
- anyscale/cloud/models.py +91 -0
- anyscale/cluster_compute.py +1 -1
- anyscale/commands/aggregated_instance_usage_commands.py +4 -4
- anyscale/commands/cloud_commands.py +87 -14
- anyscale/commands/command_examples.py +65 -0
- anyscale/commands/job_commands.py +15 -3
- anyscale/commands/machine_pool_commands.py +113 -1
- anyscale/commands/organization_invitation_commands.py +98 -0
- anyscale/commands/project_commands.py +52 -2
- anyscale/commands/resource_quota_commands.py +98 -11
- anyscale/commands/service_account_commands.py +65 -8
- anyscale/commands/service_commands.py +61 -1
- anyscale/commands/session_commands_hidden.py +5 -1
- anyscale/commands/user_commands.py +1 -1
- anyscale/commands/util.py +2 -2
- anyscale/commands/workspace_commands.py +1 -1
- anyscale/connect.py +1 -1
- anyscale/connect_utils/project.py +7 -4
- anyscale/controllers/cloud_controller.py +63 -30
- anyscale/controllers/cloud_functional_verification_controller.py +1 -1
- anyscale/controllers/cluster_controller.py +3 -11
- anyscale/controllers/compute_config_controller.py +1 -1
- anyscale/controllers/experimental_integrations_controller.py +1 -1
- anyscale/controllers/job_controller.py +8 -6
- anyscale/controllers/list_controller.py +2 -2
- anyscale/controllers/machine_pool_controller.py +12 -1
- anyscale/controllers/project_controller.py +4 -3
- anyscale/controllers/schedule_controller.py +1 -1
- anyscale/controllers/service_controller.py +1 -1
- anyscale/controllers/workspace_controller.py +1 -1
- anyscale/models/job_model.py +1 -1
- anyscale/organization_invitation/__init__.py +61 -0
- anyscale/organization_invitation/_private/organization_invitation_sdk.py +24 -0
- anyscale/organization_invitation/commands.py +84 -0
- anyscale/organization_invitation/models.py +45 -0
- anyscale/project/__init__.py +35 -0
- anyscale/project/_private/project_sdk.py +27 -0
- anyscale/project/commands.py +56 -0
- anyscale/project/models.py +91 -0
- anyscale/{project.py → project_utils.py} +3 -4
- anyscale/resource_quota/__init__.py +99 -0
- anyscale/resource_quota/_private/resource_quota_sdk.py +120 -0
- anyscale/resource_quota/commands.py +150 -0
- anyscale/resource_quota/models.py +303 -0
- anyscale/scripts.py +4 -0
- anyscale/sdk/anyscale_client/__init__.py +0 -5
- anyscale/sdk/anyscale_client/api/default_api.py +119 -150
- anyscale/sdk/anyscale_client/models/__init__.py +0 -5
- anyscale/sdk/anyscale_client/models/baseimagesenum.py +43 -1
- anyscale/sdk/anyscale_client/models/cluster_status_details.py +2 -1
- anyscale/sdk/anyscale_client/models/jobs_sort_field.py +1 -2
- anyscale/sdk/anyscale_client/models/supportedbaseimagesenum.py +43 -1
- anyscale/sdk/anyscale_client/sdk.py +1 -1
- anyscale/service/__init__.py +21 -0
- anyscale/service/_private/service_sdk.py +13 -0
- anyscale/service/commands.py +35 -0
- anyscale/service_account/__init__.py +88 -0
- anyscale/service_account/_private/service_account_sdk.py +101 -0
- anyscale/service_account/commands.py +147 -0
- anyscale/service_account/models.py +66 -0
- anyscale/shared_anyscale_utils/latest_ray_version.py +1 -1
- anyscale/shared_anyscale_utils/utils/id_gen.py +2 -0
- anyscale/user/__init__.py +1 -1
- anyscale/user/commands.py +1 -1
- anyscale/user/models.py +25 -15
- anyscale/util.py +23 -0
- anyscale/utils/cloud_utils.py +1 -1
- anyscale/version.py +1 -1
- anyscale/workspace_utils.py +1 -1
- {anyscale-0.24.88.dist-info → anyscale-0.25.5.dist-info}/METADATA +1 -5
- {anyscale-0.24.88.dist-info → anyscale-0.25.5.dist-info}/RECORD +134 -119
- anyscale/client/openapi_client/models/create_fine_tuning_hyperparameters.py +0 -156
- anyscale/client/openapi_client/models/create_fine_tuning_job_product_request.py +0 -353
- anyscale/client/openapi_client/models/finish_ft_job_request.py +0 -204
- anyscale/client/openapi_client/models/platform_fine_tuning_job.py +0 -577
- anyscale/client/openapi_client/models/session_event.py +0 -267
- anyscale/client/openapi_client/models/session_event_cause.py +0 -150
- anyscale/controllers/resource_quota_controller.py +0 -183
- anyscale/controllers/service_account_controller.py +0 -168
- anyscale/sdk/anyscale_client/models/log_level_types.py +0 -100
- anyscale/sdk/anyscale_client/models/session_event.py +0 -267
- anyscale/sdk/anyscale_client/models/session_event_cause.py +0 -150
- anyscale/sdk/anyscale_client/models/session_event_types.py +0 -111
- anyscale/sdk/anyscale_client/models/sessionevent_list_response.py +0 -147
- anyscale/utils/imports/azure.py +0 -14
- /anyscale/{cloud.py → cloud_utils.py} +0 -0
- {anyscale-0.24.88.dist-info → anyscale-0.25.5.dist-info}/LICENSE +0 -0
- {anyscale-0.24.88.dist-info → anyscale-0.25.5.dist-info}/NOTICE +0 -0
- {anyscale-0.24.88.dist-info → anyscale-0.25.5.dist-info}/WHEEL +0 -0
- {anyscale-0.24.88.dist-info → anyscale-0.25.5.dist-info}/entry_points.txt +0 -0
- {anyscale-0.24.88.dist-info → anyscale-0.25.5.dist-info}/top_level.txt +0 -0
@@ -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.
|
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.
|
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.
|
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.
|
11
|
+
from anyscale.cloud_utils import get_cloud_id_and_name
|
12
12
|
from anyscale.controllers.base_controller import BaseController
|
13
|
-
|
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.
|
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.
|
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.
|
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.
|
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,
|
anyscale/models/job_model.py
CHANGED
@@ -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)
|
@@ -0,0 +1,91 @@
|
|
1
|
+
from dataclasses import dataclass, field
|
2
|
+
from typing import Any, Dict, List
|
3
|
+
|
4
|
+
from anyscale._private.models import ModelBase, ModelEnum
|
5
|
+
|
6
|
+
|
7
|
+
class ProjectPermissionLevel(ModelEnum):
|
8
|
+
OWNER = "OWNER"
|
9
|
+
WRITE = "WRITE"
|
10
|
+
READONLY = "READONLY"
|
11
|
+
|
12
|
+
__docstrings__ = {
|
13
|
+
OWNER: "Owner permission level for the project",
|
14
|
+
WRITE: "Write permission level for the project",
|
15
|
+
READONLY: "Readonly permission level for the project",
|
16
|
+
}
|
17
|
+
|
18
|
+
|
19
|
+
@dataclass(frozen=True)
|
20
|
+
class CreateProjectCollaborator(ModelBase):
|
21
|
+
"""User to be added as a collaborator to a project.
|
22
|
+
"""
|
23
|
+
|
24
|
+
__doc_py_example__ = """\
|
25
|
+
import anyscale
|
26
|
+
from anyscale.project.models import ProjectPermissionLevel, CreateProjectCollaborator
|
27
|
+
create_project_collaborator = CreateProjectCollaborator(
|
28
|
+
# Email of the user to be added as a collaborator
|
29
|
+
email="test@anyscale.com",
|
30
|
+
# Permission level for the user to the project (ProjectPermissionLevel.OWNER, ProjectPermissionLevel.WRITE, ProjectPermissionLevel.READONLY)
|
31
|
+
permission_level=ProjectPermissionLevel.READONLY,
|
32
|
+
)
|
33
|
+
"""
|
34
|
+
|
35
|
+
def _validate_email(self, email: str):
|
36
|
+
if not isinstance(email, str):
|
37
|
+
raise TypeError("Email must be a string.")
|
38
|
+
|
39
|
+
email: str = field(
|
40
|
+
metadata={"docstring": "Email of the user to be added as a collaborator."},
|
41
|
+
)
|
42
|
+
|
43
|
+
def _validate_permission_level(
|
44
|
+
self, permission_level: ProjectPermissionLevel
|
45
|
+
) -> ProjectPermissionLevel:
|
46
|
+
if isinstance(permission_level, str):
|
47
|
+
return ProjectPermissionLevel.validate(permission_level)
|
48
|
+
elif isinstance(permission_level, ProjectPermissionLevel):
|
49
|
+
return permission_level
|
50
|
+
else:
|
51
|
+
raise TypeError(
|
52
|
+
f"'permission_level' must be a 'ProjectPermissionLevel' (it is {type(permission_level)})."
|
53
|
+
)
|
54
|
+
|
55
|
+
permission_level: ProjectPermissionLevel = field( # type: ignore
|
56
|
+
default=ProjectPermissionLevel.READONLY, # type: ignore
|
57
|
+
metadata={
|
58
|
+
"docstring": "Permission level the added user should have for the project" # type: ignore
|
59
|
+
f"(one of: {','.join([str(m.value) for m in ProjectPermissionLevel])}", # type: ignore
|
60
|
+
},
|
61
|
+
)
|
62
|
+
|
63
|
+
|
64
|
+
@dataclass(frozen=True)
|
65
|
+
class CreateProjectCollaborators(ModelBase):
|
66
|
+
"""List of users to be added as collaborators to a project.
|
67
|
+
"""
|
68
|
+
|
69
|
+
__doc_py_example__ = """\
|
70
|
+
import anyscale
|
71
|
+
from anyscale.project.models import ProjectPermissionLevel, CreateProjectCollaborator, CreateProjectCollaborators
|
72
|
+
create_project_collaborator = CreateProjectCollaborator(
|
73
|
+
# Email of the user to be added as a collaborator
|
74
|
+
email="test@anyscale.com",
|
75
|
+
# Permission level for the user to the project (ProjectPermissionLevel.OWNER, ProjectPermissionLevel.WRITE, ProjectPermissionLevel.READONLY)
|
76
|
+
permission_level=ProjectPermissionLevel.READONLY,
|
77
|
+
)
|
78
|
+
create_project_collaborators = CreateProjectCollaborators(
|
79
|
+
collaborators=[create_project_collaborator]
|
80
|
+
)
|
81
|
+
"""
|
82
|
+
|
83
|
+
collaborators: List[Dict[str, Any]] = field(
|
84
|
+
metadata={
|
85
|
+
"docstring": "List of users to be added as collaborators to a project."
|
86
|
+
},
|
87
|
+
)
|
88
|
+
|
89
|
+
def _validate_collaborators(self, collaborators: List[Dict[str, Any]]):
|
90
|
+
if not isinstance(collaborators, list):
|
91
|
+
raise TypeError("Collaborators must be a list.")
|
@@ -5,12 +5,11 @@ import click
|
|
5
5
|
from click import ClickException
|
6
6
|
import yaml
|
7
7
|
|
8
|
-
import anyscale
|
9
8
|
from anyscale.authenticate import get_auth_api_client
|
10
9
|
from anyscale.cli_logger import BlockLogger
|
11
10
|
from anyscale.client.openapi_client import Project
|
12
11
|
from anyscale.client.openapi_client.api.default_api import DefaultApi
|
13
|
-
from anyscale.
|
12
|
+
from anyscale.cloud_utils import get_cloud_id_and_name
|
14
13
|
from anyscale.cluster_compute import (
|
15
14
|
get_cluster_compute_from_name,
|
16
15
|
get_selected_cloud_id_or_default,
|
@@ -301,13 +300,13 @@ def create_new_proj_def(
|
|
301
300
|
name = slugify(name)
|
302
301
|
log.info(f"Normalized project name to {name}")
|
303
302
|
|
304
|
-
project_definition =
|
303
|
+
project_definition = ProjectDefinition(os.getcwd())
|
305
304
|
project_definition.config["name"] = name
|
306
305
|
return name, project_definition
|
307
306
|
|
308
307
|
|
309
308
|
def _do_attach(project_id: str, is_create_project: bool) -> None:
|
310
|
-
with open(
|
309
|
+
with open(ANYSCALE_PROJECT_FILE, "w") as f:
|
311
310
|
yaml.dump(
|
312
311
|
{"project_id": project_id}, f,
|
313
312
|
)
|
@@ -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)
|