22
33import itertools
44import logging
5+ import warnings
56from typing import TYPE_CHECKING , Optional
67
78from kili .adapters .kili_api_gateway .helpers .queries import QueryOptions
@@ -22,9 +23,13 @@ class ProjectCopier: # pylint: disable=too-few-public-methods
2223 "description" ,
2324 "id" ,
2425 "dataConnections.id" ,
26+ "inputType" ,
27+ "jsonInterface" ,
28+ "workflowVersion" ,
2529 )
2630
2731 def __init__ (self , kili : "Kili" ) -> None :
32+ """Simple initialization."""
2833 self .disable_tqdm = False
2934 self .kili = kili
3035
@@ -72,7 +77,7 @@ def copy_project( # pylint: disable=too-many-arguments
7277 ),
7378 )
7479
75- logger .info (f "Created new project { new_project_id } " )
80+ logger .info ("Created new project %s" , new_project_id )
7681
7782 self .kili .update_properties_in_project (
7883 project_id = new_project_id ,
@@ -84,7 +89,18 @@ def copy_project( # pylint: disable=too-many-arguments
8489
8590 if copy_labels :
8691 logger .info ("Copying labels..." )
87- self ._copy_labels (from_project_id , new_project_id )
92+ if src_project ["workflowVersion" ] == "V2" :
93+ self ._copy_labels (from_project_id = from_project_id , new_project_id = new_project_id )
94+ else :
95+ warnings .warn (
96+ "Warning: "
97+ "copying a project of an old workflow mode may cause problems in asset status and assignation. "
98+ "Consider creating a new project instead." ,
99+ DeprecationWarning ,
100+ )
101+ self ._copy_labels_legacy (
102+ from_project_id = from_project_id , new_project_id = new_project_id
103+ )
88104
89105 return new_project_id
90106
@@ -100,8 +116,58 @@ def _generate_project_title(self, src_title: str) -> str:
100116 i += 1
101117 return new_title
102118
103- # pylint: disable=too-many-locals
104119 def _copy_labels (self , from_project_id : str , new_project_id : str ) -> None :
120+ """Method to copy labels from the source project to the new project : applicable for WFV2."""
121+ nb_labels_to_copy = self .kili .kili_api_gateway .count_labels (
122+ LabelFilters (project_id = ProjectId (from_project_id ))
123+ )
124+
125+ if nb_labels_to_copy == 0 :
126+ return
127+
128+ assets_src_project = self .kili .kili_api_gateway .list_assets (
129+ AssetFilters (project_id = ProjectId (from_project_id )),
130+ ["id" , "externalId" , "labels.id" ],
131+ QueryOptions (disable_tqdm = True ),
132+ )
133+
134+ assets_dst_project = self .kili .kili_api_gateway .list_assets (
135+ AssetFilters (project_id = ProjectId (new_project_id )),
136+ ["id" , "externalId" ],
137+ QueryOptions (disable_tqdm = True ),
138+ )
139+
140+ # Iterate on assets of the source project
141+ # to copy labels to the new projectq
142+ assets_src_project_list = [
143+ asset
144+ for asset in assets_src_project
145+ if "labels" in asset and asset ["labels" ] and len (asset ["labels" ]) > 0
146+ ]
147+ assets_dst_project_map = {asset ["externalId" ]: asset ["id" ] for asset in assets_dst_project }
148+
149+ for src_asset in assets_src_project_list :
150+ src_asset_id = src_asset ["id" ]
151+ dst_asset_id = assets_dst_project_map .get (src_asset ["externalId" ])
152+ if not dst_asset_id :
153+ raise ValueError (
154+ f"Asset with externalId { src_asset ['externalId' ]} not found in new project { new_project_id } ."
155+ )
156+
157+ self .kili .kili_api_gateway .copy_labels (
158+ src_asset_id = src_asset_id ,
159+ dst_asset_id = dst_asset_id ,
160+ project_id = new_project_id ,
161+ )
162+
163+ # pylint: disable=too-many-locals
164+ def _copy_labels_legacy (self , from_project_id : str , new_project_id : str ) -> None :
165+ """Legacy mlethod to copy labels from the source project to the new project : applicable for WFV1.
166+
167+ !!! warning
168+ This method is deprecated and will be removed in the next major release.
169+ Asset with send back labels are not supported (status wise) and asset assignation is not supported.
170+ """
105171 assets_new_project = self .kili .kili_api_gateway .list_assets (
106172 AssetFilters (project_id = ProjectId (new_project_id )),
107173 ["id" , "externalId" ],
0 commit comments