Skip to content

Commit cb7c21f

Browse files
committed
PyDF now being the default matcher.
1 parent 4b4c5d6 commit cb7c21f

File tree

9 files changed

+71
-33
lines changed

9 files changed

+71
-33
lines changed

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* Added client-side filtering to many of the standard API (wherever sensibly applicable); These APIs `select`
44
and `get_all` functions now feature optional `include` and `exclude` parameters which can be used to filter
55
the results before being wrapped into Python objects; Added multiple matchers including a JSONPath matcher
6-
and a JMESPath matcher.
6+
a JMESPath matcher and a PyDF (Python Display Filter) matcher with PyDF as default.
77
* Added `QueueListener` and `AsyncQueueListener` classes to the Notification 2.0 toolkit. These pre-defined
88
listener implementation append new notifications to standard queues that can be monitored/listened to which
99
makes Notification 2.0 solutions even simpler to implement.

c8y_api/model/_base.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
from c8y_api.model.matcher import JsonMatcher
1414
from c8y_api.model._util import _DateUtil, _StringUtil, _QueryUtil
1515
try:
16-
from c8y_api.model.matcher import JmesPathMatcher
16+
from c8y_api.model.matcher import PydfMatcher
1717
except ImportError:
1818
pass
1919

@@ -639,7 +639,7 @@ def __init__(self, c8y: CumulocityRestApi, resource: str):
639639
# the last event for e.g. /event/events
640640
self.object_name = self.resource.split('/')[-1]
641641
# the default JSON matcher for client-side filtering
642-
self.default_matcher = JmesPathMatcher
642+
self.default_matcher = PydfMatcher
643643

