Skip to content

Commit 2b6b6ea

Browse files
rolincovabednar
authored andcommitted
Configuration file (influxdata#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

Lines changed: 5 additions & 0 deletions
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

Lines changed: 82 additions & 0 deletions
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

Lines changed: 51 additions & 1 deletion
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

Lines changed: 5 additions & 0 deletions
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

Lines changed: 10 additions & 0 deletions
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

Lines changed: 87 additions & 7 deletions
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)
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