@@ -101,7 +101,7 @@ def is_one_of(self, values: List[str]) -> Dict[str, Any]:
101101 Args:
102102 values: List of IDs to match
103103 """
104- return {self ._field_name : values , "__operator" : "is" }
104+ return {self ._field_name : values }
105105
106106 def is_not_one_of (self , values : List [str ]) -> Dict [str , Any ]:
107107 """Filter for items that are NOT one of the specified values.
@@ -111,6 +111,17 @@ def is_not_one_of(self, values: List[str]) -> Dict[str, Any]:
111111 """
112112 return {self ._field_name : values , "__operator" : "is_not" }
113113
114+ def has_any_of (self , values : List [str ]) -> Dict [str , Any ]:
115+ """Filter for items that have any of the specified values.
116+
117+ This is semantically equivalent to is_one_of but provides clearer intent
118+ for certain filter types like categories or annotations.
119+
120+ Args:
121+ values: List of IDs to match
122+ """
123+ return {self ._field_name : values }
124+
114125
115126class RangeField :
116127 """Field class for range-based filters like consensus_average."""
@@ -171,30 +182,12 @@ def __call__(
171182batch = ListField ("Batch" )
172183consensus_average = RangeField ("ConsensusAverage" )
173184feature_consensus_average = FeatureRangeField ("FeatureConsensusAverage" )
174- # Note: dataset is a function, not a field object
175-
176-
177- # Function versions for filter functions
178- def dataset (
179- dataset_ids : List [str ], label : Optional [str ] = None
180- ) -> Dict [str , Any ]:
181- """Filter by dataset IDs.
182185
183- Args:
184- dataset_ids: List of dataset IDs to filter by
185- label: Optional custom label to display in the UI instead of the default "DS-0" format
186-
187- Returns:
188- Dict representing the filter rule
189-
190- Examples:
191- dataset(["dataset-123", "dataset-456"])
192- dataset(["dataset-123"], label="My Custom Dataset")
193- """
194- result : Dict [str , Any ] = {"Dataset" : dataset_ids }
195- if label is not None :
196- result ["__label" ] = label
197- return result
186+ # List-based filter field instances
187+ labeled_by = ListField ("CreatedBy" ) # Maps to backend CreatedBy field
188+ dataset = ListField ("Dataset" )
189+ issue_category = ListField ("IssueCategory" )
190+ annotation = ListField ("Annotation" )
198191
199192
200193class MetadataCondition :
@@ -302,68 +295,6 @@ def metadata(
302295 return result
303296
304297
305- def labeled_by (
306- user_ids : List [str ], label : Optional [str ] = None
307- ) -> Dict [str , Any ]:
308- """Filter by users who labeled the data.
309-
310- Args:
311- user_ids: List of user IDs
312- label: Optional custom label to display in the UI
313-
314- Returns:
315- Dict representing the filter rule
316- """
317- result : Dict [str , Any ] = {"CreatedBy" : user_ids }
318- if label is not None :
319- result ["__label" ] = label
320- return result
321-
322-
323- def created_by (
324- user_ids : List [str ], label : Optional [str ] = None
325- ) -> Dict [str , Any ]:
326- """Filter by users who created the labels.
327-
328- .. deprecated:: 2.1.0
329- Use `labeled_by()` instead. This function will be removed in a future version.
330-
331- Args:
332- user_ids: List of user IDs
333- label: Optional custom label to display in the UI
334-
335- Returns:
336- Dict representing the filter rule
337- """
338- import warnings
339-
340- warnings .warn (
341- "created_by() is deprecated and will be removed in a future version. "
342- "Use labeled_by() instead." ,
343- DeprecationWarning ,
344- stacklevel = 2 ,
345- )
346- return labeled_by (user_ids , label )
347-
348-
349- def annotation (
350- schema_node_ids : List [str ], label : Optional [str ] = None
351- ) -> Dict [str , Any ]:
352- """Filter by annotation schema node IDs.
353-
354- Args:
355- schema_node_ids: List of annotation schema node IDs
356- label: Optional custom label to display in the UI
357-
358- Returns:
359- Dict representing the filter rule
360- """
361- result : Dict [str , Any ] = {"Annotation" : schema_node_ids }
362- if label is not None :
363- result ["__label" ] = label
364- return result
365-
366-
367298def sample (percentage : int , label : Optional [str ] = None ) -> Dict [str , Any ]:
368299 """Filter by random sample percentage.
369300
@@ -391,24 +322,6 @@ def sample(percentage: int, label: Optional[str] = None) -> Dict[str, Any]:
391322 return result
392323
393324
394- def issue_category (
395- category_ids : List [str ], label : Optional [str ] = None
396- ) -> Dict [str , Any ]:
397- """Filter by issue category IDs.
398-
399- Args:
400- category_ids: List of issue category IDs
401- label: Optional custom label to display in the UI
402-
403- Returns:
404- Dict representing the filter rule
405- """
406- result : Dict [str , Any ] = {"IssueCategory" : category_ids }
407- if label is not None :
408- result ["__label" ] = label
409- return result
410-
411-
412325def model_prediction (
413326 conditions : List [Dict [str , Any ]], label : Optional [str ] = None
414327) -> Dict [str , Any ]:
@@ -576,14 +489,17 @@ def convert_to_api_format(filter_rule: Dict[str, Any]) -> Dict[str, Any]:
576489
577490class ProjectWorkflowFilter (BaseModel ):
578491 """
579- Project workflow filter collection that enforces filter function syntax.
492+ Project workflow filter collection that enforces filter syntax.
580493
581- Only accepts filters created using filter functions in this module.
494+ Only accepts filters created using filter field objects and functions in this module.
582495 This ensures type safety, IDE support, and eliminates manual string construction errors.
583496
584497 Example Usage:
585498 filters = ProjectWorkflowFilter([
586- labeled_by(["user-123"]),
499+ labeled_by.is_one_of(["user-123"]),
500+ dataset.is_one_of(["dataset-456"]),
501+ issue_category.has_any_of(["cat1", "cat2"]),
502+ annotation.has_any_of(["bbox", "segmentation"]),
587503 sample(20),
588504 labeled_at.between("2024-01-01", "2024-12-31"),
589505 metadata([condition.contains("tag", "test")]),
@@ -594,7 +510,7 @@ class ProjectWorkflowFilter(BaseModel):
594510 logic.set_filters(filters)
595511
596512 # Or add individual filters
597- logic.add_filter(labeled_by(["user-123"]))
513+ logic.add_filter(labeled_by.is_one_of (["user-123"]))
598514 """
599515
600516 rules : List [Dict [str , Any ]] = Field (default_factory = lambda : [])
0 commit comments