Skip to content

Commit 5fb2e2f

Browse files
committed
Initialize client library from config file and environmental properties (#52)
1 parent 3adf95f commit 5fb2e2f

File tree

6 files changed

+239
-3
lines changed

6 files changed

+239
-3
lines changed

CHANGELOG.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
## 1.3.0 [unreleased]
22

33
### Features
4-
1. [#49](https://github.com/influxdata/influxdb-client-python/issues/50): Implemented default tags
4+
1. [#50](https://github.com/influxdata/influxdb-client-python/issues/50): Implemented default tags
5+
2. [#52](https://github.com/influxdata/influxdb-client-python/issues/52): Initialize client library from config file and environmental properties
56

67
### API
78
1. [#47](https://github.com/influxdata/influxdb-client-python/pull/47): Updated swagger to latest version

README.rst

+81
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,49 @@ 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+
self.client = InfluxDBClient.from_env_properties()
181+
140182
.. marker-index-end
141183
142184
@@ -264,6 +306,9 @@ The expressions:
264306
- ``California Miner`` - static value
265307
- ``${env.hostname}`` - environment property
266308

309+
Via API
310+
_______
311+
267312
.. code-block:: python
268313
269314
point_settings = PointSettings()
@@ -278,6 +323,42 @@ The expressions:
278323
self.write_client = self.client.write_api(write_options=SYNCHRONOUS,
279324
point_settings=PointSettings(**{"id": "132-987-655",
280325
"customer": "California Miner"}))
326+
327+
Via Configuration file
328+
______________________
329+
330+
In a ini configuration file you are able to specify default tags by ``tags`` segment.
331+
332+
.. code-block:: python
333+
334+
self.client = InfluxDBClient.from_config_file("config.ini")
335+
336+
.. code-block::
337+
338+
[influx2]
339+
url=http://localhost:9999
340+
org=my-org
341+
token=my-token
342+
timeout=6000
343+
344+
[tags]
345+
id = 132-987-655
346+
customer = California Miner
347+
data_center = ${env.data_center}
348+
349+
Via Environment Properties
350+
__________________________
351+
You are able to specify default tags by environment properties with prefix ``INFLUXDB_V2_TAG_``.
352+
353+
Examples:
354+
355+
- ``INFLUXDB_V2_TAG_ID``
356+
- ``INFLUXDB_V2_TAG_HOSTNAME``
357+
358+
.. code-block:: python
359+
360+
self.client = InfluxDBClient.from_env_properties()
361+
281362
.. marker-default-tags-end
282363
283364
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

+6
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from time import sleep
77
from typing import Union, List
88

9+
import configparser
910
import os
1011

1112
import rx
@@ -138,6 +139,11 @@ def __init__(self, influxdb_client, write_options: WriteOptions = WriteOptions()
138139
self._write_service = WriteService(influxdb_client.api_client)
139140
self._write_options = write_options
140141
self._point_settings = point_settings
142+
143+
if influxdb_client.default_tags:
144+
for key, value in influxdb_client.default_tags.items():
145+
self._point_settings.add_default_tag(key, value)
146+
141147
if self._write_options.write_type is WriteType.batching:
142148
# Define Subject that listen incoming data and produces writes into InfluxDB
143149
self._subject = Subject()

tests/config.ini

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
[influx2]
2+
url=http://localhost: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

+89-1
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
@@ -444,5 +444,93 @@ def test_point_settings_with_add(self):
444444
self.assertEqual("LA", default_tags.get("data_center"))
445445

446446

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

0 commit comments

Comments
 (0)