22
33from collections .abc import Generator
44
5- from kili_formats .tool .annotations_to_json_response import (
6- AnnotationsToJsonResponseConverter ,
7- )
8-
95from kili .adapters .kili_api_gateway .asset .formatters import (
106 load_asset_json_fields ,
117)
128from kili .adapters .kili_api_gateway .asset .mappers import asset_where_mapper
139from kili .adapters .kili_api_gateway .asset .operations import (
14- GQL_COUNT_ASSET_ANNOTATIONS ,
1510 GQL_COUNT_ASSETS ,
1611 GQL_CREATE_UPLOAD_BUCKET_SIGNED_URLS ,
1712 GQL_FILTER_EXISTING_ASSETS ,
2318 QueryOptions ,
2419 fragment_builder ,
2520)
26- from kili .adapters .kili_api_gateway .label .common import get_annotation_fragment
2721from kili .adapters .kili_api_gateway .project .common import get_project
2822from kili .core .graphql .operations .asset .mutations import GQL_SET_ASSET_CONSENSUS
2923from kili .domain .asset import AssetFilters
3024from kili .domain .types import ListOrTuple
3125
32- # Threshold for batching based on number of annotations
33- # This is used to determine whether to use a single batch or multiple batches
34- # when fetching assets. If the number of annotations counted exceeds this threshold,
35- # the asset fetch will be done in multiple smaller batches to avoid performance issues.
36- THRESHOLD_FOR_BATCHING = 200
37-
3826
3927class AssetOperationMixin (BaseOperationMixin ):
4028 """Mixin extending Kili API Gateway class with Assets related operations."""
@@ -46,9 +34,6 @@ def list_assets(
4634 options : QueryOptions ,
4735 ) -> Generator [dict , None , None ]:
4836 """List assets with given options."""
49- has_labels_url = "labels.jsonResponseUrl" in fields
50- has_latest_label_url = "latestLabel.jsonResponseUrl" in fields
51-
5237 if "labels.jsonResponse" in fields or "latestLabel.jsonResponse" in fields :
5338 # Check if we can get the jsonResponse of if we need to rebuild it.
5439 project_info = get_project (
@@ -61,10 +46,7 @@ def list_assets(
6146 "LLM_STATIC" ,
6247 "GEOSPATIAL" ,
6348 }:
64- fetch_annotations = not (has_labels_url or has_latest_label_url )
65- yield from self .list_assets_split (
66- filters , fields , options , project_info , fetch_annotations
67- )
49+ yield from self .list_assets_split (filters , fields , options , project_info )
6850 return
6951
7052 fragment = fragment_builder (fields )
@@ -90,35 +72,24 @@ def list_assets_split(
9072 fields : ListOrTuple [str ],
9173 options : QueryOptions ,
9274 project_info ,
93- fetch_annotations : bool ,
9475 ) -> Generator [dict , None , None ]:
9576 """List assets with given options."""
96- nb_annotations = self .count_assets_annotations (filters )
9777 assets_batch_max_amount = 10 if project_info ["inputType" ] == "VIDEO" else 50
9878 batch_size_to_use = min (options .batch_size , assets_batch_max_amount )
99- batch_size = (
100- 1 if nb_annotations / batch_size_to_use > THRESHOLD_FOR_BATCHING else batch_size_to_use
101- )
10279
103- options = QueryOptions (options .disable_tqdm , options .first , options .skip , batch_size )
104-
105- static_fragments = {}
106- if fetch_annotations :
107- inner_annotation_fragment = get_annotation_fragment ()
108- annotation_fragment = f"""
109- annotations {{
110- { inner_annotation_fragment }
111- }}
112- """
113- static_fragments = {"labels" : annotation_fragment , "latestLabel" : annotation_fragment }
114-
115- required_fields = {"content" , "jsonContent" , "resolution.width" , "resolution.height" }
116- fields = list (fields )
117- for field in required_fields :
118- if field not in fields :
119- fields .append (field )
120-
121- fragment = fragment_builder (fields , static_fragments if static_fragments else None )
80+ options = QueryOptions (options .disable_tqdm , options .first , options .skip , batch_size_to_use )
81+
82+ required_fields = {"content" , "jsonContent" , "resolution.width" , "resolution.height" }
83+ if "labels.jsonResponse" in fields :
84+ required_fields .add ("labels.jsonResponseUrl" )
85+ if "latestLabel.jsonResponse" in fields :
86+ required_fields .add ("latestLabel.jsonResponseUrl" )
87+ fields = list (fields )
88+ for field in required_fields :
89+ if field not in fields :
90+ fields .append (field )
91+
92+ fragment = fragment_builder (fields )
12293 query = get_assets_query (fragment )
12394 where = asset_where_mapper (filters )
12495 assets_gen = PaginatedGraphQLQuery (self .graphql_client ).execute_query_from_paginated_call (
@@ -128,28 +99,7 @@ def list_assets_split(
12899 load_asset_json_fields (asset , fields , self .http_client ) for asset in assets_gen
129100 )
130101
131- if fetch_annotations :
132- converter = AnnotationsToJsonResponseConverter (
133- json_interface = project_info ["jsonInterface" ],
134- project_input_type = project_info ["inputType" ],
135- )
136- is_requesting_annotations = any ("annotations." in element for element in fields )
137- for asset in assets_gen :
138- if "latestLabel.jsonResponse" in fields and asset .get ("latestLabel" ):
139- converter .patch_label_json_response (
140- asset , asset ["latestLabel" ], asset ["latestLabel" ]["annotations" ]
141- )
142- if not is_requesting_annotations :
143- asset ["latestLabel" ].pop ("annotations" )
144-
145- if "labels.jsonResponse" in fields :
146- for label in asset .get ("labels" , []):
147- converter .patch_label_json_response (asset , label , label ["annotations" ])
148- if not is_requesting_annotations :
149- label .pop ("annotations" )
150- yield asset
151- else :
152- yield from assets_gen
102+ yield from assets_gen
153103
154104 def count_assets (self , filters : AssetFilters ) -> int :
155105 """Send a GraphQL request calling countIssues resolver."""
@@ -176,14 +126,6 @@ def filter_existing_assets(self, project_id: str, assets_external_ids: ListOrTup
176126 external_id_response = self .graphql_client .execute (GQL_FILTER_EXISTING_ASSETS , payload )
177127 return external_id_response ["external_ids" ]
178128
179- def count_assets_annotations (self , filters : AssetFilters ) -> int :
180- """Count the number of annotations for assets matching the filters."""
181- where = asset_where_mapper (filters )
182- payload = {"where" : where }
183- count_result = self .graphql_client .execute (GQL_COUNT_ASSET_ANNOTATIONS , payload )
184- count : int = count_result ["data" ]
185- return count
186-
187129 def update_asset_consensus (
188130 self ,
189131 project_id : str ,
0 commit comments