influxdb3-python 0.14.0__tar.gz → 0.16.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 (75) hide show
  1. {influxdb3_python-0.14.0/influxdb3_python.egg-info → influxdb3_python-0.16.0}/PKG-INFO +8 -1
  2. {influxdb3_python-0.14.0 → influxdb3_python-0.16.0}/README.md +7 -0
  3. {influxdb3_python-0.14.0 → influxdb3_python-0.16.0/influxdb3_python.egg-info}/PKG-INFO +8 -1
  4. {influxdb3_python-0.14.0 → influxdb3_python-0.16.0}/influxdb_client_3/__init__.py +27 -0
  5. {influxdb3_python-0.14.0 → influxdb3_python-0.16.0}/influxdb_client_3/version.py +1 -1
  6. {influxdb3_python-0.14.0 → influxdb3_python-0.16.0}/tests/test_influxdb_client_3.py +58 -0
  7. {influxdb3_python-0.14.0 → influxdb3_python-0.16.0}/tests/test_influxdb_client_3_integration.py +13 -40
  8. {influxdb3_python-0.14.0 → influxdb3_python-0.16.0}/Examples/__init__.py +0 -0
  9. {influxdb3_python-0.14.0 → influxdb3_python-0.16.0}/Examples/basic_ssl_example.py +0 -0
  10. {influxdb3_python-0.14.0 → influxdb3_python-0.16.0}/Examples/batching_example.py +0 -0
  11. {influxdb3_python-0.14.0 → influxdb3_python-0.16.0}/Examples/cloud_dedicated_query.py +0 -0
  12. {influxdb3_python-0.14.0 → influxdb3_python-0.16.0}/Examples/cloud_dedicated_write.py +0 -0
  13. {influxdb3_python-0.14.0 → influxdb3_python-0.16.0}/Examples/config.py +0 -0
  14. {influxdb3_python-0.14.0 → influxdb3_python-0.16.0}/Examples/flight_options_example.py +0 -0
  15. {influxdb3_python-0.14.0 → influxdb3_python-0.16.0}/Examples/handle_http_error.py +0 -0
  16. {influxdb3_python-0.14.0 → influxdb3_python-0.16.0}/Examples/handle_query_error.py +0 -0
  17. {influxdb3_python-0.14.0 → influxdb3_python-0.16.0}/Examples/pandas_write.py +0 -0
  18. {influxdb3_python-0.14.0 → influxdb3_python-0.16.0}/Examples/query_async.py +0 -0
  19. {influxdb3_python-0.14.0 → influxdb3_python-0.16.0}/Examples/query_type.py +0 -0
  20. {influxdb3_python-0.14.0 → influxdb3_python-0.16.0}/LICENSE +0 -0
  21. {influxdb3_python-0.14.0 → influxdb3_python-0.16.0}/influxdb3_python.egg-info/SOURCES.txt +0 -0
  22. {influxdb3_python-0.14.0 → influxdb3_python-0.16.0}/influxdb3_python.egg-info/dependency_links.txt +0 -0
  23. {influxdb3_python-0.14.0 → influxdb3_python-0.16.0}/influxdb3_python.egg-info/requires.txt +0 -0
  24. {influxdb3_python-0.14.0 → influxdb3_python-0.16.0}/influxdb3_python.egg-info/top_level.txt +0 -0
  25. {influxdb3_python-0.14.0 → influxdb3_python-0.16.0}/influxdb_client_3/exceptions/__init__.py +0 -0
  26. {influxdb3_python-0.14.0 → influxdb3_python-0.16.0}/influxdb_client_3/exceptions/exceptions.py +0 -0
  27. {influxdb3_python-0.14.0 → influxdb3_python-0.16.0}/influxdb_client_3/py.typed +0 -0
  28. {influxdb3_python-0.14.0 → influxdb3_python-0.16.0}/influxdb_client_3/query/__init__.py +0 -0
  29. {influxdb3_python-0.14.0 → influxdb3_python-0.16.0}/influxdb_client_3/query/query_api.py +0 -0
  30. {influxdb3_python-0.14.0 → influxdb3_python-0.16.0}/influxdb_client_3/read_file.py +0 -0
  31. {influxdb3_python-0.14.0 → influxdb3_python-0.16.0}/influxdb_client_3/write_client/__init__.py +0 -0
  32. {influxdb3_python-0.14.0 → influxdb3_python-0.16.0}/influxdb_client_3/write_client/_sync/__init__.py +0 -0
  33. {influxdb3_python-0.14.0 → influxdb3_python-0.16.0}/influxdb_client_3/write_client/_sync/api_client.py +0 -0
  34. {influxdb3_python-0.14.0 → influxdb3_python-0.16.0}/influxdb_client_3/write_client/_sync/rest.py +0 -0
  35. {influxdb3_python-0.14.0 → influxdb3_python-0.16.0}/influxdb_client_3/write_client/client/__init__.py +0 -0
  36. {influxdb3_python-0.14.0 → influxdb3_python-0.16.0}/influxdb_client_3/write_client/client/_base.py +0 -0
  37. {influxdb3_python-0.14.0 → influxdb3_python-0.16.0}/influxdb_client_3/write_client/client/influxdb_client.py +0 -0
  38. {influxdb3_python-0.14.0 → influxdb3_python-0.16.0}/influxdb_client_3/write_client/client/logging_handler.py +0 -0
  39. {influxdb3_python-0.14.0 → influxdb3_python-0.16.0}/influxdb_client_3/write_client/client/util/__init__.py +0 -0
  40. {influxdb3_python-0.14.0 → influxdb3_python-0.16.0}/influxdb_client_3/write_client/client/util/date_utils.py +0 -0
  41. {influxdb3_python-0.14.0 → influxdb3_python-0.16.0}/influxdb_client_3/write_client/client/util/date_utils_pandas.py +0 -0
  42. {influxdb3_python-0.14.0 → influxdb3_python-0.16.0}/influxdb_client_3/write_client/client/util/helpers.py +0 -0
  43. {influxdb3_python-0.14.0 → influxdb3_python-0.16.0}/influxdb_client_3/write_client/client/util/multiprocessing_helper.py +0 -0
  44. {influxdb3_python-0.14.0 → influxdb3_python-0.16.0}/influxdb_client_3/write_client/client/warnings.py +0 -0
  45. {influxdb3_python-0.14.0 → influxdb3_python-0.16.0}/influxdb_client_3/write_client/client/write/__init__.py +0 -0
  46. {influxdb3_python-0.14.0 → influxdb3_python-0.16.0}/influxdb_client_3/write_client/client/write/dataframe_serializer.py +0 -0
  47. {influxdb3_python-0.14.0 → influxdb3_python-0.16.0}/influxdb_client_3/write_client/client/write/point.py +0 -0
  48. {influxdb3_python-0.14.0 → influxdb3_python-0.16.0}/influxdb_client_3/write_client/client/write/polars_dataframe_serializer.py +0 -0
  49. {influxdb3_python-0.14.0 → influxdb3_python-0.16.0}/influxdb_client_3/write_client/client/write/retry.py +0 -0
  50. {influxdb3_python-0.14.0 → influxdb3_python-0.16.0}/influxdb_client_3/write_client/client/write_api.py +0 -0
  51. {influxdb3_python-0.14.0 → influxdb3_python-0.16.0}/influxdb_client_3/write_client/configuration.py +0 -0
  52. {influxdb3_python-0.14.0 → influxdb3_python-0.16.0}/influxdb_client_3/write_client/domain/__init__.py +0 -0
  53. {influxdb3_python-0.14.0 → influxdb3_python-0.16.0}/influxdb_client_3/write_client/domain/write_precision.py +0 -0
  54. {influxdb3_python-0.14.0 → influxdb3_python-0.16.0}/influxdb_client_3/write_client/domain/write_precision_converter.py +0 -0
  55. {influxdb3_python-0.14.0 → influxdb3_python-0.16.0}/influxdb_client_3/write_client/extras.py +0 -0
  56. {influxdb3_python-0.14.0 → influxdb3_python-0.16.0}/influxdb_client_3/write_client/rest.py +0 -0
  57. {influxdb3_python-0.14.0 → influxdb3_python-0.16.0}/influxdb_client_3/write_client/service/__init__.py +0 -0
  58. {influxdb3_python-0.14.0 → influxdb3_python-0.16.0}/influxdb_client_3/write_client/service/_base_service.py +0 -0
  59. {influxdb3_python-0.14.0 → influxdb3_python-0.16.0}/influxdb_client_3/write_client/service/signin_service.py +0 -0
  60. {influxdb3_python-0.14.0 → influxdb3_python-0.16.0}/influxdb_client_3/write_client/service/signout_service.py +0 -0
  61. {influxdb3_python-0.14.0 → influxdb3_python-0.16.0}/influxdb_client_3/write_client/service/write_service.py +0 -0
  62. {influxdb3_python-0.14.0 → influxdb3_python-0.16.0}/pyproject.toml +0 -0
  63. {influxdb3_python-0.14.0 → influxdb3_python-0.16.0}/setup.cfg +0 -0
  64. {influxdb3_python-0.14.0 → influxdb3_python-0.16.0}/setup.py +0 -0
  65. {influxdb3_python-0.14.0 → influxdb3_python-0.16.0}/tests/test_api_client.py +0 -0
  66. {influxdb3_python-0.14.0 → influxdb3_python-0.16.0}/tests/test_dataframe_serializer.py +0 -0
  67. {influxdb3_python-0.14.0 → influxdb3_python-0.16.0}/tests/test_date_helper.py +0 -0
  68. {influxdb3_python-0.14.0 → influxdb3_python-0.16.0}/tests/test_deep_merge.py +0 -0
  69. {influxdb3_python-0.14.0 → influxdb3_python-0.16.0}/tests/test_merge_options.py +0 -0
  70. {influxdb3_python-0.14.0 → influxdb3_python-0.16.0}/tests/test_point.py +0 -0
  71. {influxdb3_python-0.14.0 → influxdb3_python-0.16.0}/tests/test_polars.py +0 -0
  72. {influxdb3_python-0.14.0 → influxdb3_python-0.16.0}/tests/test_query.py +0 -0
  73. {influxdb3_python-0.14.0 → influxdb3_python-0.16.0}/tests/test_write_file.py +0 -0
  74. {influxdb3_python-0.14.0 → influxdb3_python-0.16.0}/tests/test_write_local_server.py +0 -0
  75. {influxdb3_python-0.14.0 → influxdb3_python-0.16.0}/tests/test_write_precision_converter.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: influxdb3-python
