@@ -111,17 +111,14 @@ class UserGroup(BaseModel):
111
111
"""Represents a user group in Labelbox.
112
112
113
113
UserGroups allow organizing users and projects together for access control
114
- and collaboration. This implementation provides enhanced validation and
115
- member management capabilities.
114
+ and collaboration. Each user is added with an explicit role via UserGroupMember.
116
115
117
116
Attributes:
118
117
id: Unique identifier for the user group.
119
118
name: Display name of the user group.
120
119
color: Visual color identifier for the group.
121
120
description: Optional description of the group's purpose.
122
121
notify_members: Whether to notify members of group changes.
123
- default_role: Default role assigned to users added via the legacy users field.
124
- users: Legacy set of users (maintained for backward compatibility).
125
122
members: Set of UserGroupMember objects with explicit roles.
126
123
projects: Set of projects associated with this group.
127
124
client: Labelbox client instance for API communication.
@@ -136,8 +133,6 @@ class UserGroup(BaseModel):
136
133
color : UserGroupColor
137
134
description : str = ""
138
135
notify_members : bool = False
139
- default_role : Optional [Role ] = None
140
- users : Set [User ] = Field (default_factory = set )
141
136
members : Set [UserGroupMember ] = Field (default_factory = set )
142
137
projects : Set [Project ] = Field (default_factory = set )
143
138
client : Client
@@ -151,8 +146,6 @@ def __init__(
151
146
color : UserGroupColor = UserGroupColor .BLUE ,
152
147
description : str = "" ,
153
148
notify_members : bool = False ,
154
- default_role : Optional [Role ] = None ,
155
- users : Optional [Set [User ]] = None ,
156
149
members : Optional [Set [UserGroupMember ]] = None ,
157
150
projects : Optional [Set [Project ]] = None ,
158
151
) -> None :
@@ -165,8 +158,6 @@ def __init__(
165
158
color: Visual color identifier.
166
159
description: Optional description.
167
160
notify_members: Whether to notify members of changes.
168
- default_role: Default role for users added via legacy users field.
169
- users: Legacy set of users for backward compatibility.
170
161
members: Set of members with explicit roles.
171
162
projects: Set of associated projects.
172
163
"""
@@ -177,38 +168,10 @@ def __init__(
177
168
color = color ,
178
169
description = description ,
179
170
notify_members = notify_members ,
180
- default_role = default_role ,
181
- users = users or set (),
182
171
members = members or set (),
183
172
projects = projects or set (),
184
173
)
185
174
186
- def model_post_init (self , __context : Any ) -> None :
187
- """Validate that default_role is set when users field is used.
188
-
189
- Args:
190
- __context: Pydantic context (unused).
191
-
192
- Raises:
193
- ValueError: If users is set but default_role is not provided, or if default_role is invalid.
194
- """
195
- # Validate that default_role is set when legacy users field is used
196
- if self .users and self .default_role is None :
197
- raise ValueError (
198
- "default_role must be set when using the 'users' field."
199
- )
200
-
201
- # Validate that default_role is not an invalid role for UserGroups
202
- if self .default_role and hasattr (self .default_role , "name" ):
203
- role_name = (
204
- self .default_role .name .upper () if self .default_role .name else ""
205
- )
206
- if role_name in INVALID_USERGROUP_ROLES :
207
- raise ValueError (
208
- f"default_role cannot be '{ role_name } '. "
209
- f"UserGroup members cannot have '{ role_name } ' roles."
210
- )
211
-
212
175
def get (self ) -> UserGroup :
213
176
"""Reload the user group information from the server.
214
177
@@ -283,12 +246,6 @@ def update(self) -> UserGroup:
283
246
f"Project { project .uid } not found or inaccessible"
284
247
)
285
248
286
- # Validate default_role is set when legacy users field is used
287
- if self .users and self .default_role is None :
288
- raise ValueError (
289
- "default_role must be set when using the 'users' field."
290
- )
291
-
292
249
# Filter eligible users and build user roles
293
250
eligible_users = self ._filter_project_based_users ()
294
251
user_roles = self ._build_user_roles (eligible_users )
@@ -372,19 +329,12 @@ def create(self) -> UserGroup:
372
329
f"Project { project .uid } not found or inaccessible"
373
330
)
374
331
375
- # Validate default_role is set when legacy users field is used
376
- if self .users and self .default_role is None :
377
- raise ValueError (
378
- "default_role must be explicitly set when using the 'users' field. "
379
- "This ensures you are aware of what role will be assigned to legacy users."
380
- )
381
-
382
332
# Filter eligible users and build user roles
383
333
eligible_users = self ._filter_project_based_users ()
384
334
user_roles = self ._build_user_roles (eligible_users )
385
335
386
336
query = """
387
- mutation CreateUserGroupPyApi($name: String!, $description: String, $color: String!, $projectIds: [ID!], $userRoles: [UserRoleInput!], $notifyMembers: Boolean, $roleId: String, $searchQuery: AlignerrSearchServiceQuery) {
337
+ mutation CreateUserGroupPyApi($name: String!, $description: String, $color: String!, $projectIds: [ID!]! , $userRoles: [UserRoleInput!]! , $notifyMembers: Boolean, $roleId: String, $searchQuery: AlignerrSearchServiceQuery) {
388
338
createUserGroupV3(
389
339
data: {
390
340
name: $name
@@ -415,8 +365,6 @@ def create(self) -> UserGroup:
415
365
"projectIds" : [project .uid for project in self .projects ],
416
366
"userRoles" : user_roles ,
417
367
"notifyMembers" : self .notify_members ,
418
- "roleId" : None ,
419
- "searchQuery" : None ,
420
368
}
421
369
422
370
try :
@@ -554,7 +502,7 @@ def _filter_project_based_users(self) -> Set[User]:
554
502
Returns:
555
503
Set of users that are eligible to be added to the group.
556
504
"""
557
- all_users = set (self . users )
505
+ all_users = set ()
558
506
for member in self .members :
559
507
all_users .add (member .user )
560
508
@@ -632,13 +580,6 @@ def _build_user_roles(
632
580
"""
633
581
user_roles : List [Dict [str , str ]] = []
634
582
635
- # Add legacy users with default role
636
- for user in self .users :
637
- if user in eligible_users and self .default_role is not None :
638
- user_roles .append (
639
- {"userId" : user .uid , "roleId" : self .default_role .uid }
640
- )
641
-
642
583
# Add members with their explicit roles
643
584
for member in self .members :
644
585
if member .user in eligible_users :
@@ -662,7 +603,6 @@ def _update_from_response(self, group_data: Dict[str, Any]) -> None:
662
603
# notifyMembers field is not available in GraphQL response, so we keep the current value
663
604
self .projects = self ._get_projects_set (group_data ["projects" ]["nodes" ])
664
605
self .members = self ._get_members_set (group_data ["members" ])
665
- self .users = set () # Clear legacy users
666
606
667
607
def _handle_user_validation_error (
668
608
self , error : Exception , operation : str
@@ -764,8 +704,5 @@ def _get_members_set(
764
704
role = Role (self .client , role_values )
765
705
766
706
members .add (UserGroupMember (user = user , role = role ))
767
- elif self .default_role :
768
- # Fallback to default role if no role mapping found
769
- members .add (UserGroupMember (user = user , role = self .default_role ))
770
707
771
708
return members
0 commit comments