3232 resolve_disable_tqdm ,
3333)
3434from kili .presentation .client .helpers .filter_conversion import (
35+ extract_step_id_and_status_filters_from_project_steps ,
3536 extract_step_ids_from_project_steps ,
3637)
3738from kili .use_cases .asset import AssetUseCases
@@ -157,6 +158,8 @@ def assets(
157158 label_output_format : Literal ["dict" , "parsed_label" ] = "dict" ,
158159 skipped : Optional [bool ] = None ,
159160 status_in : Optional [list [AssetStatus ]] = None ,
161+ step_name_and_status_in : Optional [list [tuple [str , StatusInStep ]]] = None ,
162+ step_name_and_status_not_in : Optional [list [tuple [str , StatusInStep ]]] = None ,
160163 step_name_in : Optional [list [str ]] = None ,
161164 step_name_not_in : Optional [list [str ]] = None ,
162165 step_status_in : Optional [list [StatusInStep ]] = None ,
@@ -225,6 +228,8 @@ def assets(
225228 label_output_format : Literal ["dict" , "parsed_label" ] = "dict" ,
226229 skipped : Optional [bool ] = None ,
227230 status_in : Optional [list [AssetStatus ]] = None ,
231+ step_name_and_status_in : Optional [list [tuple [str , StatusInStep ]]] = None ,
232+ step_name_and_status_not_in : Optional [list [tuple [str , StatusInStep ]]] = None ,
228233 step_name_in : Optional [list [str ]] = None ,
229234 step_name_not_in : Optional [list [str ]] = None ,
230235 step_status_in : Optional [list [StatusInStep ]] = None ,
@@ -293,6 +298,8 @@ def assets(
293298 label_output_format : Literal ["dict" , "parsed_label" ] = "dict" ,
294299 skipped : Optional [bool ] = None ,
295300 status_in : Optional [list [AssetStatus ]] = None ,
301+ step_name_and_status_in : Optional [list [tuple [str , StatusInStep ]]] = None ,
302+ step_name_and_status_not_in : Optional [list [tuple [str , StatusInStep ]]] = None ,
296303 step_name_in : Optional [list [str ]] = None ,
297304 step_name_not_in : Optional [list [str ]] = None ,
298305 step_status_in : Optional [list [StatusInStep ]] = None ,
@@ -366,6 +373,10 @@ def assets(
366373 status_in: Returned assets should have a status that belongs to that list, if given.
367374 Possible choices: `TODO`, `ONGOING`, `LABELED`, `TO_REVIEW` or `REVIEWED`.
368375 Only applicable if the project is in the WorkflowV1 (legacy).
376+ step_name_and_status_in: Returned assets match at least one of the given (step_name, step_status) pairs.
377+ Only applicable if the project is in WorkflowV2.
378+ step_name_and_status_not_in: Returned assets do not match any of the given (step_name, step_status) pairs.
379+ Only applicable if the project is in WorkflowV2.
369380 step_name_in: Returned assets are in the step whose name belong to that list, if given.
370381 Only applicable if the project is in WorkflowV2.
371382 step_name_not_in: Returned assets are in the step whose name does not belong to that list, if given.
@@ -468,16 +479,21 @@ def assets(
468479 stacklevel = 1 ,
469480 )
470481
482+ step_id_and_status_in : Optional [list [tuple [str , StatusInStep ]]] = None
483+ step_id_and_status_not_in : Optional [list [tuple [str , StatusInStep ]]] = None
471484 step_id_in = None
472485 step_id_not_in = None
473- has_step_filters = step_name_in is not None or step_name_not_in is not None
474- has_status_filters = (
475- step_status_in is not None
486+ has_step_or_status_filters = (
487+ step_name_in is not None
488+ or step_name_not_in is not None
489+ or step_name_and_status_in is not None
490+ or step_name_and_status_not_in is not None
491+ or step_status_in is not None
476492 or step_status_not_in is not None
477493 or status_in is not None
478494 or skipped is not None
479495 )
480- if has_step_filters or has_status_filters :
496+ if has_step_or_status_filters :
481497 check_asset_workflow_arguments (
482498 project_workflow_version = project_workflow_version ,
483499 asset_workflow_filters = {
@@ -487,6 +503,8 @@ def assets(
487503 "step_name_not_in" : step_name_not_in ,
488504 "step_status_in" : step_status_in ,
489505 "step_status_not_in" : step_status_not_in ,
506+ "step_name_and_status_in" : step_name_and_status_in ,
507+ "step_name_and_status_not_in" : step_name_and_status_not_in ,
490508 },
491509 )
492510 if project_workflow_version == "V2" and step_name_in is not None :
@@ -499,6 +517,16 @@ def assets(
499517 project_steps = project_steps ,
500518 step_name_in = step_name_not_in ,
501519 )
520+ if project_workflow_version == "V2" and step_name_and_status_in is not None :
521+ step_id_and_status_in = extract_step_id_and_status_filters_from_project_steps (
522+ project_steps = project_steps ,
523+ step_name_and_status_filters = step_name_and_status_in ,
524+ )
525+ if project_workflow_version == "V2" and step_name_and_status_not_in is not None :
526+ step_id_and_status_not_in = extract_step_id_and_status_filters_from_project_steps (
527+ project_steps = project_steps ,
528+ step_name_and_status_filters = step_name_and_status_not_in ,
529+ )
502530
503531 # Resolve disable_tqdm: function parameter > client global setting > function default
504532 disable_tqdm = resolve_disable_tqdm (disable_tqdm , getattr (self , "disable_tqdm" , None ))
@@ -550,6 +578,8 @@ def assets(
550578 step_id_not_in = step_id_not_in ,
551579 step_status_in = step_status_in ,
552580 step_status_not_in = step_status_not_in ,
581+ step_id_and_status_in = step_id_and_status_in ,
582+ step_id_and_status_not_in = step_id_and_status_not_in ,
553583 )
554584 assets_gen = asset_use_cases .list_assets (
555585 filters ,
@@ -625,6 +655,8 @@ def count_assets(
625655 step_name_not_in : Optional [list [str ]] = None ,
626656 step_status_in : Optional [list [StatusInStep ]] = None ,
627657 step_status_not_in : Optional [list [StatusInStep ]] = None ,
658+ step_name_and_status_in : Optional [list [tuple [str , StatusInStep ]]] = None ,
659+ step_name_and_status_not_in : Optional [list [tuple [str , StatusInStep ]]] = None ,
628660 ) -> int :
629661 # pylint: disable=line-too-long
630662 """Count and return the number of assets with the given constraints.
@@ -691,6 +723,10 @@ def count_assets(
691723 step_status_not_in: Returned assets have the status of their step that does not belong to that list, if given.
692724 Possible choices: `TO_DO`, `DOING`, `PARTIALLY_DONE`, `REDO`, `DONE`, `SKIPPED`.
693725 Only applicable if the project is in WorkflowV2.
726+ step_name_and_status_in: Returned assets match at least one of the given (step_name, step_status) pairs.
727+ Only applicable if the project is in WorkflowV2.
728+ step_name_and_status_not_in: Returned assets do not match any of the given (step_name, step_status) pairs.
729+ Only applicable if the project is in WorkflowV2.
694730
695731 !!! info "Dates format"
696732 Date strings should have format: "YYYY-MM-DD"
@@ -734,11 +770,18 @@ def count_assets(
734770
735771 step_id_in = None
736772 step_id_not_in = None
737- has_step_filters = step_name_in is not None or step_name_not_in is not None
738- has_status_filters = (
739- status_in is not None or step_status_in is not None or step_status_not_in is not None
773+ step_id_and_status_in : Optional [list [tuple [str , StatusInStep ]]] = None
774+ step_id_and_status_not_in : Optional [list [tuple [str , StatusInStep ]]] = None
775+ has_step_or_status_filters = (
776+ step_name_in is not None
777+ or step_name_not_in is not None
778+ or step_name_and_status_in is not None
779+ or step_name_and_status_not_in is not None
780+ or status_in is not None
781+ or step_status_in is not None
782+ or step_status_not_in is not None
740783 )
741- if has_step_filters or has_status_filters :
784+ if has_step_or_status_filters :
742785 project_use_cases = ProjectUseCases (self .kili_api_gateway )
743786 (
744787 project_steps ,
@@ -749,6 +792,8 @@ def count_assets(
749792 asset_workflow_filters = {
750793 "skipped" : skipped ,
751794 "step_name_in" : step_name_in ,
795+ "step_name_and_status_in" : step_name_and_status_in ,
796+ "step_name_and_status_not_in" : step_name_and_status_not_in ,
752797 "step_name_not_in" : step_name_not_in ,
753798 "step_status_in" : step_status_in ,
754799 "step_status_not_in" : step_status_not_in ,
@@ -766,6 +811,16 @@ def count_assets(
766811 project_steps = project_steps ,
767812 step_name_in = step_name_not_in ,
768813 )
814+ if project_workflow_version == "V2" and step_name_and_status_in is not None :
815+ step_id_and_status_in = extract_step_id_and_status_filters_from_project_steps (
816+ project_steps = project_steps ,
817+ step_name_and_status_filters = step_name_and_status_in ,
818+ )
819+ if project_workflow_version == "V2" and step_name_and_status_not_in is not None :
820+ step_id_and_status_not_in = extract_step_id_and_status_filters_from_project_steps (
821+ project_steps = project_steps ,
822+ step_name_and_status_filters = step_name_and_status_not_in ,
823+ )
769824
770825 filters = AssetFilters (
771826 project_id = ProjectId (project_id ),
@@ -809,6 +864,8 @@ def count_assets(
809864 created_at_lte = created_at_lte ,
810865 issue_status = issue_status ,
811866 issue_type = issue_type ,
867+ step_id_and_status_in = step_id_and_status_in ,
868+ step_id_and_status_not_in = step_id_and_status_not_in ,
812869 step_id_in = step_id_in ,
813870 step_id_not_in = step_id_not_in ,
814871 step_status_in = step_status_in ,
0 commit comments