3
- Version: 0.14.0
3
+ Version: 0.16.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
@@ -209,6 +209,11 @@ table = reader.read_all()
209
209
  print(table.to_pandas().to_markdown())
210
210
  ```
211
211
 
212
+ ### gRPC compression
213
+ The Python client supports gRPC response compression.
214
+ If the server chooses to compress query responses (e.g., with gzip), the client
215
+ will automatically decompress them — no extra configuration is required.
216
+
212
217
  ## Windows Users
213
218
  Currently, Windows users require an extra installation when querying via Flight natively. This is due to the fact gRPC cannot locate Windows root certificates. To work around this please follow these steps:
214
219
  Install `certifi`
@@ -242,6 +247,8 @@ print(table.to_pandas())
242
247
  ```
243
248
  You may also include your own root certificate via this manor aswell.
244
249
 
250
+ If connecting to InfluxDB fails with error `DNS resolution failed` when using domain name, example `www.mydomain.com`, then try to set environment variable `GRPC_DNS_RESOLVER=native` to see if it works.
251
+
245
252
  # Contributing
246
253
 
247
254
  Tests are run using `pytest`.
@@ -162,6 +162,11 @@ table = reader.read_all()
162
162
  print(table.to_pandas().to_markdown())
163
163
  ```
164
164
 
165
+ ### gRPC compression
166
+ The Python client supports gRPC response compression.
167
+ If the server chooses to compress query responses (e.g., with gzip), the client
168
+ will automatically decompress them — no extra configuration is required.
169
+
165
170
  ## Windows Users
166
171
  Currently, Windows users require an extra installation when querying via Flight natively. This is due to the fact gRPC cannot locate Windows root certificates. To work around this please follow these steps:
167
172
  Install `certifi`
@@ -195,6 +200,8 @@ print(table.to_pandas())
195
200
  ```
