Skip to content

Commit aeaebb0

Browse files
committed
Add organization client
* Add team scoping * Add multi-run and multi-version APIs logic * Improve tagging
1 parent e96d6bc commit aeaebb0

4 files changed

Lines changed: 1779 additions & 397 deletions

File tree

cli/polyaxon/_client/organization.py

Lines changed: 72 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
from polyaxon._constants.globals import DEFAULT
99
from polyaxon._env_vars.getters.user import get_local_owner
1010
from polyaxon._schemas.lifecycle import V1ProjectVersionKind
11+
from polyaxon._sdk.schemas.v1_entities_transfer import V1EntitiesTransfer
12+
from polyaxon._sdk.schemas.v1_entities_tags import V1EntitiesTags
1113
from polyaxon._sdk.schemas.v1_list_organization_members_response import (
1214
V1ListOrganizationMembersResponse,
1315
)
@@ -40,15 +42,28 @@ class OrganizationClient(ClientMixin):
4042
* If you use this client in the context of a job or a service managed by Polyaxon,
4143
a configuration will be available to resolve the values based on that run.
4244
43-
Team Scoping:
44-
Operations can be scoped to a specific team within an organization by providing
45-
the owner in the format "owner/team". When a team is specified, methods like
46-
list_runs, get_run, delete_runs, stop_runs, invalidate_runs, and list_versions
47-
will operate only within that team's scope rather than organization-wide.
45+
Team Scoping (Using as a Team Client):
46+
This client can be used as a **Team Client** by providing the owner in the
47+
format "owner/team". When a team is specified, all applicable methods will
48+
operate within that team's scope rather than organization-wide.
49+
50+
Team-scoped methods include:
51+
* Runs: list_runs, get_run, approve_runs, archive_runs, restore_runs,
52+
delete_runs, stop_runs, skip_runs, invalidate_runs, bookmark_runs,
53+
tag_runs, transfer_runs
54+
* Versions: list_versions, list_component_versions, list_model_versions,
55+
list_artifact_versions
56+
* Artifacts: list_runs_artifacts_lineage
4857
4958
Examples:
50-
OrganizationClient(owner="my-org") # Organization-wide operations
51-
OrganizationClient(owner="my-org/engineering") # Team-scoped operations
59+
# Organization-wide operations
60+
org_client = OrganizationClient(owner="my-org")
61+
org_client.list_runs() # All runs across the organization
62+
63+
# Team-scoped operations (effectively a "Team Client")
64+
team_client = OrganizationClient(owner="my-org/engineering")
65+
team_client.list_runs() # Only runs within the engineering team
66+
team_client.list_model_versions() # Only model versions within the team
5267
5368
Properties:
5469
owner: str.
@@ -358,6 +373,8 @@ def approve_runs(self, uuids: Union[List[str], V1Uuids]):
358373
"""
359374
if isinstance(uuids, list):
360375
uuids = V1Uuids(uuids=uuids)
376+
if self.team:
377+
return self.client.teams_v1.approve_team_runs(self.owner, self.team, uuids)
361378
return self.client.organizations_v1.approve_organization_runs(
362379
self.owner, body=uuids
363380
)
@@ -373,6 +390,8 @@ def archive_runs(self, uuids: Union[List[str], V1Uuids]):
373390
"""
374391
if isinstance(uuids, list):
375392
uuids = V1Uuids(uuids=uuids)
393+
if self.team:
394+
return self.client.teams_v1.archive_team_runs(self.owner, self.team, uuids)
376395
return self.client.organizations_v1.archive_organization_runs(
377396
self.owner, body=uuids
378397
)
@@ -388,6 +407,8 @@ def restore_runs(self, uuids: Union[List[str], V1Uuids]):
388407
"""
389408
if isinstance(uuids, list):
390409
uuids = V1Uuids(uuids=uuids)
410+
if self.team:
411+
return self.client.teams_v1.restore_team_runs(self.owner, self.team, uuids)
391412
return self.client.organizations_v1.restore_organization_runs(
392413
self.owner, body=uuids
393414
)
@@ -444,6 +465,10 @@ def skip_runs(self, uuids: Union[List[str], V1Uuids]):
444465
"""
445466
if isinstance(uuids, list):
446467
uuids = V1Uuids(uuids=uuids)
468+
if self.team:
469+
return self.client.teams_v1.skip_team_runs(
470+
self.owner, self.team, body=uuids
471+
)
447472
return self.client.organizations_v1.skip_organization_runs(
448473
self.owner, body=uuids
449474
)
@@ -479,32 +504,63 @@ def bookmark_runs(self, uuids: Union[List[str], V1Uuids]):
479504
"""
480505
if isinstance(uuids, list):
481506
uuids = V1Uuids(uuids=uuids)
507+
if self.team:
508+
return self.client.teams_v1.bookmark_team_runs(
509+
self.owner, self.team, body=uuids
510+
)
482511
return self.client.organizations_v1.bookmark_organization_runs(
483512
self.owner, body=uuids
484513
)
485514

486515
@client_handler(check_no_op=True, check_offline=True)
487-
def tag_runs(self, data: Dict):
516+
def tag_runs(self, uuids: Union[List[str], V1Uuids], tags: List[str]):
488517
"""Tags multiple runs in the organization.
489518
490519
[Organization API](/docs/api/#operation/TagOrganizationRuns)
491520
492521
Args:
493522
data: Dict, required, must include 'uuids' and 'tags' fields.
494523
"""
524+
if isinstance(uuids, list):
525+
uuids = V1Uuids(uuids=uuids)
526+
data = V1EntitiesTags(
527+
uuids=uuids.uuids,
528+
tags=tags,
529+
)
530+
if self.team:
531+
return self.client.teams_v1.tag_team_runs(self.owner, self.team, body=data)
495532
return self.client.organizations_v1.tag_organization_runs(self.owner, body=data)
496533

497534
@client_handler(check_no_op=True, check_offline=True)
498-
def transfer_runs(self, data: Dict):
535+
def transfer_runs(
536+
self,
537+
uuids: Union[List[str], V1Uuids],
538+
to_project: str,
539+
):
499540
"""Transfers multiple runs to another project in the organization.
500541
501542
[Organization API](/docs/api/#operation/TransferOrganizationRuns)
502543
503544
Args:
504-
data: Dict, required, must include 'uuids' and 'project' fields.
545+
uuids: List[str] or V1Uuids, required, list of run uuids to transfer.
546+
to_project: str, required, the destination project to transfer the runs to.
505547
"""
548+
if isinstance(uuids, list):
549+
transfer_data = V1EntitiesTransfer(uuids=uuids, project=to_project)
550+
else:
551+
transfer_data = V1EntitiesTransfer(uuids=uuids.uuids, project=to_project)
552+
553+
logger.info(
554+
"Transferring {} runs to project {}".format(
555+
len(transfer_data.uuids), to_project
556+
)
557+
)
558+
if self.team:
559+
return self.client.teams_v1.transfer_team_runs(
560+
self.owner, self.team, body=transfer_data
561+
)
506562
return self.client.organizations_v1.transfer_organization_runs(
507-
self.owner, body=data
563+
self.owner, body=transfer_data
508564
)
509565

510566
# Organization Versions Management
@@ -685,6 +741,11 @@ def list_runs_artifacts_lineage(
685741
params["bookmarks"] = bookmarks
686742
if mode:
687743
params["mode"] = mode
744+
745+
if self.team:
746+
return self.client.teams_v1.get_team_runs_artifacts_lineage(
747+
self.owner, self.team, **params
748+
)
688749
return self.client.organizations_v1.get_organization_runs_artifacts_lineage(
689750
self.owner, **params
690751
)

cli/polyaxon/_client/project.py

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
from polyaxon._contexts import paths as ctx_paths
1818
from polyaxon._env_vars.getters.user import get_local_owner
1919
from polyaxon._schemas.lifecycle import V1ProjectVersionKind, V1StageCondition, V1Stages
20+
from polyaxon._sdk.schemas.v1_entities_tags import V1EntitiesTags
2021
from polyaxon._sdk.schemas.v1_entities_transfer import V1EntitiesTransfer
2122
from polyaxon._sdk.schemas.v1_list_project_versions_response import (
2223
V1ListProjectVersionsResponse,
@@ -48,14 +49,26 @@ class ProjectClient(ClientMixin):
4849
If you intend to create a new project instance or to list projects,
4950
only the `owner` parameter is required.
5051
52+
Team Scoping:
53+
Projects can be scoped to a specific team within an organization by providing
54+
the owner in the format "owner/team". When a team is specified, the project
55+
will be created under that team using the team projects API.
56+
57+
Examples:
58+
ProjectClient(owner="my-org", project="my-project") # Organization project
59+
ProjectClient(owner="my-org/engineering", project="my-project") # Team project
60+
5161
Properties:
5262
project: str.
5363
owner: str.
64+
team: str.
5465
project_data: V1Project.
5566
5667
Args:
5768
owner: str, optional, the owner is the username or
5869
the organization name owning this project.
70+
Can be specified as "owner" for organization scope or "owner/team"
71+
for team-scoped projects.
5972
project: str, optional, project name.
6073
client: [PolyaxonClient](/docs/core/python-library/polyaxon-client/), optional,
6174
an instance of a configured client, if not passed,
@@ -375,14 +388,20 @@ def bookmark_runs(self, uuids: Union[List[str], V1Uuids]):
375388
return self.client.runs_v1.bookmark_runs(self.owner, self.project, body=uuids)
376389

377390
@client_handler(check_no_op=True, check_offline=True)
378-
def tag_runs(self, data: Dict):
391+
def tag_runs(self, uuids: Union[List[str], V1Uuids], tags: List[str]):
379392
"""Tags multiple runs in the project.
380393
381394
[Run API](/docs/api/#operation/TagRuns)
382395
383396
Args:
384397
data: Dict, required, must include 'uuids' and 'tags' fields.
385398
"""
399+
if isinstance(uuids, list):
400+
uuids = V1Uuids(uuids=uuids)
401+
data = V1EntitiesTags(
402+
uuids=uuids.uuids,
403+
tags=tags,
404+
)
386405
return self.client.runs_v1.tag_runs(self.owner, self.project, body=data)
387406

388407
def _validate_kind(self, kind: V1ProjectVersionKind):

0 commit comments

Comments
 (0)