Skip to content

Commit f455a87

Browse files
authored
feat: supports numpy types in serialization to Line protocol (#306)
1 parent ad58f9e commit f455a87

File tree

3 files changed

+41
-2
lines changed

3 files changed

+41
-2
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
1. [#281](https://github.com/influxdata/influxdb-client-python/pull/281): `FluxTable`, `FluxColumn` and `FluxRecord` objects have helpful reprs
55
1. [#293](https://github.com/influxdata/influxdb-client-python/pull/293): `dataframe_serializer` supports batching
66
1. [#301](https://github.com/influxdata/influxdb-client-python/pull/301): Add `proxy_headers` to configuration options
7+
1. [#306](https://github.com/influxdata/influxdb-client-python/pull/306): Supports `numpy` type in serialization to Line protocol
78

89
### Documentation
910
1. [#301](https://github.com/influxdata/influxdb-client-python/pull/301): How to configure proxy

influxdb_client/client/write/point.py

+20-2
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,13 @@
3939
'\\': r'\\',
4040
})
4141

42+
try:
43+
import numpy as np
44+
45+
_HAS_NUMPY = True
46+
except ModuleNotFoundError:
47+
_HAS_NUMPY = False
48+
4249

4350
class Point(object):
4451
"""
@@ -145,7 +152,7 @@ def _append_fields(fields):
145152
if value is None:
146153
continue
147154

148-
if isinstance(value, float) or isinstance(value, Decimal):
155+
if isinstance(value, float) or isinstance(value, Decimal) or _np_is_subtype(value, 'float'):
149156
if not math.isfinite(value):
150157
continue
151158
s = str(value)
@@ -156,7 +163,7 @@ def _append_fields(fields):
156163
if s.endswith('.0'):
157164
s = s[:-2]
158165
_return.append(f'{_escape_key(field)}={s}')
159-
elif isinstance(value, int) and not isinstance(value, bool):
166+
elif (isinstance(value, int) or _np_is_subtype(value, 'int')) and not isinstance(value, bool):
160167
_return.append(f'{_escape_key(field)}={str(value)}i')
161168
elif isinstance(value, bool):
162169
_return.append(f'{_escape_key(field)}={str(value).lower()}')
@@ -216,3 +223,14 @@ def _convert_timestamp(timestamp, precision=DEFAULT_WRITE_PRECISION):
216223
return ns / 1e9
217224

218225
raise ValueError(timestamp)
226+
227+
228+
def _np_is_subtype(value, np_type):
229+
if not _HAS_NUMPY or not hasattr(value, 'dtype'):
230+
return False
231+
232+
if np_type == 'float':
233+
return np.issubdtype(value, np.floating)
234+
elif np_type == 'int':
235+
return np.issubdtype(value, np.integer)
236+
return False

tests/test_point.py

+20
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,26 @@ def test_backslash(self):
388388
"test,tag1=value1,tag2=value\2,tag3=value\\3,tag4=value\\4,tag5=value\\\\5 value=10i 1624989000000000000",
389389
point.to_line_protocol())
390390

391+
def test_numpy_types(self):
392+
from influxdb_client.extras import np
393+
394+
point = Point.measurement("h2o")\
395+
.tag("location", "europe")\
396+
.field("np.float1", np.float(1.123))\
397+
.field("np.float2", np.float16(2.123))\
398+
.field("np.float3", np.float32(3.123))\
399+
.field("np.float4", np.float64(4.123))\
400+
.field("np.int1", np.int8(1))\
401+
.field("np.int2", np.int16(2))\
402+
.field("np.int3", np.int32(3))\
403+
.field("np.int4", np.int64(4))\
404+
.field("np.uint1", np.uint8(5))\
405+
.field("np.uint2", np.uint16(6))\
406+
.field("np.uint3", np.uint32(7))\
407+
.field("np.uint4", np.uint64(8))
408+
409+
self.assertEqual("h2o,location=europe np.float1=1.123,np.float2=2.123,np.float3=3.123,np.float4=4.123,np.int1=1i,np.int2=2i,np.int3=3i,np.int4=4i,np.uint1=5i,np.uint2=6i,np.uint3=7i,np.uint4=8i", point.to_line_protocol())
410+
391411

392412
if __name__ == '__main__':
393413
unittest.main()

0 commit comments

Comments
 (0)