Skip to content

Commit 90e10c8

Browse files
author
Christopher Rabotin
committed
Added documentation.
1 parent 50ac36a commit 90e10c8

File tree

1 file changed

+65
-19
lines changed

1 file changed

+65
-19
lines changed

influxdb/helper.py

Lines changed: 65 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -6,46 +6,89 @@
66
import six
77

88
class SeriesHelper(object):
9+
'''
10+
Subclassing this helper eases writing data points in bulk.
11+
All data points are immutable, insuring they do not get overwritten.
12+
Each subclass can write to its own database.
13+
The time series names can also be based on one or more defined fields.
14+
15+
Annotated example:
16+
```
17+
class MySeriesHelper(SeriesHelper):
18+
class Meta:
19+
# Meta class stores time series helper configuration.
20+
client = TestSeriesHelper.client
21+
# The client should be an instance of InfluxDBClient.
22+
series_name = 'events.stats.{server_name}'
23+
# The series name must be a string. Add dependent field names in curly brackets.
24+
fields = ['time', 'server_name']
25+
# Defines all the fields in this time series.
26+
bulk_size = 5
27+
# Defines the number of data points to store prior to writing on the wire.
28+
29+
# The following will create *five* (immutable) data points.
30+
# Since bulk_size is set to 5, upon the fifth construction call, *all* data
31+
# points will be written on the wire via MySeriesHelper.Meta.client.
32+
MySeriesHelper(server_name='us.east-1', time=159)
33+
MySeriesHelper(server_name='us.east-1', time=158)
34+
MySeriesHelper(server_name='us.east-1', time=157)
35+
MySeriesHelper(server_name='us.east-1', time=156)
36+
MySeriesHelper(server_name='us.east-1', time=155)
37+
38+
# To manually submit data points which are not yet written, call commit:
39+
MySeriesHelper.commit()
40+
41+
# To inspect the JSON which will be written, call _json_body_():
42+
MySeriesHelper._json_body_()
43+
```
44+
'''
945
__initialized__ = False
1046

1147
def __new__(cls, *args, **kwargs):
48+
'''
49+
Initializes class attributes for subsequent constructor calls.
50+
'''
1251
if not SeriesHelper.__initialized__:
1352
SeriesHelper.__initialized__ = True
14-
# Introspect series representation.
1553
try:
1654
_meta = getattr(cls, 'Meta')
1755
except AttributeError:
18-
raise AttributeError('SeriesHelper {} does not contain a Meta class.'.format(cls.__name__))
56+
raise AttributeError('Missing Meta class in {}.'.format(cls.__name__))
1957

20-
for attribute in ['series_name', 'fields', 'client']:
58+
for attr in ['series_name', 'fields', 'client']:
2159
try:
22-
setattr(cls, '_' + attribute, getattr(_meta, attribute))
60+
setattr(cls, '_' + attr, getattr(_meta, attr))
2361
except AttributeError:
24-
raise AttributeError('SeriesHelper\' {0} Meta class does not define {1}.'.format(cls.__name__, attribute))
62+
raise AttributeError('Missing {} in {} Meta class.'.format(attr, cls.__name__))
2563

2664
cls._bulk_size = getattr(_meta, 'bulk_size', 1)
27-
28-
# Class attribute definitions
29-
cls._datapoints = defaultdict(list) # keys are the series name for ease of commit.
65+
66+
cls._datapoints = defaultdict(list)
3067
cls._type = namedtuple(cls.__name__, cls._fields)
3168

3269
return super(SeriesHelper, cls).__new__(cls, *args, **kwargs)
3370

34-
def __init__(self, **kwargs): # Does not support positional arguments.
71+
def __init__(self, **kw):
72+
'''
73+
Constructor call creates a new data point. All fields must be present.
74+
:note: Data points written when `bulk_size` is reached per Helper.
75+
:warning: Data points are *immutable* (`namedtuples`).
76+
'''
3577
cls = self.__class__
3678

37-
if sorted(cls._fields) != sorted(kwargs.keys()):
38-
raise NameError('Expected fields {0} and got {1}.'.format(', '.join(sorted(cls._fields)), ', '.join(sorted(kwargs.keys()))))
79+
if sorted(cls._fields) != sorted(kw.keys()):
80+
raise NameError('Expected {0}, got {1}.'.format(cls._fields, kw.keys()))
3981

40-
cls._datapoints[cls._series_name.format(**kwargs)].append(cls._type(**kwargs))
82+
cls._datapoints[cls._series_name.format(**kw)].append(cls._type(**kw))
4183

42-
if len(cls._datapoints) > cls._bulk_size:
84+
if len(cls._datapoints) >= cls._bulk_size:
4385
cls.commit()
4486

4587
@classmethod
4688
def commit(cls):
4789
'''
4890
Commit everything from datapoints via the client.
91+
:return result of client.write_points.
4992
'''
5093
rtn = cls._client.write_points(cls._json_body_())
5194
cls._reset_()
@@ -56,14 +99,17 @@ def _json_body_(cls):
5699
'''
57100
:return: JSON body of these datapoints.
58101
'''
59-
json_datapoints = []
102+
json = []
60103
for series_name, data in six.iteritems(cls._datapoints):
61-
json_datapoints.append({'name': series_name,
62-
'columns': cls._fields,
63-
'points': [[point.__dict__[k] for k in cls._fields] for point in data]
64-
})
65-
return json_datapoints
104+
json.append({'name': series_name,
105+
'columns': cls._fields,
106+
'points': [[point.__dict__[k] for k in cls._fields] for point in data]
107+
})
108+
return json
66109

67110
@classmethod
68111
def _reset_(cls):
112+
'''
113+
Reset data storage.
114+
'''
69115
cls._datapoints = defaultdict(list)

0 commit comments

Comments
 (0)