196
201
  You may also include your own root certificate via this manor aswell.
197
202
 
203
+ If connecting to InfluxDB fails with error `DNS resolution failed` when using domain name, example `www.mydomain.com`, then try to set environment variable `GRPC_DNS_RESOLVER=native` to see if it works.
204
+
198
205
  # Contributing
199
206
 
200
207
  Tests are run using `pytest`.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: influxdb3-python
3
- Version: 0.14.0
3
+ Version: 0.16.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
@@ -209,6 +209,11 @@ table = reader.read_all()
209
209
  print(table.to_pandas().to_markdown())
210
210
  ```
211
211
 
212
+ ### gRPC compression
213
+ The Python client supports gRPC response compression.
214
+ If the server chooses to compress query responses (e.g., with gzip), the client
215
+ will automatically decompress them — no extra configuration is required.
216
+
212
217
  ## Windows Users
213
218
  Currently, Windows users require an extra installation when querying via Flight natively. This is due to the fact gRPC cannot locate Windows root certificates. To work around this please follow these steps:
214
219
  Install `certifi`
@@ -242,6 +247,8 @@ print(table.to_pandas())
242
247
  ```
243
248
  You may also include your own root certificate via this manor aswell.
244
249
 
250
+ If connecting to InfluxDB fails with error `DNS resolution failed` when using domain name, example `www.mydomain.com`, then try to set environment variable `GRPC_DNS_RESOLVER=native` to see if it works.
251
+
245
252
  # Contributing
