@@ -54,6 +54,20 @@ class UploadReport:
5454 lines : List [UploadReportLine ]
5555
5656
57+ @dataclass
58+ class Member :
59+ """A member of a user group."""
60+
61+ email : str
62+
63+
64+ @dataclass
65+ class Members :
66+ """The members of a user group."""
67+
68+ members : List [Member ]
69+
70+
5771class UserGroupV2 :
5872 """Upload members to a user group."""
5973
@@ -109,7 +123,7 @@ def upload_members(
109123 "text/csv" ,
110124 )
111125 }
112- query = """mutation ImportMembersToGroup (
126+ query = """mutation ImportMembersToGroupPyPi (
113127 $roleId: ID!
114128 $file: Upload!
115129 $where: WhereUniqueIdInput!
@@ -183,6 +197,43 @@ def upload_members(
183197 csv_report = file_data ["importUsersAsCsvToGroup" ]["csvReport" ]
184198 return self ._parse_csv_report (csv_report )
185199
200+ def export_members (self , group_id : str ) -> Optional [List [Member ]]:
201+ warnings .warn (
202+ "The upload_members for UserGroupV2 is in beta. The method name and signature may change in the future.”" ,
203+ )
204+
205+ query = """query GetExportMembersAsCSVPyPi(
206+ $id: ID!
207+ ) {
208+ userGroupV2(where: { id: $id }) {
209+ id
210+ membersAsCSV
211+ }
212+ }
213+ """
214+ params = {
215+ "id" : group_id ,
216+ }
217+
218+ result = self .client .execute (query , params )
219+ if result ["userGroupV2" ] is None :
220+ raise ResourceNotFoundError (message = "The user group is not found." )
221+ data = result ["userGroupV2" ]
222+
223+ # Parse CSV string into list of members
224+ csv_lines = data ["membersAsCSV" ].strip ().split ("\n " )
225+ members_list = []
226+
227+ # Skip header row
228+ for email in csv_lines [1 :]:
229+ members_list .append (
230+ Member (
231+ email = email .strip (),
232+ )
233+ )
234+
235+ return members_list
236+
186237 def _get_role_id (self , role_name : str ) -> Optional [str ]:
187238 role_id = None
188239 query = """query GetAvailableUserRolesPyPi {
0 commit comments