|
3 | 3 | import subprocess |
4 | 4 | import sys |
5 | 5 | from pathlib import Path |
6 | | -from typing import Union, Dict, List, Optional, Literal |
| 6 | +from typing import Union, Dict, List, Optional, Literal, Any |
7 | 7 |
|
8 | 8 | import mmif |
9 | 9 | import pydantic |
@@ -101,11 +101,33 @@ class Output(_BaseModel): |
101 | 101 | "and also can be used as a expansion specification for the type definition beyond the base " |
102 | 102 | "vocabulary." |
103 | 103 | ) |
104 | | - properties: Dict[str, real_valued_primitives] = pydantic.Field( |
105 | | - {}, |
106 | | - description="(optional) Specification for type properties, if any. ``\"*\"`` indicates any value." |
| 104 | + # TODO (krim @ 5/12/21): currently there's no way to validate the property |
| 105 | + # types based on vocabulary specification of an annotation type. As a result, |
| 106 | + # we allow "any" type and do some basic validation below, but we need a |
| 107 | + # better way for validation. |
| 108 | + properties: Dict[str, Any] = pydantic.Field( |
| 109 | + {}, |
| 110 | + description="(optional) Specification for type properties, if any. `*` indicates any value." |
107 | 111 | ) |
108 | 112 |
|
| 113 | + @pydantic.field_validator('properties', mode='before') |
| 114 | + @classmethod |
| 115 | + def validate_properties(cls, value): |
| 116 | + if not isinstance(value, dict): |
| 117 | + raise ValueError("Properties must be a dictionary.") |
| 118 | + for key, val in value.items(): |
| 119 | + if not isinstance(key, str): |
| 120 | + raise ValueError(f"Property key '{key}' must be a string.") |
| 121 | + if isinstance(val, list): |
| 122 | + if not all(isinstance(item, type(val[0])) for item in val): |
| 123 | + raise ValueError(f"All elements in the list for key '{key}' must be of the same type.") |
| 124 | + elif isinstance(val, dict): |
| 125 | + if not all(isinstance(k, str) for k in val.keys()): |
| 126 | + raise ValueError(f"All keys in the dictionary for key '{key}' must be strings.") |
| 127 | + if not all(isinstance(v, type(next(iter(val.values())))) for v in val.values()): |
| 128 | + raise ValueError(f"All values in the dictionary for key '{key}' must be of the same type.") |
| 129 | + return value |
| 130 | + |
109 | 131 | def __init__(self, **kwargs): |
110 | 132 | super().__init__(**kwargs) |
111 | 133 |
|
|
0 commit comments