1616import re
1717import typing
1818import warnings
19+ from enum import Enum
20+ from typing import Optional , Type , Union
1921
2022from .common import (
2123 ClientError ,
3941)
4042from .client_pull import pull_project_async , pull_project_wait , pull_project_finalize
4143from .client_push import push_project_async , push_project_wait , push_project_finalize
42- from .utils import DateTimeEncoder , get_versions_with_file_changes , int_version , is_version_acceptable
44+ from .utils import (
45+ DateTimeEncoder ,
46+ get_versions_with_file_changes ,
47+ int_version ,
48+ is_version_acceptable ,
49+ normalize_role ,
50+ )
4351from .version import __version__
4452
4553this_dir = os .path .dirname (os .path .realpath (__file__ ))
@@ -1313,7 +1321,7 @@ def create_user(
13131321 email : str ,
13141322 password : str ,
13151323 workspace_id : int ,
1316- workspace_role : WorkspaceRole ,
1324+ workspace_role : Union [ str , WorkspaceRole ] ,
13171325 username : str = None ,
13181326 notify_user : bool = False ,
13191327 ) -> dict :
@@ -1328,11 +1336,15 @@ def create_user(
13281336 param notify_user: flag for email notifications - confirmation email will be sent
13291337 """
13301338 self .check_collaborators_members_support ()
1339+ role_enum = normalize_role (workspace_role , WorkspaceRole )
1340+ if role_enum is None :
1341+ raise ValueError (f"Invalid role: { workspace_role } " )
1342+
13311343 params = {
13321344 "email" : email ,
13331345 "password" : password ,
13341346 "workspace_id" : workspace_id ,
1335- "role" : workspace_role .value ,
1347+ "role" : role_enum .value ,
13361348 "notify_user" : notify_user ,
13371349 }
13381350 if username :
@@ -1357,17 +1369,26 @@ def list_workspace_members(self, workspace_id: int) -> typing.List[dict]:
13571369 return json .load (resp )
13581370
13591371 def update_workspace_member (
1360- self , workspace_id : int , user_id : int , workspace_role : WorkspaceRole , reset_projects_roles : bool = False
1372+ self ,
1373+ workspace_id : int ,
1374+ user_id : int ,
1375+ workspace_role : Union [str , WorkspaceRole ],
1376+ reset_projects_roles : bool = False ,
13611377 ) -> dict :
13621378 """
13631379 Update workspace role of a workspace member, optionally resets the projects role
13641380
13651381 param reset_projects_roles: all project specific roles will be removed
13661382 """
13671383 self .check_collaborators_members_support ()
1384+
1385+ role_enum = normalize_role (workspace_role , WorkspaceRole )
1386+ if role_enum is None :
1387+ raise ValueError (f"Invalid role: { workspace_role } " )
1388+
13681389 params = {
13691390 "reset_projects_roles" : reset_projects_roles ,
1370- "workspace_role" : workspace_role .value ,
1391+ "workspace_role" : role_enum .value ,
13711392 }
13721393 workspace_member = self .patch (f"v2/workspaces/{ workspace_id } /members/{ user_id } " , params , json_headers )
13731394 return json .load (workspace_member )
@@ -1387,25 +1408,35 @@ def list_project_collaborators(self, project_id: str) -> typing.List[dict]:
13871408 project_collaborators = self .get (f"v2/projects/{ project_id } /collaborators" )
13881409 return json .load (project_collaborators )
13891410
1390- def add_project_collaborator (self , project_id : str , user : str , project_role : ProjectRole ) -> dict :
1411+ def add_project_collaborator (self , project_id : str , user : str , project_role : Union [ str , ProjectRole ] ) -> dict :
13911412 """
13921413 Add a user to project collaborators and grant them a project role.
13931414 Fails if user is already a member of the project.
13941415
13951416 param user: login (username or email) of the user
13961417 """
13971418 self .check_collaborators_members_support ()
1419+
1420+ role_enum = normalize_role (project_role , ProjectRole )
1421+ if role_enum is None :
1422+ raise ValueError (f"Invalid role: { project_role } " )
1423+
13981424 params = {"role" : project_role .value , "user" : user }
13991425 project_collaborator = self .post (f"v2/projects/{ project_id } /collaborators" , params , json_headers )
14001426 return json .load (project_collaborator )
14011427
1402- def update_project_collaborator (self , project_id : str , user_id : int , project_role : ProjectRole ) -> dict :
1428+ def update_project_collaborator (self , project_id : str , user_id : int , project_role : Union [ str , ProjectRole ] ) -> dict :
14031429 """
14041430 Update project role of the existing project collaborator.
14051431 Fails if user is not a member of the project yet.
14061432 """
14071433 self .check_collaborators_members_support ()
1434+
1435+ role_enum = normalize_role (project_role , ProjectRole )
1436+ if role_enum is None :
1437+ raise ValueError (f"Invalid role: { project_role } " )
14081438 params = {"role" : project_role .value }
1439+
14091440 project_collaborator = self .patch (f"v2/projects/{ project_id } /collaborators/{ user_id } " , params , json_headers )
14101441 return json .load (project_collaborator )
14111442
@@ -1481,13 +1512,18 @@ def send_logs(
14811512 request = urllib .request .Request (url , data = payload , headers = header )
14821513 return self ._do_request (request )
14831514
1484- def create_invitation (self , workspace_id : int , email : str , workspace_role : WorkspaceRole ):
1515+ def create_invitation (self , workspace_id : int , email : str , workspace_role : Union [ str , WorkspaceRole ] ):
14851516 """
14861517 Create invitation to workspace for specific role
14871518 """
14881519 min_version = "2025.6.1"
14891520 if not is_version_acceptable (self .server_version (), min_version ):
14901521 raise NotImplementedError (f"This needs server at version { min_version } or later" )
1491- params = {"email" : email , "role" : workspace_role .value }
1522+
1523+ role_enum = normalize_role (workspace_role , WorkspaceRole )
1524+ if role_enum is None :
1525+ raise ValueError (f"Invalid role: { workspace_role } " )
1526+
1527+ params = {"email" : email , "role" : role_enum .value }
14921528 ws_inv = self .post (f"v2/workspaces/{ workspace_id } /invitations" , params , json_headers )
14931529 return json .load (ws_inv )
0 commit comments