246
253
 
247
254
  Tests are run using `pytest`.
@@ -467,6 +467,33 @@ class InfluxDBClient3:
467
467
  except ArrowException as e:
468
468
  raise InfluxDB3ClientQueryError(f"Error while executing query: {e}")
469
469
 
470
+ def get_server_version(self) -> str:
471
+ """
472
+ Get the version of the connected InfluxDB server.
473
+
474
+ This method makes a ping request to the server and extracts the version information
475
+ from either the response headers or response body.
476
+
477
+ :return: The version string of the InfluxDB server.
478
+ :rtype: str
479
+ """
480
+ version = None
481
+ (resp_body, _, header) = self._client.api_client.call_api(
482
+ resource_path="/ping",
483
+ method="GET",
484
+ response_type=object
485
+ )
486
+
487
+ for key, value in header.items():
488
+ if key.lower() == "x-influxdb-version":
489
+ version = value
490
+ break
491
+
492
+ if version is None and isinstance(resp_body, dict):
493
+ version = resp_body['version']
494
+
495
+ return version
496
+
470
497
  def close(self):
471
498
  """Close the client and clean up resources."""
472
499
  self._write_api.close()
@@ -1,4 +1,4 @@
1
1
  """Version of the Client that is used in User-Agent header."""
2
2
 
3
- VERSION = '0.14.0'
3
+ VERSION = '0.16.0'
4
4
  USER_AGENT = f'influxdb3-python/{VERSION}'
@@ -1,12 +1,22 @@
1
+ import re
1
2
  import unittest
2
3
  from unittest.mock import patch
3
4
 
5
+ from pytest_httpserver import HTTPServer
6
+
4
7
  from influxdb_client_3 import InfluxDBClient3, WritePrecision, DefaultWriteOptions, Point, WriteOptions, WriteType
