@@ -159,6 +159,7 @@ def __init__(
159159
160160 self .method = method
161161 self .modifier = modifier
162+
162163 params = {
163164 "limit" : limit ,
164165 "bbox" : self ._format_bbox (bbox ),
@@ -167,8 +168,8 @@ def __init__(
167168 "collections" : self ._format_collections (collections ),
168169 "intersects" : self ._format_intersects (intersects ),
169170 "query" : self ._format_query (query ),
170- "filter" : self ._format_filter (filter ),
171- "filter-lang" : self ._format_filter_lang (filter , filter_lang ),
171+ "filter" : self ._format_filter (method , filter_lang , filter ),
172+ "filter-lang" : self ._format_filter_lang (method , filter , filter_lang ),
172173 "sortby" : self ._format_sortby (sortby ),
173174 "fields" : self ._format_fields (fields ),
174175 "q" : q ,
@@ -204,6 +205,8 @@ def _clean_params_for_get_request(self) -> dict[str, Any]:
204205 params ["sortby" ] = self ._sortby_dict_to_str (params ["sortby" ])
205206 if "fields" in params :
206207 params ["fields" ] = self ._fields_dict_to_str (params ["fields" ])
208+ if "filter" in params and isinstance (params ["filter" ], dict ):
209+ params ["filter" ] = json .dumps (params ["filter" ])
207210 return params
208211
209212 def url_with_parameters (self ) -> str :
@@ -266,29 +269,69 @@ def _format_query(self, value: QueryLike | None) -> dict[str, Any] | None:
266269
267270 @staticmethod
268271 def _format_filter_lang (
269- _filter : FilterLike | None , value : FilterLangLike | None
272+ method : str | None ,
273+ _filter : FilterLike | None ,
274+ value : FilterLangLike | None ,
270275 ) -> str | None :
271276 if _filter is None :
272277 return None
273278
274279 if value is not None :
275280 return value
276281
277- if isinstance ( _filter , str ) :
282+ if method == "GET" :
278283 return "cql2-text"
279284
280- if isinstance ( _filter , dict ) :
285+ if method == "POST" :
281286 return "cql2-json"
282287
283288 return None
284289
285- def _format_filter (self , value : FilterLike | None ) -> FilterLike | None :
286- if value is None :
290+ def _format_filter (
291+ self ,
292+ method : str | None ,
293+ filter_lang : FilterLangLike | None ,
294+ value : FilterLike | None ,
295+ ) -> FilterLike | None :
296+ if not value :
287297 return None
288298
289299 if self .client and not self .client .conforms_to (ConformanceClasses .FILTER ):
290300 warnings .warn (DoesNotConformTo ("FILTER" ))
291301
302+ if method == "GET" and isinstance (value , str ):
303+ return value
304+
305+ if method == "POST" and isinstance (value , dict ):
306+ return value
307+
308+ # if filter_lang is specified, do not coerce
309+ if filter_lang is not None :
310+ return value
311+
312+ try :
313+ import cql2
314+
315+ if isinstance (value , dict ):
316+ expr = cql2 .parse_json (json .dumps (value ))
317+ else :
318+ # could be cql2-text or stringified cql2-json
319+ expr = cql2 .Expr (value )
320+
321+ except ImportError as e :
322+ raise ValueError (
323+ "Unless you specify ``filter_lang`` pystac-client will try to convert "
324+ "the filter to cql2-text or cql2-json based on the HTTP method "
325+ "provided.\n "
326+ "Resolve this error by installing ``cql2``: ``pip install cql2``"
327+ ) from e
328+
329+ if method == "GET" :
330+ return str (expr .to_text ())
331+
332+ if method == "POST" :
333+ return dict (expr .to_json ())
334+
292335 return value
293336
294337 @staticmethod
0 commit comments