Skip to content

Commit b6427ed

Browse files
authored
Vb/member export plt 2099 (#1925)
1 parent 78a7e3d commit b6427ed

File tree

4 files changed

+108
-4
lines changed

4 files changed

+108
-4
lines changed

docs/labelbox/index.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,5 +52,5 @@ Labelbox Python SDK Documentation
5252
task
5353
task-queue
5454
user
55-
user-group-upload
55+
user-group-v2
5656
webhook

docs/labelbox/user-group-v2.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
User Group
2+
===============================================================================================
3+
4+
.. automodule:: labelbox.schema.user_group_v2
5+
:members:
6+
:show-inheritance:

libs/labelbox/src/labelbox/schema/user_group_upload.py renamed to libs/labelbox/src/labelbox/schema/user_group_v2.py

Lines changed: 51 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,14 @@ class UploadReport:
5454
lines: List[UploadReportLine]
5555

5656

57-
class UserGroupUpload:
57+
@dataclass
58+
class Member:
59+
"""A member of a user group."""
60+
61+
email: str
62+
63+
64+
class UserGroupV2:
5865
"""Upload members to a user group."""
5966

6067
def __init__(self, client: Client):
@@ -80,7 +87,7 @@ def upload_members(
8087
For indicvidual email errors, the error message is available in the UploadReport.
8188
"""
8289
warnings.warn(
83-
"The upload_members for UserGroupUpload is in beta. The method name and signature may change in the future.”",
90+
"The upload_members for UserGroupV2 is in beta. The method name and signature may change in the future.”",
8491
)
8592

8693
if len(emails) == 0:
@@ -109,7 +116,7 @@ def upload_members(
109116
"text/csv",
110117
)
111118
}
112-
query = """mutation ImportMembersToGroup(
119+
query = """mutation ImportMembersToGroupPyPi(
113120
$roleId: ID!
114121
$file: Upload!
115122
$where: WhereUniqueIdInput!
@@ -183,6 +190,47 @@ def upload_members(
183190
csv_report = file_data["importUsersAsCsvToGroup"]["csvReport"]
184191
return self._parse_csv_report(csv_report)
185192

193+
def export_members(self, group_id: str) -> Optional[List[Member]]:
194+
warnings.warn(
195+
"The export_members for UserGroupV2 is in beta. The method name and signature may change in the future.",
196+
)
197+
198+
if not group_id:
199+
raise ValueError("Group id is required")
200+
201+
query = """query GetExportMembersAsCSVPyPi(
202+
$id: ID!
203+
) {
204+
userGroupV2(where: { id: $id }) {
205+
id
206+
membersAsCSV
207+
}
208+
}
209+
"""
210+
params = {
211+
"id": group_id,
212+
}
213+
214+
result = self.client.execute(query, params)
215+
if result["userGroupV2"] is None:
216+
raise ResourceNotFoundError(message="The user group is not found.")
217+
data = result["userGroupV2"]
218+
219+
return self._parse_members_csv(data["membersAsCSV"])
220+
221+
def _parse_members_csv(self, csv_data: str) -> List[Member]:
222+
csv_lines = csv_data.strip().split("\n")
223+
if not csv_lines:
224+
return []
225+
226+
members_list = []
227+
# Skip header row
228+
for email in csv_lines[1:]:
229+
if email.strip(): # Skip empty lines
230+
members_list.append(Member(email=email.strip()))
231+
232+
return members_list
233+
186234
def _get_role_id(self, role_name: str) -> Optional[str]:
187235
role_id = None
188236
query = """query GetAvailableUserRolesPyPi {
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
from unittest.mock import MagicMock
2+
3+
import pytest
4+
5+
from labelbox.schema.user_group_v2 import Member, UserGroupV2
6+
7+
8+
@pytest.fixture
9+
def client():
10+
return MagicMock()
11+
12+
13+
def test_parse_members_csv_empty(client):
14+
group = UserGroupV2(client)
15+
assert group._parse_members_csv("") == []
16+
assert group._parse_members_csv("\n") == []
17+
18+
19+
def test_parse_members_csv_header_only(client):
20+
group = UserGroupV2(client)
21+
assert group._parse_members_csv("email\n") == []
22+
23+
24+
def test_parse_members_csv_single_member(client):
25+
group = UserGroupV2(client)
26+
result = group._parse_members_csv("email\n[email protected]")
27+
assert len(result) == 1
28+
assert isinstance(result[0], Member)
29+
assert result[0].email == "[email protected]"
30+
31+
32+
def test_parse_members_csv_multiple_members(client):
33+
group = UserGroupV2(client)
34+
35+
result = group._parse_members_csv(csv_data)
36+
assert len(result) == 3
37+
assert [m.email for m in result] == [
38+
39+
40+
41+
]
42+
43+
44+
def test_parse_members_csv_handles_whitespace(client):
45+
group = UserGroupV2(client)
46+
csv_data = "email\n [email protected] \n\n[email protected]\n"
47+
result = group._parse_members_csv(csv_data)
48+
assert len(result) == 2
49+
assert result[0].email == "[email protected]"
50+
assert result[1].email == "[email protected]"

0 commit comments

Comments
 (0)