diff --git a/src/label_studio_sdk/label_interface/control_tags.py b/src/label_studio_sdk/label_interface/control_tags.py index 330e9df..442d213 100644 --- a/src/label_studio_sdk/label_interface/control_tags.py +++ b/src/label_studio_sdk/label_interface/control_tags.py @@ -344,10 +344,11 @@ def _resolve_to_name(self, to_name: Optional[str] = None) -> str: return to_name else: - if len(self.to_name) > 1: - raise Exception( - "Multiple to_name in control tag, specify to_name in function" - ) + # TODO: "Pairwise" tag has multiple to_name + # if len(self.to_name) > 1: + # raise Exception( + # "Multiple to_name in control tag, specify to_name in function" + # ) return self.to_name[0] @@ -494,6 +495,10 @@ class ChoicesTag(ControlTag): _label_attr_name: str = "choices" _value_class: Type[ChoicesValue] = ChoicesValue + @property + def is_multiple_choice(self): + return self.attr.get("choice") == "multiple" + def to_json_schema(self): """ Converts the current ChoicesTag instance into a JSON Schema. @@ -501,6 +506,17 @@ def to_json_schema(self): Returns: dict: A dictionary representing the JSON Schema compatible with OpenAPI 3. """ + if self.is_multiple_choice: + return { + "type": "array", + "items": { + "type": "string", + "enum": self.labels, + }, + "uniqueItems": True, + "description": f"Choices for {self.to_name[0]}", + } + return { "type": "string", "enum": self.labels, @@ -813,9 +829,10 @@ class PairwiseTag(ControlTag): _value_class: Type[PairwiseValue] = PairwiseValue _label_attr_name: str = "selected" - def label(self, side): + def label(self, label): """ """ - value = PairwiseValue(selected=side) + value = PairwiseValue(selected=label) + # tag has equal from_name and to_name, and string label that's not a list of strings return Region(from_tag=self, to_tag=self, value=value) def to_json_schema(self): diff --git a/tests/custom/test_interface/test_json_schema.py b/tests/custom/test_interface/test_json_schema.py index b11e214..46896be 100644 --- a/tests/custom/test_interface/test_json_schema.py +++ b/tests/custom/test_interface/test_json_schema.py @@ -34,6 +34,36 @@ {"sentiment": "Positive"}, {"sentiment": "Positive"} ), + # multiple choice + ( + """ + + + + + + + + + """, + { + "type": "object", + "properties": { + "sentiment": { + "description": "Choices for doc", + "type": "array", + "items": { + "type": "string", + "enum": ["Positive", "Negative", "Neutral"] + }, + "uniqueItems": True, + } + }, + "required": ["sentiment"] + }, + {"sentiment": ["Positive", "Negative"]}, + {"sentiment": ["Positive", "Negative"]} + ), # ner ( """ @@ -188,6 +218,7 @@ # ... ], ids=[ "simple_choices", + "multiple_choices", "ner", "classification_with_textarea", "complex_interface"