644644
def build_object_path(self, object_id: int | str) -> str:
645645
"""Build the path to a specific object of this resource.

c8y_api/model/administration.py

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -959,17 +959,20 @@ def select(
959959
limit (int): Limit the number of results to this number.
960960
include (str | JsonMatcher): Matcher/expression to filter the query
961961
results (on client side). The inclusion is applied first.
962-
Creates a JMESPath matcher by default for strings.
962+
Creates a PyDF (Python Display Filter) matcher by default for strings.
963963
exclude (str | JsonMatcher): Matcher/expression to filter the query
964964
results (on client side). The exclusion is applied second.
965-
Creates a JMESPath matcher by default for strings.
965+
Creates a PyDF (Python Display Filter) matcher by default for strings.
966966
page_size (int): Define the number of objects read (and parsed
967967
in one chunk). This is a performance related setting.
968968
page_number (int): Pull a specific page; this effectively disables
969969
automatic follow-up page retrieval.
970970
971971
Returns:
972972
Generator for InventoryRole objects
973+
974+
See also:
975+
https://github.com/bytebutcher/pydfql/blob/main/docs/USER_GUIDE.md#4-query-language
973976
"""
974977
base_query = self._prepare_query(page_size=page_size)
975978
return super()._iterate(base_query, page_number, limit, include, exclude, InventoryRole.from_json)
@@ -1116,10 +1119,10 @@ def select(
11161119
limit (int): Limit the number of results to this number.
11171120
include (str | JsonMatcher): Matcher/expression to filter the query
11181121
results (on client side). The inclusion is applied first.
1119-
Creates a JMESPath matcher by default for strings.
1122+
Creates a PyDF (Python Display Filter) matcher by default for strings.
11201123
exclude (str | JsonMatcher): Matcher/expression to filter the query
11211124
results (on client side). The exclusion is applied second.
1122-
Creates a JMESPath matcher by default for strings.
1125+
Creates a PyDF (Python Display Filter) matcher by default for strings.
11231126
page_size (int): Define the number of events which are read (and
11241127
parsed in one chunk). This is a performance related setting.
11251128
page_number (int): Pull a specific page; this effectively disables
@@ -1131,6 +1134,9 @@ def select(
11311134
11321135
Returns:
11331136
Generator of User instances
1137+
1138+
See also:
1139+
https://github.com/bytebutcher/pydfql/blob/main/docs/USER_GUIDE.md#4-query-language
11341140
"""
11351141
# group_list can be ints, strings (names) or Group objects
11361142
# it needs to become a comma-separated string
@@ -1337,15 +1343,18 @@ def select(
13371343
If omitted, all available global roles are returned
13381344
include (str | JsonMatcher): Matcher/expression to filter the query
13391345
results (on client side). The inclusion is applied first.
1340-
Creates a JMESPath matcher by default for strings.
1346+
Creates a PyDF (Python Display Filter) matcher by default for strings.
13411347
exclude (str | JsonMatcher): Matcher/expression to filter the query
13421348
results (on client side). The exclusion is applied second.
1343-
Creates a JMESPath matcher by default for strings.
1349+
Creates a PyDF (Python Display Filter) matcher by default for strings.
13441350
page_size (int): Maximum number of entries fetched per requests;
13451351
this is a performance setting
13461352
13471353
Return:
13481354
Generator of GlobalRole instances
1355+
1356+
See also:
1357+
https://github.com/bytebutcher/pydfql/blob/main/docs/USER_GUIDE.md#4-query-language
13491358
"""
13501359
# unfortunately, as selecting by username can't be implemented using the
13511360
# generic _iterate method, we have to do everything manually.
@@ -1400,15 +1409,18 @@ def get_all(
14001409
If omitted, all available global roles are returned
14011410
include (str | JsonMatcher): Matcher/expression to filter the query
14021411
results (on client side). The inclusion is applied first.
1403-
Creates a JMESPath matcher by default for strings.
1412+
Creates a PyDF (Python Display Filter) matcher by default for strings.
14041413
exclude (str | JsonMatcher): Matcher/expression to filter the query
14051414
results (on client side). The exclusion is applied second.
1406-
Creates a JMESPath matcher by default for strings.
1415+
Creates a PyDF (Python Display Filter) matcher by default for strings.
14071416
page_size (int): Maximum number of entries fetched per requests;
14081417
this is a performance setting
14091418
14101419
Return:
14111420
List of GlobalRole instances
1421+
1422+
See also:
1423+
https://github.com/bytebutcher/pydfql/blob/main/docs/USER_GUIDE.md#4-query-language
14121424
"""
14131425
return list(self.select(username=username, include=include, exclude=exclude, page_size=page_size))
14141426

c8y_api/model/alarms.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -307,10 +307,10 @@ def select(self,
307307
limit (int): Limit the number of results to this number.
308308
include (str | JsonMatcher): Matcher/expression to filter the query
309309
results (on client side). The inclusion is applied first.
310-
Creates a JMESPath matcher by default for strings.
310+
Creates a PyDF (Python Display Filter) matcher by default for strings.
311311
exclude (str | JsonMatcher): Matcher/expression to filter the query
312312
results (on client side). The exclusion is applied second.
313-
Creates a JMESPath matcher by default for strings.
313+
Creates a PyDF (Python Display Filter) matcher by default for strings.
314314
page_size (int): Define the number of alarms which are read (and
315315
parsed in one chunk). This is a performance related setting.
316316
page_number (int): Pull a specific page; this effectively disables
@@ -322,6 +322,9 @@ def select(self,
322322
323323
Returns:
324324
Generator of Alarm objects
325+
326+
See also:
327+
https://github.com/bytebutcher/pydfql/blob/main/docs/USER_GUIDE.md#4-query-language
325328
"""
326329
base_query = self._prepare_query(
327330
expression=expression,

c8y_api/model/audit.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -240,10 +240,10 @@ def select(
240240
limit (int): Limit the number of results to this number.
241241
include (str | JsonMatcher): Matcher/expression to filter the query
242242
results (on client side). The inclusion is applied first.
243-
Creates a JMESPath matcher by default for strings.
243+
Creates a PyDF (Python Display Filter) matcher by default for strings.
244244
exclude (str | JsonMatcher): Matcher/expression to filter the query
245245
results (on client side). The exclusion is applied second.
246-
Creates a JMESPath matcher by default for strings.
246+
Creates a PyDF (Python Display Filter) matcher by default for strings.
247247
page_size (int): Define the number of objects which are read (and
248248
parsed in one chunk). This is a performance related setting.
249249
page_number (int): Pull a specific page; this effectively disables
@@ -255,6 +255,9 @@ def select(
255255
256256
Returns:
257257
Generator for AuditRecord objects
258+
259+
See also:
260+
https://github.com/bytebutcher/pydfql/blob/main/docs/USER_GUIDE.md#4-query-language
258261
"""
259262
base_query = self._prepare_query(
260263
expression=expression,

c8y_api/model/events.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -330,10 +330,10 @@ def select(self,
330330
limit (int): Limit the number of results to this number.
331331
include (str | JsonMatcher): Matcher/expression to filter the query
332332
results (on client side). The inclusion is applied first.
333-
Creates a JMESPath matcher by default for strings.
333+
Creates a PyDF (Python Display Filter) matcher by default for strings.
334334
exclude (str | JsonMatcher): Matcher/expression to filter the query
335335
results (on client side). The exclusion is applied second.
336-
Creates a JMESPath matcher by default for strings.
336+
Creates a PyDF (Python Display Filter) matcher by default for strings.
337337
page_size (int): Define the number of events which are read (and
338338
parsed in one chunk). This is a performance related setting.
339339
page_number (int): Pull a specific page; this effectively disables
@@ -345,6 +345,9 @@ def select(self,
345345
346346
Returns:
347347
Generator for Event objects
348+
349+
See also:
350+
https://github.com/bytebutcher/pydfql/blob/main/docs/USER_GUIDE.md#4-query-language
348351
"""
349352
base_query = self._prepare_event_query(
350353
expression=expression,

c8y_api/model/inventory.py

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -298,10 +298,10 @@ def select(
298298
limit (int): Limit the number of results to this number.
299299
include (str | JsonMatcher): Matcher/expression to filter the query
300300
results (on client side). The inclusion is applied first.
301-
Creates a JMESPath matcher by default for strings.
301+
Creates a PyDF (Python Display Filter) matcher by default for strings.
302302
exclude (str | JsonMatcher): Matcher/expression to filter the query
303303
results (on client side). The exclusion is applied second.
304-
Creates a JMESPath matcher by default for strings.
304+
Creates a PyDF (Python Display Filter) matcher by default for strings.
305305
page_size (int): Define the number of events which are read (and
306306
parsed in one chunk). This is a performance related setting.
307307
page_number (int): Pull a specific page; this effectively disables
@@ -313,8 +313,10 @@ def select(
313313
314314
Returns:
315315
Generator for ManagedObject instances
316-
"""
317316
317+
See also:
318+
https://github.com/bytebutcher/pydfql/blob/main/docs/USER_GUIDE.md#4-query-language
319+
"""
318320
return self._select(
319321
ManagedObject.from_json,
320322
device_mode=False,
@@ -694,10 +696,10 @@ def select( # noqa (order)
694696
limit (int): Limit the number of results to this number.
695697
include (str | JsonMatcher): Matcher/expression to filter the query
696698
results (on client side). The inclusion is applied first.
697-
Creates a JMESPath matcher by default for strings.
699+
Creates a PyDF (Python Display Filter) matcher by default for strings.
698700
exclude (str | JsonMatcher): Matcher/expression to filter the query
699701
results (on client side). The exclusion is applied second.
700-
Creates a JMESPath matcher by default for strings.
702+
Creates a PyDF (Python Display Filter) matcher by default for strings.
701703
page_size (int): Define the number of events which are read (and
702704
parsed in one chunk). This is a performance related setting.
703705
page_number (int): Pull a specific page; this effectively disables
@@ -709,6 +711,9 @@ def select( # noqa (order)
709711
710712
Returns:
711713
Generator for Device objects
714+
715+
See also:
716+
https://github.com/bytebutcher/pydfql/blob/main/docs/USER_GUIDE.md#4-query-language
712717
"""
713718
return super()._select(
714719
Device.from_json,
@@ -962,10 +967,10 @@ def select( # noqa (changed signature)
962967
limit (int): Limit the number of results to this number.
963968
include (str | JsonMatcher): Matcher/expression to filter the query
964969
results (on client side). The inclusion is applied first.
965-
Creates a JMESPath matcher by default for strings.
970+
Creates a PyDF (Python Display Filter) matcher by default for strings.
966971
exclude (str | JsonMatcher): Matcher/expression to filter the query
967972
results (on client side). The exclusion is applied second.
968-
Creates a JMESPath matcher by default for strings.
973+
Creates a PyDF (Python Display Filter) matcher by default for strings.
969974
page_size (int): Define the number of events which are read (and
970975
parsed in one chunk). This is a performance related setting.
971976
page_number (int): Pull a specific page; this effectively disables
@@ -977,6 +982,9 @@ def select( # noqa (changed signature)
977982
978983
Returns:
979984
Generator of DeviceGroup instances
985+
986+
See also:
987+
https://github.com/bytebutcher/pydfql/blob/main/docs/USER_GUIDE.md#4-query-language
980988
"""
981989
type = type or (DeviceGroup.CHILD_TYPE if parent else None)
982990
if fragments:

c8y_api/model/operations.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -201,10 +201,10 @@ def select(
201201
limit (int): Limit the number of results to this number.
202202
include (str | JsonMatcher): Matcher/expression to filter the query
203203
results (on client side). The inclusion is applied first.
204-
Creates a JMESPath matcher by default for strings.
204+
Creates a PyDF (Python Display Filter) matcher by default for strings.
205205
exclude (str | JsonMatcher): Matcher/expression to filter the query
206206
results (on client side). The exclusion is applied second.
207-
Creates a JMESPath matcher by default for strings.
207+
Creates a PyDF (Python Display Filter) matcher by default for strings.
208208
page_size (int): Define the number of operations which are
209209
read (and parsed in one chunk). This is a performance
210210
related setting.
@@ -217,6 +217,9 @@ def select(
217217
218218
Returns:
219219
Generator[Operation]: Iterable of matching Operation objects
220+
221+
See also:
222+
https://github.com/bytebutcher/pydfql/blob/main/docs/USER_GUIDE.md#4-query-language
220223
"""
221224
base_query = self._prepare_query(
222225
expression=expression,

samples/client_side_filtering.py

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
from c8y_api.app import SimpleCumulocityApp
44
from c8y_api.model import Device
5-
from c8y_api.model.matcher import field, match_all, match_not
5+
from c8y_api.model.matcher import field, match_all, match_not, pydf
66
from util.testing_util import load_dotenv
77

88
logging.basicConfig(level=logging.DEBUG)
@@ -23,11 +23,16 @@
2323
Client-side filters are defined for the _raw_ JSON structure. Hence, when you
2424
want to use them you must be aware of Cumulocity's JSON data format.
2525
26+
By default, PyDF (Python Display Filter) expression can be specified directly
27+
as strings. See also
28+
https://github.com/bytebutcher/pydfql/blob/main/docs/USER_GUIDE.md#4-query-language
29+
for details.
30+
2631
Performance: Hi there, optimization kids! To put it bluntly - using this
2732
feature does most likely _not_ increase performance in any way. This is
2833
because the actual JSON parsing will happen in any case and this is the
2934
expensive part. So - all the illustrated methods below do only marginally
30-
differ in speeed.
35+
differ in speeed.
3136
"""
3237

3338
load_dotenv() # load environment from a .env if present
@@ -57,11 +62,11 @@
5762

5863
# Option 2: using the client-side filtering with JMESPath filters
5964
# The following statement will simply list "all" devices (there are no DB
60-
# filters) and subsequently filter the results using a JMESPath expression.
61-
# The JMESPath is matched against the unprocessed JSON, hence it is required
65+
# filters) and subsequently filter the results using a PyDF expression.
66+
# The PyDF expression is matched against the unprocessed JSON, hence it is required
6267
# to understand Cumulocity's native JSON formats (but they are close to how
6368
# the Python API resembles it:
64-
filtered_devices_2 = c8y.device_inventory.get_all(type='c8y_TestDevice', include="contains(name, 'Device')")
69+
filtered_devices_2 = c8y.device_inventory.get_all(type='c8y_TestDevice', include="name contains Device")
6570
# -> We will only have devices which are named "Device something"
6671
print("Option #2 result (same thing):")
6772
for d in filtered_devices_2:
@@ -84,14 +89,15 @@
8489

8590
# Option 4: the client-side filtering with nested filters
8691
# The following statement applies the same as above, but using ridiculously
87-
# nested Python matchers to get the same logic.
92+
# nested Python matchers to get the same logic. Note that we combine custom
93+
# filters with a PyDF expression filter.
8894

8995
filtered_devices_4 = c8y.device_inventory.get_all(
9096
type='c8y_TestDevice',
9197
include=match_all(
9298
field('name', '*Device*'),
9399
match_not(
94-
field('name', '*#*')
100+
pydf("name contains '#'")
95101
)
96102
))
97103
# -> Same result

0 commit comments

Comments
 (0)