influxdb3-python 0.4.0__tar.gz → 0.5.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. {influxdb3_python-0.4.0 → influxdb3_python-0.5.0}/PKG-INFO +11 -7
  2. {influxdb3_python-0.4.0 → influxdb3_python-0.5.0}/README.md +7 -6
  3. {influxdb3_python-0.4.0 → influxdb3_python-0.5.0}/influxdb3_python.egg-info/PKG-INFO +11 -7
  4. {influxdb3_python-0.4.0 → influxdb3_python-0.5.0}/influxdb3_python.egg-info/SOURCES.txt +6 -1
  5. {influxdb3_python-0.4.0 → influxdb3_python-0.5.0}/influxdb3_python.egg-info/requires.txt +4 -0
  6. {influxdb3_python-0.4.0 → influxdb3_python-0.5.0}/influxdb_client_3/__init__.py +45 -24
  7. influxdb3_python-0.5.0/influxdb_client_3/py.typed +0 -0
  8. {influxdb3_python-0.4.0 → influxdb3_python-0.5.0}/setup.py +9 -2
  9. influxdb3_python-0.5.0/tests/test_deep_merge.py +54 -0
  10. influxdb3_python-0.5.0/tests/test_influxdb_client_3_integration.py +44 -0
  11. influxdb3_python-0.5.0/tests/test_merge_options.py +28 -0
  12. influxdb3_python-0.5.0/tests/test_query.py +53 -0
  13. {influxdb3_python-0.4.0 → influxdb3_python-0.5.0}/LICENSE +0 -0
  14. {influxdb3_python-0.4.0 → influxdb3_python-0.5.0}/influxdb3_python.egg-info/dependency_links.txt +0 -0
  15. {influxdb3_python-0.4.0 → influxdb3_python-0.5.0}/influxdb3_python.egg-info/top_level.txt +0 -0
  16. {influxdb3_python-0.4.0 → influxdb3_python-0.5.0}/influxdb_client_3/read_file.py +0 -0
  17. {influxdb3_python-0.4.0 → influxdb3_python-0.5.0}/influxdb_client_3/write_client/__init__.py +0 -0
  18. {influxdb3_python-0.4.0 → influxdb3_python-0.5.0}/influxdb_client_3/write_client/_sync/__init__.py +0 -0
  19. {influxdb3_python-0.4.0 → influxdb3_python-0.5.0}/influxdb_client_3/write_client/_sync/api_client.py +0 -0
  20. {influxdb3_python-0.4.0 → influxdb3_python-0.5.0}/influxdb_client_3/write_client/_sync/rest.py +0 -0
  21. {influxdb3_python-0.4.0 → influxdb3_python-0.5.0}/influxdb_client_3/write_client/client/__init__.py +0 -0
  22. {influxdb3_python-0.4.0 → influxdb3_python-0.5.0}/influxdb_client_3/write_client/client/_base.py +0 -0
  23. {influxdb3_python-0.4.0 → influxdb3_python-0.5.0}/influxdb_client_3/write_client/client/exceptions.py +0 -0
  24. {influxdb3_python-0.4.0 → influxdb3_python-0.5.0}/influxdb_client_3/write_client/client/influxdb_client.py +0 -0
  25. {influxdb3_python-0.4.0 → influxdb3_python-0.5.0}/influxdb_client_3/write_client/client/logging_handler.py +0 -0
  26. {influxdb3_python-0.4.0 → influxdb3_python-0.5.0}/influxdb_client_3/write_client/client/util/__init__.py +0 -0
  27. {influxdb3_python-0.4.0 → influxdb3_python-0.5.0}/influxdb_client_3/write_client/client/util/date_utils.py +0 -0
  28. {influxdb3_python-0.4.0 → influxdb3_python-0.5.0}/influxdb_client_3/write_client/client/util/date_utils_pandas.py +0 -0
  29. {influxdb3_python-0.4.0 → influxdb3_python-0.5.0}/influxdb_client_3/write_client/client/util/helpers.py +0 -0
  30. {influxdb3_python-0.4.0 → influxdb3_python-0.5.0}/influxdb_client_3/write_client/client/util/multiprocessing_helper.py +0 -0
  31. {influxdb3_python-0.4.0 → influxdb3_python-0.5.0}/influxdb_client_3/write_client/client/warnings.py +0 -0
  32. {influxdb3_python-0.4.0 → influxdb3_python-0.5.0}/influxdb_client_3/write_client/client/write/__init__.py +0 -0
  33. {influxdb3_python-0.4.0 → influxdb3_python-0.5.0}/influxdb_client_3/write_client/client/write/dataframe_serializer.py +0 -0
  34. {influxdb3_python-0.4.0 → influxdb3_python-0.5.0}/influxdb_client_3/write_client/client/write/point.py +0 -0
  35. {influxdb3_python-0.4.0 → influxdb3_python-0.5.0}/influxdb_client_3/write_client/client/write/retry.py +0 -0
  36. {influxdb3_python-0.4.0 → influxdb3_python-0.5.0}/influxdb_client_3/write_client/client/write_api.py +0 -0
  37. {influxdb3_python-0.4.0 → influxdb3_python-0.5.0}/influxdb_client_3/write_client/configuration.py +0 -0
  38. {influxdb3_python-0.4.0 → influxdb3_python-0.5.0}/influxdb_client_3/write_client/domain/__init__.py +0 -0
  39. {influxdb3_python-0.4.0 → influxdb3_python-0.5.0}/influxdb_client_3/write_client/domain/write_precision.py +0 -0
  40. {influxdb3_python-0.4.0 → influxdb3_python-0.5.0}/influxdb_client_3/write_client/extras.py +0 -0
  41. {influxdb3_python-0.4.0 → influxdb3_python-0.5.0}/influxdb_client_3/write_client/rest.py +0 -0
  42. {influxdb3_python-0.4.0 → influxdb3_python-0.5.0}/influxdb_client_3/write_client/service/__init__.py +0 -0
  43. {influxdb3_python-0.4.0 → influxdb3_python-0.5.0}/influxdb_client_3/write_client/service/_base_service.py +0 -0
  44. {influxdb3_python-0.4.0 → influxdb3_python-0.5.0}/influxdb_client_3/write_client/service/signin_service.py +0 -0
  45. {influxdb3_python-0.4.0 → influxdb3_python-0.5.0}/influxdb_client_3/write_client/service/signout_service.py +0 -0
  46. {influxdb3_python-0.4.0 → influxdb3_python-0.5.0}/influxdb_client_3/write_client/service/write_service.py +0 -0
  47. {influxdb3_python-0.4.0 → influxdb3_python-0.5.0}/influxdb_client_3/write_client/version.py +0 -0
  48. {influxdb3_python-0.4.0 → influxdb3_python-0.5.0}/setup.cfg +0 -0
  49. {influxdb3_python-0.4.0 → influxdb3_python-0.5.0}/tests/test_dataframe_serializer.py +0 -0
  50. {influxdb3_python-0.4.0 → influxdb3_python-0.5.0}/tests/test_influxdb_client_3.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: influxdb3-python
