Skip to content

Commit 2b6b6ea

Browse files
rolincovabednar
authored andcommitted
Configuration file (#53)
* Initialize client library from config file and environmental properties
1 parent 73b74b9 commit 2b6b6ea

File tree

6 files changed

+240
-8
lines changed

6 files changed

+240
-8
lines changed

CHANGELOG.md

+5
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
## 1.4.0 [unreleased]
2+
3+
### Features
4+
1. [#52](https://github.com/influxdata/influxdb-client-python/issues/52): Initialize client library from config file and environmental properties
5+
16
## 1.3.0 [2020-01-17]
27

38
### Features

README.rst

+82
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,50 @@ Please follow the `Installation`_ and then run the following:
136136
for cell in row:
137137
val_count += 1
138138
139+
139140
.. marker-query-end
141+
142+
Client configuration
143+
--------------------
144+
145+
Via File
146+
^^^^^^^^
147+
A client can be configured via ``*.ini`` file in segment ``influx2``.
148+
149+
The following options are supported:
150+
151+
- ``url`` - the url to connect to InfluxDB
152+
- ``org`` - default destination organization for writes and queries
153+
- ``token`` - the token to use for the authorization
154+
- ``timeout`` - socket timeout in ms (default value is 10000)
155+
156+
.. code-block:: python
157+
158+
self.client = InfluxDBClient.from_config_file("config.ini")
159+
160+
.. code-block::
161+
162+
[influx2]
163+
url=http://localhost:9999
164+
org=my-org
165+
token=my-token
166+
timeout=6000
167+
168+
Via Environment Properties
169+
^^^^^^^^^^^^^^^^^^^^^^^^^^
170+
A client can be configured via environment properties.
171+
172+
Supported properties are:
173+
174+
- ``INFLUXDB_V2_URL`` - the url to connect to InfluxDB
175+
- ``INFLUXDB_V2_ORG`` - default destination organization for writes and queries
176+
- ``INFLUXDB_V2_TOKEN`` - the token to use for the authorization
177+
- ``INFLUXDB_V2_TIMEOUT`` - socket timeout in ms (default value is 10000)
178+
179+
.. code-block:: python
180+
181+
self.client = InfluxDBClient.from_env_properties()
182+
140183
.. marker-index-end
141184
142185
@@ -264,6 +307,9 @@ The expressions:
264307
- ``California Miner`` - static value
265308
- ``${env.hostname}`` - environment property
266309

310+
Via API
311+
_______
312+
267313
.. code-block:: python
268314
269315
point_settings = PointSettings()
@@ -278,6 +324,42 @@ The expressions:
278324
self.write_client = self.client.write_api(write_options=SYNCHRONOUS,
279325
point_settings=PointSettings(**{"id": "132-987-655",
280326
"customer": "California Miner"}))
327+
328+
Via Configuration file
329+
______________________
330+
331+
In a ini configuration file you are able to specify default tags by ``tags`` segment.
332+
333+
.. code-block:: python
334+
335+
self.client = InfluxDBClient.from_config_file("config.ini")
336+
337+
.. code-block::
338+
339+
[influx2]
340+
url=http://localhost:9999
341+
org=my-org
342+
token=my-token
343+
timeout=6000
344+
345+
[tags]
346+
id = 132-987-655
347+
customer = California Miner
348+
data_center = ${env.data_center}
349+
350+
Via Environment Properties
351+
__________________________
352+
You are able to specify default tags by environment properties with prefix ``INFLUXDB_V2_TAG_``.
353+
354+
Examples:
355+
356+
- ``INFLUXDB_V2_TAG_ID``
357+
- ``INFLUXDB_V2_TAG_HOSTNAME``
358+
359+
.. code-block:: python
360+
361+
self.client = InfluxDBClient.from_env_properties()
362+
281363
.. marker-default-tags-end
282364
283365
Asynchronous client

influxdb_client/client/influxdb_client.py

+51-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
from __future__ import absolute_import
22

3+
import configparser
4+
import os
5+
36
from influxdb_client import Configuration, ApiClient, HealthCheck, HealthService, Ready, ReadyService
47
from influxdb_client.client.authorizations_api import AuthorizationsApi
58
from influxdb_client.client.bucket_api import BucketsApi
@@ -14,7 +17,8 @@
1417

1518
class InfluxDBClient(object):
1619

17-
def __init__(self, url, token, debug=None, timeout=10000, enable_gzip=False, org: str = None) -> None:
20+
def __init__(self, url, token, debug=None, timeout=10000, enable_gzip=False, org: str = None,
21+
default_tags: dict = None) -> None:
1822
"""
1923
:class:`influxdb_client.InfluxDBClient` is client for HTTP API defined
2024
in https://github.com/influxdata/influxdb/blob/master/http/swagger.yml.
@@ -33,6 +37,8 @@ def __init__(self, url, token, debug=None, timeout=10000, enable_gzip=False, org
3337
self.timeout = timeout
3438
self.org = org
3539

40+
self.default_tags = default_tags
41+
3642
conf = _Configuration()
3743
conf.host = self.url
3844
conf.enable_gzip = enable_gzip
@@ -45,6 +51,50 @@ def __init__(self, url, token, debug=None, timeout=10000, enable_gzip=False, org
4551
self.api_client = ApiClient(configuration=conf, header_name=auth_header_name,
4652
header_value=auth_header_value)
4753

54+
@classmethod
55+
def from_config_file(cls, config_file: str = "config.ini", debug=None, enable_gzip=False):
56+
config = configparser.ConfigParser()
57+
config.read(config_file)
58+
59+
url = config['influx2']['url']
60+
token = config['influx2']['token']
61+
62+
timeout = None
63+
64+
if config.has_option('influx2', 'timeout'):
65+
timeout = config['influx2']['timeout']
66+
67+
org = None
68+
69+
if config.has_option('influx2', 'org'):
70+
org = config['influx2']['org']
71+
72+
default_tags = None
73+
74+
if config.has_section('tags'):
75+
default_tags = dict(config.items('tags'))
76+
77+
if timeout:
78+
return cls(url, token, debug=debug, timeout=int(timeout), org=org, default_tags=default_tags,
79+
enable_gzip=enable_gzip)
80+
81+
return cls(url, token, debug=debug, org=org, default_tags=default_tags, enable_gzip=enable_gzip)
82+
83+
@classmethod
84+
def from_env_properties(cls, debug=None, enable_gzip=False):
85+
url = os.getenv('INFLUXDB_V2_URL', "http://localhost:9999")
86+
token = os.getenv('INFLUXDB_V2_TOKEN', "my-token")
87+
timeout = os.getenv('INFLUXDB_V2_TIMEOUT', "10000")
88+
org = os.getenv('INFLUXDB_V2_ORG', "my-org")
89+
90+
default_tags = dict()
91+
92+
for key, value in os.environ.items():
93+
if key.startswith("INFLUXDB_V2_TAG_"):
94+
default_tags[key[16:].lower()] = value
95+
96+
return cls(url, token, debug=debug, timeout=int(timeout), org=org, default_tags=default_tags, enable_gzip=enable_gzip)
97+
4898
def write_api(self, write_options=WriteOptions(), point_settings=PointSettings()) -> WriteApi:
4999
"""
50100
Creates a Write API instance

influxdb_client/client/write_api.py

+5
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,11 @@ def __init__(self, influxdb_client, write_options: WriteOptions = WriteOptions()
138138
self._write_service = WriteService(influxdb_client.api_client)
139139
self._write_options = write_options
140140
self._point_settings = point_settings
141+
142+
if influxdb_client.default_tags:
143+
for key, value in influxdb_client.default_tags.items():
144+
self._point_settings.add_default_tag(key, value)
145+
141146
if self._write_options.write_type is WriteType.batching:
142147
# Define Subject that listen incoming data and produces writes into InfluxDB
143148
self._subject = Subject()

tests/config.ini

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
[influx2]
2+
url=http://192.168.0.2:9999
3+
org=my-org
4+
token=my-token
5+
timeout=6000
6+
7+
[tags]
8+
id = 132-987-655
9+
customer = California Miner
10+
data_center = ${env.data_center}

tests/test_WriteApi.py

+87-7
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
import time
99
from multiprocessing.pool import ApplyResult
1010

11-
from influxdb_client import Point, WritePrecision
11+
from influxdb_client import Point, WritePrecision, InfluxDBClient
1212
from influxdb_client.client.write_api import SYNCHRONOUS, ASYNCHRONOUS, PointSettings
1313
from influxdb_client.rest import ApiException
1414
from tests.base_test import BaseTest
@@ -77,7 +77,6 @@ def test_write_records_list(self):
7777
self.write_client.write(bucket.name, self.org, record_list)
7878

7979
query = 'from(bucket:"' + bucket.name + '") |> range(start: 1970-01-01T00:00:00.000000001Z)'
80-
print(query)
8180

8281
flux_result = self.client.query_api().query(query)
8382

@@ -109,7 +108,6 @@ def test_write_points_unicode(self):
109108
p.field(field_name, utf8_val)
110109
p.tag(tag, tag_value)
111110
record_list = [p]
112-
print(record_list)
113111

114112
self.write_client.write(bucket.name, self.org, record_list)
115113

@@ -147,7 +145,6 @@ def test_write_using_default_tags(self):
147145
p2.time(2)
148146

149147
record_list = [p, p2]
150-
print(record_list)
151148

152149
self.write_client.write(bucket.name, self.org, record_list)
153150

@@ -304,7 +301,6 @@ def test_write_dictionaries(self):
304301
time.sleep(1)
305302

306303
query = 'from(bucket:"' + bucket.name + '") |> range(start: 1970-01-01T00:00:00.000000001Z)'
307-
print(query)
308304

309305
flux_result = self.client.query_api().query(query)
310306

@@ -344,7 +340,6 @@ def test_use_default_tags_with_dictionaries(self):
344340
time.sleep(1)
345341

346342
query = 'from(bucket:"' + bucket.name + '") |> range(start: 1970-01-01T00:00:00.000000001Z)'
347-
print(query)
348343

349344
flux_result = self.client.query_api().query(query)
350345

@@ -379,7 +374,6 @@ def test_write_bytes(self):
379374
time.sleep(1)
380375

381376
query = 'from(bucket:"' + bucket.name + '") |> range(start: 1970-01-01T00:00:00.000000001Z)'
382-
print(query)
383377

384378
flux_result = self.client.query_api().query(query)
385379

@@ -444,5 +438,91 @@ def test_point_settings_with_add(self):
444438
self.assertEqual("LA", default_tags.get("data_center"))
445439

446440

441+
class DefaultTagsConfiguration(BaseTest):
442+
443+
def setUp(self) -> None:
444+
super().setUp()
445+
446+
os.environ['data_center'] = "LA"
447+
448+
self.id_tag = "132-987-655"
449+
self.customer_tag = "California Miner"
450+
self.data_center_key = "data_center"
451+
452+
os.environ['INFLUXDB_V2_TOKEN'] = "my-token"
453+
os.environ['INFLUXDB_V2_TIMEOUT'] = "6000"
454+
os.environ['INFLUXDB_V2_ORG'] = "my-org"
455+
456+
os.environ['INFLUXDB_V2_TAG_ID'] = self.id_tag
457+
os.environ['INFLUXDB_V2_TAG_CUSTOMER'] = self.customer_tag
458+
os.environ['INFLUXDB_V2_TAG_DATA_CENTER'] = "${env.data_center}"
459+
460+
def tearDown(self) -> None:
461+
self.write_client.__del__()
462+
super().tearDown()
463+
464+
def test_connection_option_from_conf_file(self):
465+
self.client.close()
466+
self.client = InfluxDBClient.from_config_file(os.getcwd() + "/tests/config.ini", self.debug)
467+
468+
self._check_connection_settings()
469+
470+
def test_connection_option_from_env(self):
471+
self.client.close()
472+
self.client = InfluxDBClient.from_env_properties(self.debug)
473+
474+
self._check_connection_settings()
475+
476+
def _check_connection_settings(self):
477+
self.write_client = self.client.write_api(write_options=SYNCHRONOUS)
478+
479+
self.assertEqual(os.getenv("INFLUXDB_V2_URL"), self.client.url)
480+
self.assertEqual("my-org", self.client.org)
481+
self.assertEqual("my-token", self.client.token)
482+
self.assertEqual(6000, self.client.timeout)
483+
484+
def test_default_tags_from_conf_file(self):
485+
self.client.close()
486+
self.client = InfluxDBClient.from_config_file(os.getcwd() + "/tests/config.ini", self.debug)
487+
488+
self._write_point()
489+
490+
def test_default_tags_from_env(self):
491+
self.client.close()
492+
self.client = InfluxDBClient.from_env_properties(self.debug)
493+
494+
self._write_point()
495+
496+
def _write_point(self):
497+
self.write_client = self.client.write_api(write_options=SYNCHRONOUS)
498+
499+
bucket = self.create_test_bucket()
500+
501+
measurement = "h2o_feet"
502+
field_name = "water_level"
503+
val = "1.0"
504+
tag = "location"
505+
tag_value = "creek level"
506+
507+
p = Point(measurement)
508+
p.field(field_name, val)
509+
p.tag(tag, tag_value)
510+
511+
record_list = [p]
512+
513+
self.write_client.write(bucket.name, self.org, record_list)
514+
515+
query = 'from(bucket:"' + bucket.name + '") |> range(start: 1970-01-01T00:00:00.000000001Z)'
516+
flux_result = self.client.query_api().query(query)
517+
self.assertEqual(1, len(flux_result))
518+
rec = flux_result[0].records[0]
519+
520+
self.assertEqual(self.id_tag, rec["id"])
521+
self.assertEqual(self.customer_tag, rec["customer"])
522+
self.assertEqual("LA", rec[self.data_center_key])
523+
524+
self.delete_test_bucket(bucket)
525+
526+
447527
if __name__ == '__main__':
448528
unittest.main()

0 commit comments

Comments
 (0)