5
8
  from influxdb_client_3.exceptions import InfluxDB3ClientQueryError
9
+ from influxdb_client_3.write_client.rest import ApiException
6
10
  from tests.util import asyncio_run
7
11
  from tests.util.mocks import ConstantFlightServer, ConstantData, ErrorFlightServer
8
12
 
9
13
 
14
+ def http_server():
15
+ httpserver = HTTPServer()
16
+ httpserver.start()
17
+ return httpserver
18
+
19
+
10
20
  class TestInfluxDBClient3(unittest.TestCase):
11
21
 
12
22
  @patch('influxdb_client_3._InfluxDBClient')
@@ -22,6 +32,11 @@ class TestInfluxDBClient3(unittest.TestCase):
22
32
  database="my_db",
23
33
  token="my_token"
24
34
  )
35
+ self.http_server = http_server()
36
+
37
+ def tearDown(self):
38
+ if self.http_server is not None:
39
+ self.http_server.stop()
25
40
 
26
41
  def test_init(self):
27
42
  self.assertEqual(self.client._org, "my_org")
@@ -226,6 +241,49 @@ class TestInfluxDBClient3(unittest.TestCase):
226
241
  await c.query_async("SELECT * FROM my_data")
227
242
  self.assertIn("Error while executing query", str(err.exception))
228
243
 
244
+ def test_get_version_header_success(self):
245
+ server = self.http_server
246
+ server.expect_request(re.compile(".*")).respond_with_json(
247
+ headers={"X-Influxdb-Version": "1.8.2"},
248
+ response_json={"version": "3.0"}
249
+ )
250
+ version = InfluxDBClient3(
251
+ host=f'http://{server.host}:{server.port}', org="ORG", database="DB", token="TOKEN"
252
+ ).get_server_version()
253
+ assert version == "1.8.2"
254
+
255
+ def test_get_version_in_body_success(self):
256
+ server = self.http_server
257
+ server.expect_request('/ping').respond_with_json(
258
+ response_json={"version": "3.0"},
259
+ )
260
+ version = InfluxDBClient3(
261
+ host=f'http://{server.host}:{server.port}', org="ORG", database="DB", token="TOKEN"
262
+ ).get_server_version()
263
+ assert version == "3.0"
264
+
265
+ def test_get_version_empty(self):
266
+ server = self.http_server
267
+ server.expect_request("/ping").respond_with_data(
268
+ headers={"abc": "1.8.2"},
269
+ )
270
+
271
+ version = InfluxDBClient3(
272
+ host=f'http://{server.host}:{server.port}', org="ORG", database="DB", token="TOKEN"
273
+ ).get_server_version()
274
+ assert version is None
275
+
276
+ def test_get_version_fail(self):
277
+ server = self.http_server
278
+ server.expect_request("/ping").respond_with_json(
279
+ response_json={"error": "error"},
280
+ status=400
281
+ )
282
+ with self.assertRaises(ApiException):
283
+ InfluxDBClient3(
284
+ host=f'http://{server.host}:{server.port}', org="ORG", database="DB", token="TOKEN"
285
+ ).get_server_version()
286
+
229
287
 
230
288
  if __name__ == '__main__':
231
289
  unittest.main()
@@ -1,15 +1,14 @@
1
1
  import logging
2
2
  import os
3
+ import pyarrow
4
+ import pytest
3
5
  import random
4
6
  import string
5
7
  import time
6
8
  import unittest
7
9
 
8
- import pyarrow
9
- import pytest
10
- from influxdb_client_3.exceptions import InfluxDB3ClientQueryError, InfluxDBError
11
-
12
10
  from influxdb_client_3 import InfluxDBClient3, write_client_options, WriteOptions
11
+ from influxdb_client_3.exceptions import InfluxDBError
13
12
  from tests.util import asyncio_run, lp_to_py_object
14
13
 
15
14
 
@@ -64,30 +63,18 @@ class TestInfluxDBClient3Integration(unittest.TestCase):
64
63
  test_id = time.time_ns()
