88from kili .domain .asset .asset import AssetStatus , StatusInStep
99from kili .domain .issue import IssueStatus , IssueType
1010from kili .domain .label import LabelType
11+ from kili .domain .project import ProjectId
1112from kili .domain .types import ListOrTuple
1213from kili .domain_api .base import DomainNamespace
1314from kili .domain_api .namespace_utils import get_available_methods
@@ -63,6 +64,70 @@ def __init__(self, client, gateway):
6364 super ().__init__ (client , gateway , "exports" )
6465 self .raw = self .kili
6566
67+ def _get_workflow_version (self , project_id : str ) -> Optional [str ]:
68+ """Get the workflow version for a project.
69+
70+ Args:
71+ project_id: The project identifier
72+
73+ Returns:
74+ The workflow version ("V1" or "V2") or None if project not found
75+ """
76+ project = self ._gateway .get_project (
77+ project_id = ProjectId (project_id ), fields = ["workflowVersion" ]
78+ )
79+
80+ if not project :
81+ return None
82+
83+ return project .get ("workflowVersion" )
84+
85+ def _get_optimal_export_type (self , workflow_version : Optional [str ]) -> ExportType :
86+ """Determine the optimal export type based on project workflow configuration.
87+
88+ For non-multi-review projects (Workflow V1), uses "latest"
89+ which queries the singular latestLabel field for better performance.
90+
91+ For multi-review projects (Workflow V2), uses "latest_from_last_step"
92+ which queries the plural latestLabels field to support multiple annotators.
93+
94+ Args:
95+ workflow_version: The workflow version ("V1", "V2", or None)
96+
97+ Returns:
98+ The optimal export type for this project
99+ """
100+ if workflow_version == "V2" :
101+ return "latest_from_last_step"
102+ return "latest"
103+
104+ def _validate_export_type_compatibility (
105+ self , workflow_version : Optional [str ], export_type : ExportType
106+ ) -> None :
107+ """Validate that the export type is compatible with the project workflow.
108+
109+ Workflow V1 projects cannot use export types that rely on multi-step workflows:
110+ - latest_from_last_step: Uses latestLabels field (V2 multi-review feature)
111+ - latest_from_all_steps: Uses labels with isLastForStep (V2 multi-step feature)
112+
113+ Args:
114+ workflow_version: The workflow version ("V1", "V2", or None)
115+ export_type: The requested export type
116+
117+ Raises:
118+ ValueError: If the export type is incompatible with the project workflow version
119+ """
120+ if export_type not in ("latest_from_last_step" , "latest_from_all_steps" ):
121+ return
122+
123+ if workflow_version == "V1" :
124+ raise ValueError (
125+ f"Export type '{ export_type } ' is not compatible with Workflow V1 projects. "
126+ f"Workflow V1 projects should use export_type='latest' or 'normal'. "
127+ f"The '{ export_type } ' export type is designed for Workflow V2 projects "
128+ f"with multi-step workflows."
129+ )
130+
66131 @deprecated (
67132 "'exports' is a namespace, not a callable method. "
68133 "Use kili.exports.kili() or other available methods instead."
@@ -93,7 +158,7 @@ def kili(
93158 include_sent_back_labels : Optional [bool ] = None ,
94159 label_type_in : Optional [list [LabelType ]] = None ,
95160 single_file : Optional [bool ] = False ,
96- export_type : ExportType = "latest_from_last_step" ,
161+ export_type : Optional [ ExportType ] = None ,
97162 ):
98163 """Export project labels in Kili native format.
99164
@@ -114,14 +179,17 @@ def kili(
114179 whose type belongs to that list.
115180 By default, only `DEFAULT` and `REVIEW` labels are exported.
116181 single_file: If True, all labels are exported in a single JSON file.
117- export_type: Type of export. Options are:
182+ export_type: Type of export. If not specified, automatically selects the optimal type:
183+ - For Workflow V1 projects: uses `"latest"` (single label per asset)
184+ - For Workflow V2 projects: uses `"latest_from_last_step"` (supports multiple annotators)
185+
186+ Available options:
118187 - `"latest_from_last_step"`: exports the latest labels from the last workflow step
119188 (uses `latestLabels` field, supports multiple annotators).
120189 - `"latest_from_all_steps"`: exports latest labels from all workflow steps
121190 - `"latest"`: exports the latest label for each asset
122191 (deprecated, use `"latest_from_last_step"` instead).
123192 - `"normal"`: exports all labels for each asset.
124- Defaults to `"latest_from_last_step"`.
125193
126194 Returns:
127195 Export information or None if export failed.
@@ -151,7 +219,7 @@ def coco(
151219 include_sent_back_labels : Optional [bool ] = None ,
152220 label_type_in : Optional [list [LabelType ]] = None ,
153221 layout : SplitOption = "split" ,
154- export_type : ExportType = "latest_from_last_step" ,
222+ export_type : Optional [ ExportType ] = None ,
155223 ):
156224 """Export project labels in COCO format.
157225
@@ -175,14 +243,17 @@ def coco(
175243 By default, only `DEFAULT` and `REVIEW` labels are exported.
176244 layout: Layout of the exported files. "split" means there is one folder
177245 per job, "merged" that there is one folder with every labels.
178- export_type: Type of export. Options are:
246+ export_type: Type of export. If not specified, automatically selects the optimal type:
247+ - For Workflow V1 projects: uses `"latest"` (single label per asset)
248+ - For Workflow V2 projects: uses `"latest_from_last_step"` (supports multiple annotators)
249+
250+ Available options:
179251 - `"latest_from_last_step"`: exports the latest labels from the last workflow step
180252 (uses `latestLabels` field, supports multiple annotators).
181253 - `"latest_from_all_steps"`: exports latest labels from all workflow steps
182254 - `"latest"`: exports the latest label for each asset
183255 (deprecated, use `"latest_from_last_step"` instead).
184256 - `"normal"`: exports all labels for each asset.
185- Defaults to `"latest_from_last_step"`.
186257
187258 Returns:
188259 Export information or None if export failed.
@@ -211,7 +282,7 @@ def yolo_v4(
211282 filter : Optional [ExportAssetFilter ] = None ,
212283 include_sent_back_labels : Optional [bool ] = None ,
213284 label_type_in : Optional [list [LabelType ]] = None ,
214- export_type : ExportType = "latest_from_last_step" ,
285+ export_type : Optional [ ExportType ] = None ,
215286 ):
216287 """Export project labels in YOLO v4 format.
217288
@@ -234,14 +305,17 @@ def yolo_v4(
234305 By default, only `DEFAULT` and `REVIEW` labels are exported.
235306 include_sent_back_labels: If True, the export will include the labels that
236307 have been sent back.
237- export_type: Type of export. Options are:
308+ export_type: Type of export. If not specified, automatically selects the optimal type:
309+ - For Workflow V1 projects: uses `"latest"` (single label per asset)
310+ - For Workflow V2 projects: uses `"latest_from_last_step"` (supports multiple annotators)
311+
312+ Available options:
238313 - `"latest_from_last_step"`: exports the latest labels from the last workflow step
239314 (uses `latestLabels` field, supports multiple annotators).
240315 - `"latest_from_all_steps"`: exports latest labels from all workflow steps
241316 - `"latest"`: exports the latest label for each asset
242317 (deprecated, use `"latest_from_last_step"` instead).
243318 - `"normal"`: exports all labels for each asset.
244- Defaults to `"latest_from_last_step"`.
245319
246320 Returns:
247321 Export information or None if export failed.
@@ -269,7 +343,7 @@ def yolo_v5(
269343 filter : Optional [ExportAssetFilter ] = None ,
270344 include_sent_back_labels : Optional [bool ] = None ,
271345 label_type_in : Optional [list [LabelType ]] = None ,
272- export_type : ExportType = "latest_from_last_step" ,
346+ export_type : Optional [ ExportType ] = None ,
273347 ):
274348 """Export project labels in YOLO v5 format.
275349
@@ -292,14 +366,17 @@ def yolo_v5(
292366 By default, only `DEFAULT` and `REVIEW` labels are exported.
293367 include_sent_back_labels: If True, the export will include the labels that
294368 have been sent back.
295- export_type: Type of export. Options are:
369+ export_type: Type of export. If not specified, automatically selects the optimal type:
370+ - For Workflow V1 projects: uses `"latest"` (single label per asset)
371+ - For Workflow V2 projects: uses `"latest_from_last_step"` (supports multiple annotators)
372+
373+ Available options:
296374 - `"latest_from_last_step"`: exports the latest labels from the last workflow step
297375 (uses `latestLabels` field, supports multiple annotators).
298376 - `"latest_from_all_steps"`: exports latest labels from all workflow steps
299377 - `"latest"`: exports the latest label for each asset
300378 (deprecated, use `"latest_from_last_step"` instead).
301379 - `"normal"`: exports all labels for each asset.
302- Defaults to `"latest_from_last_step"`.
303380
304381 Returns:
305382 Export information or None if export failed.
@@ -327,7 +404,7 @@ def yolo_v7(
327404 filter : Optional [ExportAssetFilter ] = None ,
328405 include_sent_back_labels : Optional [bool ] = None ,
329406 label_type_in : Optional [list [LabelType ]] = None ,
330- export_type : ExportType = "latest_from_last_step" ,
407+ export_type : Optional [ ExportType ] = None ,
331408 ):
332409 """Export project labels in YOLO v7 format.
333410
@@ -350,14 +427,17 @@ def yolo_v7(
350427 By default, only `DEFAULT` and `REVIEW` labels are exported.
351428 include_sent_back_labels: If True, the export will include the labels that
352429 have been sent back.
353- export_type: Type of export. Options are:
430+ export_type: Type of export. If not specified, automatically selects the optimal type:
431+ - For Workflow V1 projects: uses `"latest"` (single label per asset)
432+ - For Workflow V2 projects: uses `"latest_from_last_step"` (supports multiple annotators)
433+
434+ Available options:
354435 - `"latest_from_last_step"`: exports the latest labels from the last workflow step
355436 (uses `latestLabels` field, supports multiple annotators).
356437 - `"latest_from_all_steps"`: exports latest labels from all workflow steps
357438 - `"latest"`: exports the latest label for each asset
358439 (deprecated, use `"latest_from_last_step"` instead).
359440 - `"normal"`: exports all labels for each asset.
360- Defaults to `"latest_from_last_step"`.
361441
362442 Returns:
363443 Export information or None if export failed.
@@ -385,7 +465,7 @@ def yolo_v8(
385465 filter : Optional [ExportAssetFilter ] = None ,
386466 include_sent_back_labels : Optional [bool ] = None ,
387467 label_type_in : Optional [list [LabelType ]] = None ,
388- export_type : ExportType = "latest_from_last_step" ,
468+ export_type : Optional [ ExportType ] = None ,
389469 ):
390470 """Export project labels in YOLO v8 format.
391471
@@ -408,14 +488,17 @@ def yolo_v8(
408488 By default, only `DEFAULT` and `REVIEW` labels are exported.
409489 include_sent_back_labels: If True, the export will include the labels that
410490 have been sent back.
411- export_type: Type of export. Options are:
491+ export_type: Type of export. If not specified, automatically selects the optimal type:
492+ - For Workflow V1 projects: uses `"latest"` (single label per asset)
493+ - For Workflow V2 projects: uses `"latest_from_last_step"` (supports multiple annotators)
494+
495+ Available options:
412496 - `"latest_from_last_step"`: exports the latest labels from the last workflow step
413497 (uses `latestLabels` field, supports multiple annotators).
414498 - `"latest_from_all_steps"`: exports latest labels from all workflow steps
415499 - `"latest"`: exports the latest label for each asset
416500 (deprecated, use `"latest_from_last_step"` instead).
417501 - `"normal"`: exports all labels for each asset.
418- Defaults to `"latest_from_last_step"`.
419502
420503 Returns:
421504 Export information or None if export failed.
@@ -442,7 +525,7 @@ def pascal_voc(
442525 filter : Optional [ExportAssetFilter ] = None ,
443526 include_sent_back_labels : Optional [bool ] = None ,
444527 label_type_in : Optional [list [LabelType ]] = None ,
445- export_type : ExportType = "latest_from_last_step" ,
528+ export_type : Optional [ ExportType ] = None ,
446529 ):
447530 """Export project labels in Pascal VOC format.
448531
@@ -463,14 +546,17 @@ def pascal_voc(
463546 By default, only `DEFAULT` and `REVIEW` labels are exported.
464547 include_sent_back_labels: If True, the export will include the labels that
465548 have been sent back.
466- export_type: Type of export. Options are:
549+ export_type: Type of export. If not specified, automatically selects the optimal type:
550+ - For Workflow V1 projects: uses `"latest"` (single label per asset)
551+ - For Workflow V2 projects: uses `"latest_from_last_step"` (supports multiple annotators)
552+
553+ Available options:
467554 - `"latest_from_last_step"`: exports the latest labels from the last workflow step
468555 (uses `latestLabels` field, supports multiple annotators).
469556 - `"latest_from_all_steps"`: exports latest labels from all workflow steps
470557 - `"latest"`: exports the latest label for each asset
471558 (deprecated, use `"latest_from_last_step"` instead).
472559 - `"normal"`: exports all labels for each asset.
473- Defaults to `"latest_from_last_step"`.
474560
475561 Returns:
476562 Export information or None if export failed.
@@ -497,7 +583,7 @@ def geojson(
497583 filter : Optional [ExportAssetFilter ] = None ,
498584 include_sent_back_labels : Optional [bool ] = None ,
499585 label_type_in : Optional [list [LabelType ]] = None ,
500- export_type : ExportType = "latest_from_last_step" ,
586+ export_type : Optional [ ExportType ] = None ,
501587 ):
502588 """Export project labels in GeoJSON format.
503589
@@ -518,14 +604,17 @@ def geojson(
518604 By default, only `DEFAULT` and `REVIEW` labels are exported.
519605 include_sent_back_labels: If True, the export will include the labels that
520606 have been sent back.
521- export_type: Type of export. Options are:
607+ export_type: Type of export. If not specified, automatically selects the optimal type:
608+ - For Workflow V1 projects: uses `"latest"` (single label per asset)
609+ - For Workflow V2 projects: uses `"latest_from_last_step"` (supports multiple annotators)
610+
611+ Available options:
522612 - `"latest_from_last_step"`: exports the latest labels from the last workflow step
523613 (uses `latestLabels` field, supports multiple annotators).
524614 - `"latest_from_all_steps"`: exports latest labels from all workflow steps
525615 - `"latest"`: exports the latest label for each asset
526616 (deprecated, use `"latest_from_last_step"` instead).
527617 - `"normal"`: exports all labels for each asset.
528- Defaults to `"latest_from_last_step"`.
529618
530619 Returns:
531620 Export information or None if export failed.
@@ -610,7 +699,7 @@ def _export(
610699 project_id : str ,
611700 single_file : bool = False ,
612701 with_assets : Optional [bool ] = True ,
613- export_type : ExportType = "latest_from_last_step" ,
702+ export_type : Optional [ ExportType ] = None ,
614703 ) -> Optional [list [dict [str , Union [list [str ], str ]]]]:
615704 """Export the project labels with the requested format into the requested output path.
616705
@@ -657,6 +746,13 @@ def _export(
657746 ... filter={"external_id_contains": ["batch_1"]}
658747 ... )
659748 """
749+ workflow_version = self ._get_workflow_version (project_id )
750+
751+ if export_type is None :
752+ export_type = self ._get_optimal_export_type (workflow_version )
753+ else :
754+ self ._validate_export_type_compatibility (workflow_version , export_type )
755+
660756 asset_filter_kwargs = dict (filter ) if filter else {}
661757 return self ._client .export_labels (
662758 project_id = project_id ,
0 commit comments