Skip to content

Commit 922a0a5

Browse files
author
aviau
committed
ResultSet: added Keys() and items() functions
1 parent 863a5d4 commit 922a0a5

File tree

2 files changed

+99
-35
lines changed

2 files changed

+99
-35
lines changed

influxdb/resultset.py

Lines changed: 55 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -35,40 +35,23 @@ def __getitem__(self, key):
3535
if not isinstance(name, (str, type(None))):
3636
raise TypeError('serie_name must be an str or None')
3737

38-
for result in self.raw['results']:
39-
for serie in result['series']:
40-
serie_name = serie.get('name', None)
41-
if serie_name is None:
42-
# this is a "system" query or a query which
43-
# doesn't return a name attribute.
44-
# like 'show retention policies' ..
45-
if key is None:
46-
for point in serie['values']:
47-
yield Point(None, serie['columns'], point)
38+
for serie in self._get_series():
39+
serie_name = serie.get('name', None)
40+
if serie_name is None:
41+
# this is a "system" query or a query which
42+
# doesn't return a name attribute.
43+
# like 'show retention policies' ..
44+
if key is None:
45+
for point in serie['values']:
46+
yield Point(None, serie['columns'], point)
4847

49-
elif name in (None, serie_name):
50-
# by default if no tags was provided then
51-
# we will matches every returned serie
52-
serie_matches = True
53-
serie_tags = serie.get('tags', {})
54-
if tags:
55-
serie_matches = False
56-
# if there are some tags requested,
57-
# let's check them:
58-
for tag_name, tag_value in tags.items():
59-
# using _sentinel as I'm not sure that "None"
60-
# could be used, because it could be a valid
61-
# serie_tags value : when a serie has no such tag
62-
# then I think it's set to /null/None/.. TBC..
63-
serie_tag_value = serie_tags.get(tag_name, _sentinel)
64-
if serie_tag_value != tag_value:
65-
break
66-
else:
67-
serie_matches = True
68-
69-
if serie_matches:
70-
for point in serie['values']:
71-
yield Point(serie_name, serie['columns'], point, serie_tags)
48+
elif name in (None, serie_name):
49+
# by default if no tags was provided then
50+
# we will matches every returned serie
51+
serie_tags = serie.get('tags', {})
52+
if tags is None or self._tag_matches(serie_tags, tags):
53+
for point in serie['values']:
54+
yield Point(serie_name, serie['columns'], point, serie_tags)
7255

7356
def __repr__(self):
7457
return str(self.raw)
@@ -80,5 +63,42 @@ def __iter__(self):
8063
for serie in results['series']:
8164
yield serie
8265

83-
#def __len__(self):
84-
# return len(self.raw)
66+
def _tag_matches(self, tags, filter):
67+
"""Checks if all key/values in filter match in tags"""
68+
for tag_name, tag_value in filter.items():
69+
# using _sentinel as I'm not sure that "None"
70+
# could be used, because it could be a valid
71+
# serie_tags value : when a serie has no such tag
72+
# then I think it's set to /null/None/.. TBC..
73+
serie_tag_value = tags.get(tag_name, _sentinel)
74+
if serie_tag_value != tag_value:
75+
return False
76+
return True
77+
78+
def _get_series(self):
79+
"""Returns all series"""
80+
series = []
81+
try:
82+
for result in self.raw['results']:
83+
series.extend(result['series'])
84+
except KeyError:
85+
pass
86+
return series
87+
88+
def __len__(self):
89+
return len(self.keys())
90+
91+
def keys(self):
92+
keys = []
93+
for serie in self._get_series():
94+
keys.append((serie['name'], serie['tags']))
95+
return keys
96+
97+
def items(self):
98+
items = []
99+
for serie in self._get_series():
100+
serie_key = (serie['name'], serie['tags'])
101+
items.append(
102+
(serie_key, self.__getitem__(serie_key))
103+
)
104+
return items

tests/influxdb/resultset_test.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,3 +72,47 @@ def test_filter_by_tags(self):
7272
tags={"host": "server02", "region": "us-west"}),
7373
]
7474
)
75+
76+
def test_keys(self):
77+
self.assertItemsEqual(
78+
self.rs.keys(),
79+
[
80+
('cpu_load_short', {'host': 'server01', 'region': 'us-west'}),
81+
('cpu_load_short', {'host': 'server02', 'region': 'us-west'}),
82+
('other_serie', {'host': 'server01', 'region': 'us-west'})
83+
]
84+
)
85+
86+
def test_len(self):
87+
self.assertEqual(
88+
len(self.rs),
89+
3
90+
)
91+
92+
def test_items(self):
93+
items = list(self.rs.items())
94+
items_lists = [(item[0], list(item[1])) for item in items]
95+
96+
self.assertEqual(
97+
items_lists,
98+
[
99+
(
100+
('cpu_load_short', {'host': 'server01', 'region': 'us-west'}),
101+
[Point("cpu_load_short", ["time", "value"],
102+
["2015-01-29T21:51:28.968422294Z", 0.64],
103+
tags={"host": "server01", "region": "us-west"})]
104+
),
105+
(
106+
('cpu_load_short', {'host': 'server02', 'region': 'us-west'}),
107+
[Point("cpu_load_short", ["time", "value"],
108+
["2015-01-29T21:51:28.968422294Z", 0.64],
109+
tags={"host": "server02", "region": "us-west"})]
110+
),
111+
(
112+
('other_serie', {'host': 'server01', 'region': 'us-west'}),
113+
[Point("other_serie", ["time", "value"],
114+
["2015-01-29T21:51:28.968422294Z", 0.64],
115+
tags={"host": "server01", "region": "us-west"})]
116+
)
117+
]
118+
)

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy