Skip to content

Commit ab75516

Browse files
refactor: multiprocess helper class
1 parent a022daa commit ab75516

25 files changed

Lines changed: 1340 additions & 2721 deletions

CHANGELOG.md

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,65 @@
22

33
## 0.21.0 [unreleased]
44

5+
### Breaking Changes
6+
7+
1. [#217](https://github.com/InfluxCommunity/influxdb3-python/pull/217): Make Write API simpler and consistent with other v3 clients.
8+
- Remove unused `InfluxLoggingHandler` class.
9+
- WriteApi now has all functions to write to InfluxDB. `Configuration`, `ApiClient`, `WriteService`, `InfluxDBClient` are no longer needed.
10+
All settings needed for writing now can be passed to the constructor of WriteApi.
11+
``` python
12+
import time
13+
from influxdb_client_3.write_client import WriteApi
14+
from influxdb_client_3.write_client._sync import rest_client
15+
from influxdb_client_3 import WriteOptions, write_client_options
16+
17+
default_header = {
18+
'Authorization': 'Token my-token'
19+
}
20+
rest = rest_client.RestClient(
21+
base_url='http://localhost:8181',
22+
default_header=default_header,
23+
verify_ssl=True,
24+
ssl_ca_cert=None,
25+
cert_file=None,
26+
cert_key_file=None,
27+
cert_key_password=None,
28+
ssl_context=None,
29+
proxy=None,
30+
proxy_headers=None,
31+
retries=False,
32+
debug=False,
33+
connection_pool_maxsize=25
34+
)
35+
36+
wco=write_client_options(write_options=WriteOptions(batch_size=100)))
37+
write_api = WriteApi(
38+
bucket='bucket_name',
39+
org='my-org',
40+
default_header=default_header,
41+
gzip_threshold=None,
42+
enable_gzip=False,
43+
auth_scheme='Token',
44+
timeout=None,
45+
rest_client=rest,
46+
point_settings=None,
47+
**wco
48+
)
49+
50+
test_id = time.time_ns()
51+
write_api.write(record=f"cpu,type=used ram=16,test_id={test_id}i")
52+
write_api.close()
53+
54+
```
55+
- rest_client.RestClient will now be responsible for low-level handling the HTTP requests.
56+
- `InfluxDBClient3` constructor will have additional parameters for configuring the RestClient and WriteApi.
57+
- auth_scheme,
58+
- enable_gzip,
59+
- gzip_threshold,
60+
- point_settings,
61+
- debug,
62+
- Refactor Multiprocessing helper class.
63+
564
## 0.20.0 [2026-06-11]
665

766
### Features

influxdb_client_3/__init__.py

Lines changed: 90 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,16 @@
1+
import multiprocessing
2+
13
import importlib.util
4+
import json
25
import os
36
import urllib.parse
47
from typing import Any, List, Literal, Optional, TYPE_CHECKING
58

69
import pyarrow as pa
710

11+
from influxdb_client_3.version import USER_AGENT
12+
from influxdb_client_3.write_client._sync import rest_client as rest
13+
814
if TYPE_CHECKING:
915
import pandas as pd
1016
import polars as pl
@@ -14,7 +20,7 @@
1420
from influxdb_client_3.exceptions import InfluxDBError
1521
from influxdb_client_3.query.query_api import QueryApi as _QueryApi, QueryApiOptionsBuilder
1622
from influxdb_client_3.read_file import UploadFile
17-
from influxdb_client_3.write_client import InfluxDBClient as _InfluxDBClient, WriteOptions, Point
23+
from influxdb_client_3.write_client import WriteOptions, Point
1824
from influxdb_client_3.write_client.client.write_api import WriteApi as _WriteApi, SYNCHRONOUS, ASYNCHRONOUS, \
1925
PointSettings, DefaultWriteOptions, WriteType
2026
from influxdb_client_3.write_client.domain.write_precision import WritePrecision
@@ -189,11 +195,16 @@ def __init__(
189195
org=None,
190196
database=None,
191197
token=None,
198+
auth_scheme=None,
199+
enable_gzip=False,
200+
gzip_threshold=None,
192201
write_client_options=None,
193202
flight_client_options=None,
194203
write_port_overwrite=None,
195204
query_port_overwrite=None,
196205
disable_grpc_compression=False,
206+
point_settings=None,
207+
debug=False,
197208
**kwargs):
198209
"""
199210
Initialize an InfluxDB client.
@@ -212,6 +223,14 @@ def __init__(
212223
:type flight_client_options: dict[str, any]
213224
:param disable_grpc_compression: Disable gRPC compression for Flight query responses. Default is False.
214225
:type disable_grpc_compression: bool
226+
:param point_settings The settings for Points
227+
:type point_settings: PointSettings
228+
:param debug: enable verbose logging of http requests
229+
:type debug: bool
230+
:param enable_gzip: Enable GZIP compression for write requests.
231+
:type enable_gzip: bool
232+
:param gzip_threshold: Minimum payload size (bytes) to trigger GZIP when enable_gzip is True.
233+
:type gzip_threshold: int
215234
:key auth_scheme: token authentication scheme. Set to "Bearer" for Edge.
216235
:key bool verify_ssl: Set this to false to skip verifying SSL certificate when calling API from https server.
217236
:key str ssl_ca_cert: Set this to customize the certificate file to verify the peer.
@@ -235,6 +254,10 @@ def __init__(
235254
:key bool write_no_sync: disable sync confirmation on V3 API endpoint writes.
236255
:key list[str] profilers: list of enabled Flux profilers
237256
"""
257+
for key in ["host", "token", "database"]:
258+
if locals().get(key) is None:
259+
raise Exception(f"The '{key}' key is required")
260+
238261
self._org = org if org is not None else "default"
239262
self._database = database
240263
self._token = token
@@ -293,14 +316,49 @@ def __init__(
293316
if write_port_overwrite is not None:
294317
port = write_port_overwrite
295318

296-
self._client = _InfluxDBClient(
297-
url=f"{scheme}://{hostname}:{port}",
298-
token=self._token,
319+
auth_schema = 'Token' if auth_scheme is None else auth_scheme
320+
default_header = {
321+
'User-Agent': USER_AGENT
322+
}
323+
if self._token is not None:
324+
default_header['Authorization'] = f'{auth_schema} {self._token}'
325+
self.base_url = f"{scheme}://{hostname}:{port}"
326+
self.default_header = default_header
327+
self.rest_client = rest.RestClient(
328+
base_url=self.base_url,
329+
default_header=default_header,
330+
verify_ssl=kwargs.get('verify_ssl', True),
331+
ssl_ca_cert=kwargs.get('ssl_ca_cert', None),
332+
cert_file=kwargs.get('cert_file', None),
333+
cert_key_file=kwargs.get('cert_key_file', None),
334+
cert_key_password=kwargs.get('cert_key_password', None),
335+
ssl_context=kwargs.get('ssl_context', None),
336+
proxy=kwargs.get('proxy', None),
337+
proxy_headers=kwargs.get('proxy_headers', None),
338+
retries=kwargs.get('retries', False),
339+
debug=debug,
340+
connection_pool_maxsize=kwargs.get('connection_pool_maxsize', multiprocessing.cpu_count() * 5,)
341+
)
342+
343+
if point_settings is None:
344+
point_settings = PointSettings()
345+
346+
# Keep WriteOptions.timeout in sync with the resolved write_timeout
347+
if isinstance(self._write_client_options, dict) and self._write_client_options.get("write_options") is not None:
348+
self._write_client_options["write_options"].timeout = write_timeout
349+
350+
self._write_api = _WriteApi(
351+
bucket=self._database,
299352
org=self._org,
353+
gzip_threshold=gzip_threshold,
354+
enable_gzip=enable_gzip,
355+
auth_scheme=auth_scheme,
300356
timeout=write_timeout,
301-
**kwargs)
302-
303-
self._write_api = _WriteApi(influxdb_client=self._client, **self._write_client_options)
357+
default_header=default_header,
358+
rest_client=self.rest_client,
359+
point_settings=point_settings,
360+
**self._write_client_options
361+
)
304362

305363
if query_port_overwrite is not None:
306364
port = query_port_overwrite
@@ -658,32 +716,31 @@ async def query_async(self, query: str, language: str = "sql", mode: str = "all"
658716
except ArrowException as e:
659717
raise InfluxDB3ClientQueryError(f"Error while executing query: {e}")
660718

661-
def get_server_version(self) -> str:
719+
def get_server_version(self) -> Optional[str]:
662720
"""
663-
Get the version of the connected InfluxDB server.
721+
Retrieves the server version by querying the designated endpoint and
722+
extracting the version information from either response headers or
723+
the response body.
664724
665-
This method makes a ping request to the server and extracts the version information
666-
from either the response headers or response body.
725+
This method interacts with a REST API endpoint to fetch the server's
726+
version details, which might be stored in a specific HTTP header or
727+
available in the response body as part of a JSON structure.
667728
668-
:return: The version string of the InfluxDB server.
669-
:rtype: str
729+
:return: The version string of the server if available, otherwise None.
730+
:rtype: Optional[str]
670731
"""
671-
version = None
672-
(resp_body, _, header) = self._client.api_client.call_api(
673-
resource_path="/ping",
674-
method="GET",
675-
response_type=object
676-
)
677-
678-
for key, value in header.items():
732+
resp = self.rest_client.request(path='/ping', method="GET", headers=self.default_header)
733+
for key, value in resp.getheaders().items():
679734
if key.lower() == "x-influxdb-version":
680-
version = value
681-
break
735+
return value
682736

683-
if version is None and isinstance(resp_body, dict):
684-
version = resp_body['version']
685-
686-
return version
737+
try:
738+
if resp.data is not None:
739+
return json.loads(resp.data).get("version")
740+
else:
741+
return None
742+
except (ValueError, TypeError):
743+
return None
687744

688745
def flush(self):
689746
"""
@@ -700,9 +757,12 @@ def flush(self):
700757

701758
def close(self):
702759
"""Close the client and clean up resources."""
703-
self._write_api.close()
704-
self._query_api.close()
705-
self._client.close()
760+
if self._write_api is not None:
761+
self._write_api.close()
762+
if self._query_api is not None:
763+
self._query_api.close()
764+
if self.rest_client is not None:
765+
self.rest_client.close()
706766

707767
def __enter__(self):
708768
return self

influxdb_client_3/write_client/__init__.py

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,9 @@
44

55
from __future__ import absolute_import
66

7-
from influxdb_client_3.write_client.client.write_api import WriteApi, WriteOptions
8-
from influxdb_client_3.write_client.client.influxdb_client import InfluxDBClient
9-
from influxdb_client_3.write_client.client.logging_handler import InfluxLoggingHandler
7+
from influxdb_client_3.version import VERSION
108
from influxdb_client_3.write_client.client.write.point import Point
11-
12-
from influxdb_client_3.write_client.service.write_service import WriteService
13-
9+
from influxdb_client_3.write_client.client.write_api import WriteApi, WriteOptions
1410
from influxdb_client_3.write_client.domain.write_precision import WritePrecision
1511

16-
from influxdb_client_3.write_client.configuration import Configuration
17-
from influxdb_client_3.version import VERSION
1812
__version__ = VERSION

0 commit comments

Comments
 (0)