@@ -81,41 +81,6 @@ class Collections(TypedDict, total=False):
8181 numberReturned : Optional [int ] = None
8282
8383
84- class PartialCollection (TypedDict , total = False ):
85- """Partial STAC Collection."""
86-
87- type : Optional [str ]
88- stac_version : Optional [str ]
89- stac_extensions : Optional [List [str ]]
90- id : Optional [str ]
91- title : Optional [str ]
92- description : Optional [str ]
93- links : List [Dict [str , Any ]]
94- keywords : Optional [List [str ]]
95- license : Optional [str ]
96- providers : Optional [List [Dict [str , Any ]]]
97- extent : Optional [Dict [str , Any ]]
98- summaries : Optional [Dict [str , Any ]]
99- assets : Optional [Dict [str , Any ]]
100- numberMatched : Optional [int ] = None
101- numberReturned : Optional [int ] = None
102-
103-
104- class PartialItem (TypedDict , total = False ):
105- """Partial STAC Item."""
106-
107- type : Optional [Literal ["Feature" ]]
108- stac_version : Optional [str ]
109- stac_extensions : Optional [List [str ]]
110- id : Optional [str ]
111- geometry : Optional [Dict [str , Any ]]
112- bbox : Optional [BBox ]
113- properties : Optional [Dict [str , Any ]]
114- links : Optional [List [Dict [str , Any ]]]
115- assets : Optional [Dict [str , Any ]]
116- collection : Optional [str ]
117-
118-
11984class PatchAddReplaceTest (StacBaseModel ):
12085 """Add, Replace or Test Operation."""
12186
@@ -188,3 +153,78 @@ class PatchMoveCopy(StacBaseModel):
188153
189154
190155PatchOperation = Union [PatchAddReplaceTest , PatchMoveCopy , PatchRemove ]
156+
157+
158+ class BasePartial (StacBaseModel ):
159+ """Base Partial Class."""
160+
161+ @staticmethod
162+ def merge_to_operations (data : Dict ) -> List [PatchOperation ]:
163+ """Convert merge operation to list of RF6902 operations.
164+
165+ Args:
166+ data: dictionary to convert.
167+
168+ Returns:
169+ List: list of RF6902 operations.
170+ """
171+ operations = []
172+
173+ for key , value in data .copy ().items ():
174+ if value is None :
175+ operations .append (PatchRemove (op = "remove" , path = key ))
176+
177+ elif isinstance (value , dict ):
178+ nested_operations = BasePartial .merge_to_operations (value )
179+
180+ for nested_operation in nested_operations :
181+ nested_operation .path = f"{ key } /{ nested_operation .path } "
182+ operations .append (nested_operation )
183+
184+ else :
185+ operations .append (PatchAddReplaceTest (op = "add" , path = key , value = value ))
186+
187+ return operations
188+
189+ def operations (self ) -> List [PatchOperation ]:
190+ """Equivalent RF6902 operations to merge of Partial.
191+
192+ Returns:
193+ List[PatchOperation]: Equivalent list of RF6902 operations
194+ """
195+ return self .merge_to_operations (self .model_dump ())
196+
197+
198+ class PartialCollection (BasePartial ):
199+ """Partial STAC Collection."""
200+
201+ type : Optional [str ]
202+ stac_version : Optional [str ]
203+ stac_extensions : Optional [List [str ]]
204+ id : Optional [str ]
205+ title : Optional [str ]
206+ description : Optional [str ]
207+ links : List [Dict [str , Any ]]
208+ keywords : Optional [List [str ]]
209+ license : Optional [str ]
210+ providers : Optional [List [Dict [str , Any ]]]
211+ extent : Optional [Dict [str , Any ]]
212+ summaries : Optional [Dict [str , Any ]]
213+ assets : Optional [Dict [str , Any ]]
214+ numberMatched : Optional [int ] = None
215+ numberReturned : Optional [int ] = None
216+
217+
218+ class PartialItem (BasePartial ):
219+ """Partial STAC Item."""
220+
221+ type : Optional [Literal ["Feature" ]]
222+ stac_version : Optional [str ]
223+ stac_extensions : Optional [List [str ]]
224+ id : Optional [str ]
225+ geometry : Optional [Dict [str , Any ]]
226+ bbox : Optional [BBox ]
227+ properties : Optional [Dict [str , Any ]]
228+ links : Optional [List [Dict [str , Any ]]]
229+ assets : Optional [Dict [str , Any ]]
230+ collection : Optional [str ]
0 commit comments