65
64
  with self.assertRaises(InfluxDBError) as err:
66
65
  self.client.write(f"integration_test_python,type=used value=123.0,test_id={test_id}i")
67
- self.assertEqual('unauthorized access', err.exception.message) # Cloud
66
+ self.assertEqual('Authorization header was malformed, the request was not in the form of '
67
+ '\'Authorization: <auth-scheme> <token>\', supported auth-schemes are Bearer, Token and Basic',
68
+ err.exception.message) # Cloud
68
69
 
69
70
  def test_auth_error_auth_scheme(self):
70
71
  self.client = InfluxDBClient3(host=self.host, database=self.database, token=self.token, auth_scheme='Any')
71
72
  test_id = time.time_ns()
72
73
  with self.assertRaises(InfluxDBError) as err:
73
74
  self.client.write(f"integration_test_python,type=used value=123.0,test_id={test_id}i")
74
- self.assertEqual('unauthorized access', err.exception.message) # Cloud
75
-
76
- def test_error_headers(self):
77
- self.client = InfluxDBClient3(host=self.host, database=self.database, token=self.token)
78
- with self.assertRaises(InfluxDBError) as err:
79
- self.client.write("integration_test_python,type=used value=123.0,test_id=")
80
- self.assertIn("Could not parse entire line. Found trailing content:", err.exception.message)
81
- headers = err.exception.getheaders()
82
- try:
83
- self.assertIsNotNone(headers)
84
- self.assertRegex(headers['trace-id'], '[0-9a-f]{16}')
85
- self.assertEqual('false', headers['trace-sampled'])
86
- self.assertIsNotNone(headers['Strict-Transport-Security'])
87
- self.assertRegex(headers['X-Influxdb-Request-ID'], '[0-9a-f]+')
88
- self.assertIsNotNone(headers['X-Influxdb-Build'])
89
- except KeyError as ke:
90
- self.fail(f'Header {ke} not found')
75
+ self.assertEqual('Authorization header was malformed, the request was not in the form of '
76
+ '\'Authorization: <auth-scheme> <token>\', supported auth-schemes are Bearer, Token and Basic',
77
+ err.exception.message) # Cloud
91
78
 
92
79
  def test_batch_write_callbacks(self):
93
80
  write_success = False
@@ -212,24 +199,6 @@ IdKIRUY6EyIVG+Z/nbuVqUlgnIWOMp0yg4RRC91zHy3Xvykf3Vai25H/jQpa6cbU
212
199
  def remove_test_cert(self, cert_file):
213
200
  os.remove(cert_file)
214
201
 
215
- def test_queries_w_bad_cert(self):
216
- cert_file = "test_cert.pem"
217
- self.create_test_cert(cert_file)
218
- with InfluxDBClient3(host=self.host,
219
- database=self.database,
220
- token=self.token,
221
- verify_ssl=True,
222
- ssl_ca_cert=cert_file,
223
- debug=True) as client:
224
- try:
225
- query = "SELECT table_name FROM information_schema.tables"
226
- client.query(query, mode="")
227
- assert False, "query should throw SSL_ERROR"
228
- except InfluxDB3ClientQueryError as fe:
229
- assert str(fe).__contains__('SSL_ERROR_SSL')
230
- finally:
231
- self.remove_test_cert(cert_file)
232
-
233
202
  def test_verify_ssl_false(self):
234
203
  cert_file = "test_cert.pem"
235
204
  self.create_test_cert(cert_file)
@@ -274,3 +243,7 @@ IdKIRUY6EyIVG+Z/nbuVqUlgnIWOMp0yg4RRC91zHy3Xvykf3Vai25H/jQpa6cbU
274
243
  result_list = result.to_pylist()
275
244
  for item in data:
276
245
  assert lp_to_py_object(item) in result_list, f"original lp data \"{item}\" should be in result list"
246
+
247
+ def test_get_server_version(self):
248
+ version = self.client.get_server_version()
249
+ assert version is not None