@@ -102,6 +102,65 @@ def data_type(self):
102102 def attached_datasets (self ):
103103 return self .__project_data .get ("attached_datasets" )
104104
105+ def status (self ) -> Dict :
106+ """
107+ Poll project status until completion or timeout.
108+
109+ Returns:
110+ Final project data with status information
111+
112+ Examples:
113+ # Get current project status
114+ final_status = project.status()
115+ """
116+ from .utils import poll
117+
118+ def get_project_status ():
119+ unique_id = str (uuid .uuid4 ())
120+ url = (
121+ f"{ constants .BASE_URL } /projects/project/{ self .project_id } ?client_id={ self .client .client_id } "
122+ f"&uuid={ unique_id } "
123+ )
124+
125+ response = self .client .make_request (
126+ "GET" ,
127+ url ,
128+ extra_headers = {"content-type" : "application/json" },
129+ request_id = unique_id ,
130+ )
131+ project_data = response .get ("response" , {})
132+ if project_data :
133+ self .__project_data = project_data
134+ return project_data
135+
136+ def is_completed (project_data ):
137+ status_code = project_data .get ("status_code" , 500 )
138+ # Consider project complete when status_code is 300 (success) or >= 400 (error/failed)
139+ return status_code == 300 or status_code >= 400
140+
141+ def on_success (project_data ):
142+ status_code = project_data .get ("status_code" , 500 )
143+ if status_code == 300 :
144+ logging .info (
145+ "Project %s processing completed successfully!" , self .project_id
146+ )
147+ else :
148+ logging .warning (
149+ "Project %s processing finished with status code: %s" ,
150+ self .project_id ,
151+ status_code ,
152+ )
153+ return project_data
154+
155+ return poll (
156+ function = get_project_status ,
157+ condition = is_completed ,
158+ interval = 2.0 ,
159+ timeout = None ,
160+ max_retries = None ,
161+ on_success = on_success ,
162+ )
163+
105164 def detach_dataset_from_project (self , dataset_id = None , dataset_ids = None ):
106165 """
107166 Detaches one or more datasets from an existing project.
@@ -568,3 +627,19 @@ def __fetch_exports_download_url(self, project_id, uuid, export_id, client_id):
568627 return response .get ("response" )
569628 except Exception as e :
570629 raise LabellerrError (f"Failed to download export: { str (e )} " )
630+
631+ def import_users (self , from_project : "LabellerrProject" ):
632+ """
633+ Imports users from a source project to the current project.
634+
635+ :param from_project: The source project to import users from
636+ :return: Dictionary containing import results
637+ :raises LabellerrError: If the import fails
638+ """
639+ # Validate parameters using Pydantic
640+ unique_id = str (uuid .uuid4 ())
641+ url = f"{ constants .BASE_URL } /users/projects/import_users?selected_project_id={ self .project_id } &project_id={ from_project .project_id } &client_id={ self .client .client_id } &uuid={ unique_id } "
642+ response = self .client .make_request (
643+ "POST" , url , extra_headers = {"Content-Type" : "application/json" }
644+ )
645+ return response .get ("response" )
0 commit comments