1414 Union ,
1515)
1616
17- from pydantic import AliasChoices , BaseModel , ConfigDict , Field , TypeAdapter
17+ from pydantic import (
18+ AliasChoices ,
19+ BaseModel ,
20+ ConfigDict ,
21+ Field ,
22+ TypeAdapter ,
23+ model_validator ,
24+ )
1825
1926logger = logging .getLogger (__name__ )
2027
@@ -59,6 +66,29 @@ def folder_identifier(self) -> str:
5966 return self .folder_path
6067
6168
69+ class EntityResourceOverwrite (ResourceOverwrite ):
70+ resource_type : Literal ["entity" ]
71+ name : str = Field (alias = "name" )
72+ folder_id : Optional [str ] = Field (default = None , alias = "folderId" )
73+ folder_path : Optional [str ] = Field (default = None , alias = "folderPath" )
74+
75+ @model_validator (mode = "after" )
76+ def validate_folder_identifier (self ) -> "EntityResourceOverwrite" :
77+ if self .folder_id and self .folder_path :
78+ raise ValueError ("Only one of folderId or folderPath may be provided." )
79+ if not self .folder_id and not self .folder_path :
80+ raise ValueError ("Either folderId or folderPath must be provided." )
81+ return self
82+
83+ @property
84+ def resource_identifier (self ) -> str :
85+ return self .name
86+
87+ @property
88+ def folder_identifier (self ) -> str :
89+ return self .folder_id or self .folder_path or ""
90+
91+
6292class ConnectionResourceOverwrite (ResourceOverwrite ):
6393 resource_type : Literal ["connection" ]
6494 # In eval context, studio web provides "ConnectionId".
@@ -83,7 +113,9 @@ def folder_identifier(self) -> str:
83113
84114
85115ResourceOverwriteUnion = Annotated [
86- Union [GenericResourceOverwrite , ConnectionResourceOverwrite ],
116+ Union [
117+ GenericResourceOverwrite , EntityResourceOverwrite , ConnectionResourceOverwrite
118+ ],
87119 Field (discriminator = "resource_type" ),
88120]
89121
@@ -112,9 +144,23 @@ def parse(cls, key: str, value: dict[str, Any]) -> ResourceOverwrite:
112144 The appropriate ResourceOverwrite subclass instance
113145 """
114146 resource_type = key .split ("." )[0 ]
115- value_with_type = {"resource_type" : resource_type , ** value }
147+ normalized_value = cls ._normalize_value (resource_type , value )
148+ value_with_type = {"resource_type" : resource_type , ** normalized_value }
116149 return cls ._adapter .validate_python (value_with_type )
117150
151+ @staticmethod
152+ def _normalize_value (resource_type : str , value : dict [str , Any ]) -> dict [str , Any ]:
153+ if resource_type != "entity" :
154+ return value
155+
156+ normalized = dict (value )
157+ if "folderId" in normalized :
158+ normalized ["folder_id" ] = normalized .pop ("folderId" )
159+ if "folderPath" in normalized :
160+ normalized ["folder_path" ] = normalized .pop ("folderPath" )
161+
162+ return normalized
163+
118164
119165_resource_overwrites : ContextVar [Optional [dict [str , ResourceOverwrite ]]] = ContextVar (
120166 "resource_overwrites" , default = None
0 commit comments