3
- Version: 0.4.0
3
+ Version: 0.5.0
4
4
  Summary: Community Python client for InfluxDB 3.0
5
5
  Home-page: https://github.com/InfluxCommunity/influxdb3-python
6
6
  Author: InfluxData
@@ -29,6 +29,9 @@ Requires-Dist: polars; extra == "polars"
29
29
  Provides-Extra: dataframe
30
30
  Requires-Dist: pandas; extra == "dataframe"
31
31
  Requires-Dist: polars; extra == "dataframe"
32
+ Provides-Extra: test
33
+ Requires-Dist: pytest; extra == "test"
34
+ Requires-Dist: pytest-cov; extra == "test"
32
35
 
33
36
  <p align="center">
34
37
  <img src="https://github.com/InfluxCommunity/influxdb3-python/blob/main/python-logo.png?raw=true" alt="Your Image" width="150px">
@@ -60,11 +63,12 @@ Requires-Dist: polars; extra == "dataframe"
60
63
 
61
64
  `influxdb_client_3` is a Python module that provides a simple and convenient way to interact with InfluxDB 3.0. This module supports both writing data to InfluxDB and querying data using the Flight client, which allows you to execute SQL and InfluxQL queries on InfluxDB 3.0.
62
65
 
66
+ We offer a ["Getting Started: InfluxDB 3.0 Python Client Library"](https://www.youtube.com/watch?v=tpdONTm1GC8) video that goes over how to use the library and goes over the examples.
63
67
  ## Dependencies
64
68
 
65
69
  - `pyarrow` (automatically installed)
66
70
  - `pandas` (optional)
67
-
71
+
68
72
 
69
73
  ## Installation
70
74
 
@@ -145,7 +149,7 @@ write_options = WriteOptions(batch_size=500,
145
149
  wco = write_client_options(success_callback=callback.success,
146
150
  error_callback=callback.error,
147
151
  retry_callback=callback.retry,
148
- WriteOptions=write_options
152
+ write_options=write_options
149
153
  )
150
154
 
151
155
  with InfluxDBClient3.InfluxDBClient3(
@@ -158,11 +162,11 @@ with InfluxDBClient3.InfluxDBClient3(
158
162
  client.write_file(
159
163
  file='./out.csv',
160
164
  timestamp_column='time', tag_columns=["provider", "machineID"])
161
-
165
+
162
166
  client.write_file(
163
167
  file='./out.json',
164
168
  timestamp_column='time', tag_columns=["provider", "machineID"], date_unit='ns' )
165
-
169
+
166
170
 
167
171
  ```
168
172
 
@@ -176,7 +180,7 @@ client._write_api.write(bucket="pokemon-codex", record=pd_df, data_frame_measure
176
180
  client._write_api.write(bucket="pokemon-codex", record=pl_df, data_frame_measurement_name='caught', data_frame_tag_columns=['trainer', 'id', 'num'], data_frame_timestamp_column='timestamp')
177
181
  ```
178
182
 
179
- ## Querying
183
+ ## Querying
180
184
 
181
185
  ### Querying with SQL
182
186
  ```python
@@ -228,4 +232,4 @@ table = client.query(
228
232
 
229
233
  print(table.to_pandas())
230
234
  ```
231
- You may also include your own root certificate via this manor aswell.
235
+ You may also include your own root certificate via this manor aswell.
@@ -28,11 +28,12 @@
28
28
 
29
29
  `influxdb_client_3` is a Python module that provides a simple and convenient way to interact with InfluxDB 3.0. This module supports both writing data to InfluxDB and querying data using the Flight client, which allows you to execute SQL and InfluxQL queries on InfluxDB 3.0.
30
30
 
31
+ We offer a ["Getting Started: InfluxDB 3.0 Python Client Library"](https://www.youtube.com/watch?v=tpdONTm1GC8) video that goes over how to use the library and goes over the examples.
31
32
  ## Dependencies
32
33
 
33
34
  - `pyarrow` (automatically installed)
34
35
  - `pandas` (optional)
35
-
36
+
36
37
 
37
38
  ## Installation
38
39
 
@@ -113,7 +114,7 @@ write_options = WriteOptions(batch_size=500,
113
114
  wco = write_client_options(success_callback=callback.success,
114
115
  error_callback=callback.error,
115
116
  retry_callback=callback.retry,
116
- WriteOptions=write_options
117
+ write_options=write_options
117
118
  )
118
119
 
119
120
  with InfluxDBClient3.InfluxDBClient3(
@@ -126,11 +127,11 @@ with InfluxDBClient3.InfluxDBClient3(
126
127
  client.write_file(
127
128
  file='./out.csv',
128
129
  timestamp_column='time', tag_columns=["provider", "machineID"])
129
-
130
+
130
131
  client.write_file(
131
132
  file='./out.json',
132
133
  timestamp_column='time', tag_columns=["provider", "machineID"], date_unit='ns' )
133
-
134
+
134
135
 
135
136
  ```
136
137
 
@@ -144,7 +145,7 @@ client._write_api.write(bucket="pokemon-codex", record=pd_df, data_frame_measure
144
145
  client._write_api.write(bucket="pokemon-codex", record=pl_df, data_frame_measurement_name='caught', data_frame_tag_columns=['trainer', 'id', 'num'], data_frame_timestamp_column='timestamp')
145
146
  ```
146
147
 
147
- ## Querying
148
+ ## Querying
148
149
 
149
150
  ### Querying with SQL
150
151
  ```python
@@ -196,4 +197,4 @@ table = client.query(
196
197
 
197
198
  print(table.to_pandas())
198
199
  ```
199
- You may also include your own root certificate via this manor aswell.
200
+ You may also include your own root certificate via this manor aswell.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: influxdb3-python
3
- Version: 0.4.0
3
+ Version: 0.5.0
4
4
  Summary: Community Python client for InfluxDB 3.0
5
5
  Home-page: https://github.com/InfluxCommunity/influxdb3-python
6
6
  Author: InfluxData
@@ -29,6 +29,9 @@ Requires-Dist: polars; extra == "polars"
29
29
  Provides-Extra: dataframe
30
30
  Requires-Dist: pandas; extra == "dataframe"
31
31
  Requires-Dist: polars; extra == "dataframe"
32
+ Provides-Extra: test
33
+ Requires-Dist: pytest; extra == "test"
34
+ Requires-Dist: pytest-cov; extra == "test"
32
35
 
33
36
  <p align="center">
34
37
  <img src="https://github.com/InfluxCommunity/influxdb3-python/blob/main/python-logo.png?raw=true" alt="Your Image" width="150px">
@@ -60,11 +63,12 @@ Requires-Dist: polars; extra == "dataframe"
60
63
 
61
64
  `influxdb_client_3` is a Python module that provides a simple and convenient way to interact with InfluxDB 3.0. This module supports both writing data to InfluxDB and querying data using the Flight client, which allows you to execute SQL and InfluxQL queries on InfluxDB 3.0.
62
65
 
66
+ We offer a ["Getting Started: InfluxDB 3.0 Python Client Library"](https://www.youtube.com/watch?v=tpdONTm1GC8) video that goes over how to use the library and goes over the examples.
63
67
  ## Dependencies
64
68
 
65
69
  - `pyarrow` (automatically installed)
66
70
  - `pandas` (optional)
67
-
71
+
68
72
 
69
73
  ## Installation
70
74
 
@@ -145,7 +149,7 @@ write_options = WriteOptions(batch_size=500,
145
149
  wco = write_client_options(success_callback=callback.success,
146
150
  error_callback=callback.error,
147
151
  retry_callback=callback.retry,
148
- WriteOptions=write_options
152
+ write_options=write_options
149
153
  )
150
154
 
151
155
  with InfluxDBClient3.InfluxDBClient3(
@@ -158,11 +162,11 @@ with InfluxDBClient3.InfluxDBClient3(
158
162
  client.write_file(
159
163
  file='./out.csv',
160
164
  timestamp_column='time', tag_columns=["provider", "machineID"])
161
-
165
+
162
166
  client.write_file(
163
167
  file='./out.json',
164
168
  timestamp_column='time', tag_columns=["provider", "machineID"], date_unit='ns' )
165
-
169
+
166
170
 
167
171
  ```
168
172
 
@@ -176,7 +180,7 @@ client._write_api.write(bucket="pokemon-codex", record=pd_df, data_frame_measure
176
180
  client._write_api.write(bucket="pokemon-codex", record=pl_df, data_frame_measurement_name='caught', data_frame_tag_columns=['trainer', 'id', 'num'], data_frame_timestamp_column='timestamp')
177
181
  ```
178
182
 
179
- ## Querying
183
+ ## Querying
180
184
 
181
185
  ### Querying with SQL
182
186
  ```python
@@ -228,4 +232,4 @@ table = client.query(
228
232
 
229
233
  print(table.to_pandas())
230
234
  ```
231
- You may also include your own root certificate via this manor aswell.
235
+ You may also include your own root certificate via this manor aswell.
@@ -7,6 +7,7 @@ influxdb3_python.egg-info/dependency_links.txt
7
7
  influxdb3_python.egg-info/requires.txt
8
8
  influxdb3_python.egg-info/top_level.txt
9
9
  influxdb_client_3/__init__.py
10
+ influxdb_client_3/py.typed
10
11
  influxdb_client_3/read_file.py
11
12
  influxdb_client_3/write_client/__init__.py
12
13
  influxdb_client_3/write_client/configuration.py
@@ -40,4 +41,8 @@ influxdb_client_3/write_client/service/signin_service.py
40
41
  influxdb_client_3/write_client/service/signout_service.py
41
42
  influxdb_client_3/write_client/service/write_service.py
42
43
  tests/test_dataframe_serializer.py
43
- tests/test_influxdb_client_3.py
44
+ tests/test_deep_merge.py
45
+ tests/test_influxdb_client_3.py
46
+ tests/test_influxdb_client_3_integration.py
47
+ tests/test_merge_options.py
48
+ tests/test_query.py
@@ -14,3 +14,7 @@ pandas
14
14
 
15
15
  [polars]
16
16
  polars
17
+
18
+ [test]
19
+ pytest
20
+ pytest-cov
@@ -69,12 +69,26 @@ def _deep_merge(target, source):
69
69
  elif isinstance(target, list) and isinstance(source, list):
70
70
  # If both target and source are lists, concatenate them
71
71
  target.extend(source)
72
- else:
72
+ elif source is not None:
73
73
  # For other types, simply replace the target with the source
74
74
  target = source
75
75
  return target
76
76
 
77
77
 
78
+ def _merge_options(defaults, exclude_keys=None, custom=None):
79
+ """
80
+ Merge default option arguments with custom (user-provided) arguments,
81
+ excluding specific keys defined in exclude_keys.
82
+ """
83
+ if custom is None or len(custom) == 0:
84
+ return defaults
85
+
86
+ if exclude_keys is None:
87
+ exclude_keys = []
88
+
89
+ return _deep_merge(defaults, {key: value for key, value in custom.items() if key not in exclude_keys})
90
+
91
+
78
92
  class InfluxDBClient3:
79
93
  def __init__(
80
94
  self,
@@ -135,14 +149,6 @@ class InfluxDBClient3:
135
149
  port = query_port_overwrite
136
150
  self._flight_client = FlightClient(f"grpc+tls://{hostname}:{port}", **self._flight_client_options)
137
151
 
138
- def _merge_options(self, defaults, custom={}):
139
- """
140
- Merge default option arguments with custom (user-provided) arguments.
141
- """
142
- if len(custom) == 0:
143
- return defaults
144
- return _deep_merge(defaults, {key: value for key, value in custom.items()})
145
-
146
152
  def write(self, record=None, database=None, **kwargs):
147
153
  """
148
154
  Write data to InfluxDB.
@@ -214,20 +220,23 @@ class InfluxDBClient3:
214
220
  data_frame_tag_columns=tag_columns,
215
221
  data_frame_timestamp_column=timestamp_column, **kwargs)
216
222
 
217
- def query(self, query, language="sql", mode="all", database=None, **kwargs):
218
- """
219
- Query data from InfluxDB.
220
-
221
- :param query: The query string.
222
- :type query: str
223
- :param language: The query language; "sql" or "influxql" (default is "sql").
224
- :type language: str
225
- :param mode: The mode of fetching data (all, pandas, chunk, reader, schema).
226
- :type mode: str
223
+ def query(self, query: str, language: str = "sql", mode: str = "all", database: str = None, **kwargs):
224
+ """Query data from InfluxDB.
225
+
226
+ If you want to use query parameters, you can pass them as kwargs:
227
+
228
+ >>> client.query("select * from cpu where host=$host", query_parameters={"host": "server01"})
229
+
230
+ :param query: The query to execute on the database.
231
+ :param language: The query language to use. It should be one of "influxql" or "sql". Defaults to "sql".
232
+ :param mode: The mode to use for the query. It should be one of "all", "pandas", "polars", "chunk",
233
+ "reader" or "schema". Defaults to "all".
227
234
  :param database: The database to query from. If not provided, uses the database provided during initialization.
228
- :type database: str
229
- :param kwargs: FlightClientCallOptions for the query.
230
- :return: The queried data.
235
+ :param kwargs: Additional arguments to pass to the ``FlightCallOptions headers``. For example, it can be used to
236
+ set up per request headers.
237
+ :keyword query_parameters: The query parameters to use in the query.
238
+ It should be a ``dictionary`` of key-value pairs.
239
+ :return: The query result in the specified mode.
231
240
  """
232
241
  if mode == "polars" and polars is False:
233
242
  raise ImportError("Polars is not installed. Please install it with `pip install polars`.")
@@ -241,10 +250,22 @@ class InfluxDBClient3:
241
250
  "headers": [(b"authorization", f"Bearer {self._token}".encode('utf-8'))],
242
251
  "timeout": 300
243
252
  }
244
- opts = self._merge_options(optargs, kwargs)
253
+ opts = _merge_options(optargs, exclude_keys=['query_parameters'], custom=kwargs)
245
254
  _options = FlightCallOptions(**opts)
246
255
 
247
- ticket_data = {"database": database, "sql_query": query, "query_type": language}
256
+ #
257
+ # Ticket data
258
+ #
259
+ ticket_data = {
260
+ "database": database,
261
+ "sql_query": query,
262
+ "query_type": language
263
+ }
264
+ # add query parameters
265
+ query_parameters = kwargs.get("query_parameters", None)
266
+ if query_parameters:
267
+ ticket_data["params"] = query_parameters
268
+
248
269
  ticket = Ticket(json.dumps(ticket_data).encode('utf-8'))
249
270
  flight_reader = self._flight_client.do_get(ticket, _options)
250
271
 
File without changes
@@ -2,7 +2,6 @@ from setuptools import setup, find_packages
2
2
  import os
3
3
  import re
4
4
 
5
-
6
5
  requires = [
7
6
  'reactivex >= 4.0.4',
8
7
  'certifi >= 14.05.14',
@@ -15,6 +14,7 @@ requires = [
15
14
  with open("./README.md", "r", encoding="utf-8") as fh:
16
15
  long_description = fh.read()
17
16
 
17
+
18
18
  def get_version_from_github_ref():
19
19
  github_ref = os.environ.get("GITHUB_REF")
20
20
  if not github_ref:
@@ -26,6 +26,7 @@ def get_version_from_github_ref():
26
26
 
27
27
  return match.group(1)
28
28
 
29
+
29
30
  def get_version():
30
31
  # If running in GitHub Actions, get version from GITHUB_REF
31
32
  version = get_version_from_github_ref()
@@ -35,6 +36,7 @@ def get_version():
35
36
  # Fallback to a default version if not in GitHub Actions
36
37
  return "v0.0.0"
37
38
 
39
+
38
40
  setup(
39
41
  name='influxdb3-python',
40
42
  version=get_version(),
@@ -45,7 +47,12 @@ setup(
45
47
  author_email='contact@influxdata.com',
46
48
  url='https://github.com/InfluxCommunity/influxdb3-python',
47
49
  packages=find_packages(exclude=['tests', 'tests.*', 'examples', 'examples.*']),
48
- extras_require={'pandas': ['pandas'], 'polars': ['polars'], 'dataframe': ['pandas', 'polars']},
50
+ extras_require={
51
+ 'pandas': ['pandas'],
52
+ 'polars': ['polars'],
53
+ 'dataframe': ['pandas', 'polars'],
54
+ 'test': ['pytest', 'pytest-cov']
55
+ },
49
56
  install_requires=requires,
50
57
  python_requires='>=3.8',
51
58
  classifiers=[
@@ -0,0 +1,54 @@
1
+ import unittest
2
+
3
+ import influxdb_client_3
4
+
5
+
6
+ class TestDeepMerge(unittest.TestCase):
7
+
8
+ def test_deep_merge_dicts_with_no_overlap(self):
9
+ target = {"a": 1, "b": 2}
10
+ source = {"c": 3, "d": 4}
11
+ result = influxdb_client_3._deep_merge(target, source)
12
+ self.assertEqual(result, {"a": 1, "b": 2, "c": 3, "d": 4})
13
+
14
+ def test_deep_merge_dicts_with_overlap(self):
15
+ target = {"a": 1, "b": 2}
16
+ source = {"b": 3, "c": 4}
17
+ result = influxdb_client_3._deep_merge(target, source)
18
+ self.assertEqual(result, {"a": 1, "b": 3, "c": 4})
19
+
20
+ def test_deep_merge_nested_dicts(self):
21
+ target = {"a": {"b": 1}}
22
+ source = {"a": {"c": 2}}
23
+ result = influxdb_client_3._deep_merge(target, source)
24
+ self.assertEqual(result, {"a": {"b": 1, "c": 2}})
25
+
26
+ def test_deep_merge_lists(self):
27
+ target = [1, 2]
28
+ source = [3, 4]
29
+ result = influxdb_client_3._deep_merge(target, source)
30
+ self.assertEqual(result, [1, 2, 3, 4])
31
+
32
+ def test_deep_merge_non_overlapping_types(self):
33
+ target = {"a": 1}
34
+ source = [2, 3]
35
+ result = influxdb_client_3._deep_merge(target, source)
36
+ self.assertEqual(result, [2, 3])
37
+
38
+ def test_deep_merge_none_to_flight(self):
39
+ target = {
40
+ "headers": [(b"authorization", "Bearer xyz".encode('utf-8'))],
41
+ "timeout": 300
42
+ }
43
+ source = None
44
+ result = influxdb_client_3._deep_merge(target, source)
45
+ self.assertEqual(result, target)
46
+
47
+ def test_deep_merge_empty_to_flight(self):
48
+ target = {
49
+ "headers": [(b"authorization", "Bearer xyz".encode('utf-8'))],
50
+ "timeout": 300
51
+ }
52
+ source = {}
53
+ result = influxdb_client_3._deep_merge(target, source)
54
+ self.assertEqual(result, target)
@@ -0,0 +1,44 @@
1
+ import os
2
+ import time
3
+ import unittest
4
+
5
+ import pytest
6
+
7
+ from influxdb_client_3 import InfluxDBClient3
8
+
9
+
10
+ @pytest.mark.integration
11
+ @pytest.mark.skipif(
12
+ not all(
13
+ [
14
+ os.getenv('TESTING_INFLUXDB_URL'),
15
+ os.getenv('TESTING_INFLUXDB_TOKEN'),
16
+ os.getenv('TESTING_INFLUXDB_DATABASE'),
17
+ ]
18
+ ),
19
+ reason="Integration test environment variables not set.",
20
+ )
21
+ class TestInfluxDBClient3Integration(unittest.TestCase):
22
+
23
+ def setUp(self):
24
+ host = os.getenv('TESTING_INFLUXDB_URL')
25
+ token = os.getenv('TESTING_INFLUXDB_TOKEN')
26
+ database = os.getenv('TESTING_INFLUXDB_DATABASE')
27
+
28
+ self.client = InfluxDBClient3(host=host, database=database, token=token)
29
+
30
+ def tearDown(self):
31
+ if self.client:
32
+ self.client.close()
33
+
34
+ def test_write_and_query(self):
35
+ test_id = time.time_ns()
36
+ self.client.write(f"integration_test_python,type=used value=123.0,test_id={test_id}i")
37
+
38
+ sql = 'SELECT * FROM integration_test_python where type=$type and test_id=$test_id'
39
+
40
+ df = self.client.query(sql, mode="pandas", query_parameters={'type': 'used', 'test_id': test_id})
41
+
42
+ self.assertEqual(1, len(df))
43
+ self.assertEqual(test_id, df['test_id'][0])
44
+ self.assertEqual(123.0, df['value'][0])
@@ -0,0 +1,28 @@
1
+ import unittest
2
+
3
+ import influxdb_client_3
4
+
5
+
6
+ class MergeOptionsTests(unittest.TestCase):
7
+
8
+ def test_merge_with_empty_custom(self):
9
+ defaults = {"a": 1, "b": 2}
10
+ result = influxdb_client_3._merge_options(defaults, custom={})
11
+ self.assertEqual(result, defaults)
12
+
13
+ def test_merge_with_none_custom(self):
14
+ defaults = {"a": 1, "b": 2}
15
+ result = influxdb_client_3._merge_options(defaults, custom=None)
16
+ self.assertEqual(result, defaults)
17
+
18
+ def test_merge_with_no_excluded_keys(self):
19
+ defaults = {"a": 1, "b": 2}
20
+ custom = {"b": 3, "c": 4}
21
+ result = influxdb_client_3._merge_options(defaults, custom=custom)
22
+ self.assertEqual(result, {"a": 1, "b": 3, "c": 4})
23
+
24
+ def test_merge_with_excluded_keys(self):
25
+ defaults = {"a": 1, "b": 2}
26
+ custom = {"b": 3, "c": 4}
27
+ result = influxdb_client_3._merge_options(defaults, exclude_keys=["b"], custom=custom)
28
+ self.assertEqual(result, {"a": 1, "b": 2, "c": 4})
@@ -0,0 +1,53 @@
1
+ import unittest
2
+ from unittest.mock import Mock, patch, ANY
3
+
4
+ from pyarrow.flight import Ticket
5
+
6
+ from influxdb_client_3 import InfluxDBClient3
7
+
8
+
9
+ class QueryTests(unittest.TestCase):
10
+
11
+ @patch('influxdb_client_3._InfluxDBClient')
12
+ @patch('influxdb_client_3._WriteApi')
13
+ @patch('influxdb_client_3.FlightClient')
14
+ def setUp(self, mock_flight_client, mock_write_api, mock_influx_db_client):
15
+ self.mock_influx_db_client = mock_influx_db_client
16
+ self.mock_write_api = mock_write_api
17
+ self.mock_flight_client = mock_flight_client
18
+ self.client = InfluxDBClient3(
19
+ host="localhost",
20
+ org="my_org",
21
+ database="my_db",
22
+ token="my_token"
23
+ )
24
+ self.client._flight_client = mock_flight_client
25
+ self.client._write_api = mock_write_api
26
+
27
+ def test_query_without_parameters(self):
28
+ mock_do_get = Mock()
29
+ self.client._flight_client.do_get = mock_do_get
30
+
31
+ self.client.query('SELECT * FROM measurement')
32
+
33
+ expected_ticket = Ticket(
34
+ '{"database": "my_db", '
35
+ '"sql_query": "SELECT * FROM measurement", '
36
+ '"query_type": "sql"}'.encode('utf-8')
37
+ )
38
+
39
+ mock_do_get.assert_called_once_with(expected_ticket, ANY)
40
+
41
+ def test_query_with_parameters(self):
42
+ mock_do_get = Mock()
43
+ self.client._flight_client.do_get = mock_do_get
44
+
45
+ self.client.query('SELECT * FROM measurement WHERE time > $time', query_parameters={"time": "2021-01-01"})
46
+
47
+ expected_ticket = Ticket(
48
+ '{"database": "my_db", '
49
+ '"sql_query": "SELECT * FROM measurement WHERE time > $time", '
50
+ '"query_type": "sql", "params": {"time": "2021-01-01"}}'.encode('utf-8')
51
+ )
52
+
53
+ mock_do_get.assert_called_once_with(expected_ticket, ANY)