Skip to content

refactor: rest client#217

Draft
NguyenHoangSon96 wants to merge 13 commits into
mainfrom
refactor/rest-client
Draft

refactor: rest client#217
NguyenHoangSon96 wants to merge 13 commits into
mainfrom
refactor/rest-client

Conversation

@NguyenHoangSon96

@NguyenHoangSon96 NguyenHoangSon96 commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

Closes #216

Proposed Changes

  • I'm trying to make python3 similar to other v3 clients as possible, so I removed some functionalities that currently don't exist in other clients.

Summarize

  • RestClient will be created in InfluxDBClient3 and injected to WriteApi; WriteApi will have all functions to write to Influxdb -> InfluxDBClient3 -> WriteApi -> RestClient.

Removed features:

  • Debug.
  • org_id - only allow org name.
  • _return_http_data_only param.
  • zap-trace-span param.
  • _preload_content

Checklist

  • CHANGELOG.md updated
  • Rebased/mergeable
  • A test has been added if appropriate
  • Tests pass
  • Commit messages are conventional
  • Sign CLA (if not already signed)

@NguyenHoangSon96 NguyenHoangSon96 self-assigned this Jun 12, 2026
Copilot AI review requested due to automatic review settings June 12, 2026 15:16

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR refactors the write path to use a new synchronous RestClient (urllib3-based) instead of the previous generated client/write service wiring, and updates InfluxDBClient3 construction accordingly.

Changes:

  • Refactors WriteApi to issue HTTP requests via a new RestClient, adds gzip decision/compression utilities, and adds endpoint/exception translation logic.
  • Introduces influxdb_client_3/write_client/_sync/rest_client.py to encapsulate urllib3 request/response handling.
  • Updates InfluxDBClient3 initialization to pass write connection details (base_url/auth/gzip) directly into WriteApi.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 15 comments.

File Description
influxdb_client_3/write_client/client/write_api.py Major refactor of write implementation to use a new REST client and custom request building/serialization paths.
influxdb_client_3/write_client/_sync/rest_client.py Adds a new urllib3-based synchronous REST client abstraction used by WriteApi.
influxdb_client_3/__init__.py Wires new write API constructor parameters (auth/gzip/base_url) and updates public kwargs documentation.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread influxdb_client_3/write_client/client/write_api.py Outdated
Comment thread influxdb_client_3/write_client/client/write_api.py Outdated
Comment thread influxdb_client_3/write_client/client/write_api.py Outdated
Comment thread influxdb_client_3/write_client/client/write_api.py Outdated
Comment thread influxdb_client_3/write_client/client/write_api.py Outdated
Comment thread influxdb_client_3/write_client/_sync/rest_client.py Outdated
Comment thread influxdb_client_3/__init__.py Outdated
Comment thread influxdb_client_3/write_client/client/write_api.py Outdated
Comment thread influxdb_client_3/write_client/client/write_api.py Outdated
Comment thread influxdb_client_3/write_client/client/write_api.py Outdated

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 19 out of 19 changed files in this pull request and generated 12 comments.

Comments suppressed due to low confidence (2)

tests/test_write_api.py:251

  • WriteApi.write() takes parameters in (bucket, org, record, ...) order, but this test passes (org, bucket, record). This makes the test less representative of real usage and can mask issues in how query parameters are constructed.
    tests/test_write_api.py:293
  • This call passes (org, bucket, record) instead of (bucket, org, record), which makes the timeout test less representative of real usage and inconsistent with other tests in this file.

Comment thread influxdb_client_3/write_client/client/write_api.py
Comment thread influxdb_client_3/write_client/client/write_api.py Outdated
Comment thread influxdb_client_3/write_client/client/write_api.py
Comment thread influxdb_client_3/write_client/_sync/rest_client.py Outdated
Comment thread influxdb_client_3/__init__.py Outdated
Comment thread .circleci/config.yml
Comment thread influxdb_client_3/write_client/_sync/rest_client.py Outdated
Comment thread influxdb_client_3/write_client/_sync/rest_client.py Outdated
Comment thread influxdb_client_3/write_client/_sync/rest_client.py Outdated
Comment thread influxdb_client_3/write_client/_sync/rest_client.py

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 19 out of 19 changed files in this pull request and generated 2 comments.

Comments suppressed due to low confidence (4)

influxdb_client_3/write_client/client/write_api.py:1171

  • __getstate__ deletes _write_service, but WriteApi no longer defines that attribute. This will raise KeyError during pickling (and del state['_subject'] / del state['_disposable'] can also KeyError depending on instance state). Use state.pop(..., None) and remove the stale _write_service reference.
    def __getstate__(self):
        """Return a dict of attributes that you want to pickle."""
        state = self.__dict__.copy()
        # Remove rx
        del state['_subject']
        del state['_disposable']
        del state['_write_service']
        return state

influxdb_client_3/write_client/client/write_api.py:1181

  • __setstate__ calls self.__init__(self._write_options, self._point_settings, ...), but WriteApi.__init__ requires token, bucket, and org as the first arguments. As written, unpickling will raise TypeError. Recreate the Rx batching pipeline based on the restored _write_options instead of re-calling __init__ with the wrong signature.
    def __setstate__(self, state):
        """Set your object with the provided dict."""
        self.__dict__.update(state)
        # Init Rx
        self.__init__(self._write_options,
                      self._point_settings,
                      success_callback=self._success_callback,
                      error_callback=self._error_callback,
                      retry_callback=self._retry_callback)

tests/test_write_api.py:252

  • WriteApi.write() expects positional arguments in the order (bucket, org, record). This call passes org first, which swaps the query parameters and makes the test less representative of real usage. Use keyword arguments (or correct positional order) to avoid accidental swaps.
    tests/test_write_api.py:293
  • WriteApi.write() positional argument order is (bucket, org, record). This test passes org then bucket, which is easy to get wrong and can hide routing/query-param bugs. Prefer keyword arguments to make the intent explicit (and keep _request_timeout behavior under test).

Comment thread influxdb_client_3/__init__.py
Comment thread influxdb_client_3/__init__.py

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 19 out of 19 changed files in this pull request and generated 2 comments.

Comments suppressed due to low confidence (5)

tests/test_write_api.py:29

  • mock_urllib3_timeout_request is used as a side_effect for urllib3._request_methods.RequestMethods.request, which passes the RequestMethods instance as the first positional arg. The helper currently omits that parameter, so method/url are shifted and the test can behave incorrectly.
    tests/test_write_api.py:252
  • WriteApi.write() takes bucket as the first positional argument and org as the second. This call passes them in the opposite order, so the request routing/query params will be wrong.
    tests/test_write_api.py:293
  • WriteApi.write() takes bucket as the first positional argument and org as the second. This call passes them in the opposite order, so it won't exercise the intended timeout behavior for the right endpoint params.
    influxdb_client_3/write_client/client/write_api.py:1171
  • __getstate__ deletes state['_write_service'], but this class no longer defines _write_service. Pickling will raise KeyError here.
        state = self.__dict__.copy()
        # Remove rx
        del state['_subject']
        del state['_disposable']
        del state['_write_service']
        return state

influxdb_client_3/write_client/client/write_api.py:1181

  • __setstate__ calls self.__init__(self._write_options, self._point_settings, ...), but __init__ now requires token, bucket, org, and other constructor args. This will break unpickling; it should just recreate the Rx batching pipeline based on the restored _write_options.
    def __setstate__(self, state):
        """Set your object with the provided dict."""
        self.__dict__.update(state)
        # Init Rx
        self.__init__(self._write_options,
                      self._point_settings,
                      success_callback=self._success_callback,
                      error_callback=self._error_callback,
                      retry_callback=self._retry_callback)

Comment thread influxdb_client_3/write_client/client/write_api.py
Comment thread influxdb_client_3/__init__.py

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 19 out of 19 changed files in this pull request and generated 2 comments.

Comments suppressed due to low confidence (3)

tests/test_write_api.py:252

  • WriteApi.write() takes positional arguments in the order (bucket, org, record). This call passes org first and bucket second, which swaps routing parameters and can hide bugs in header/query handling. Prefer keyword arguments (or swap the positionals) to make the intent unambiguous.
    tests/test_write_api.py:293
  • Same positional-argument issue as above: this passes org first and bucket second to WriteApi.write(bucket, org, record), which inverts query parameters. Using keywords also makes the _request_timeout intent clearer.
    influxdb_client_3/write_client/client/write_api.py:1181
  • __getstate__ / __setstate__ are broken after the refactor: _write_service is no longer an attribute, so del state['_write_service'] will raise KeyError during pickling. Additionally, __setstate__ calls __init__ with the wrong arguments for the new constructor signature (it no longer accepts just write_options and point_settings). This makes pickling/unpickling unusable.
    def __getstate__(self):
        """Return a dict of attributes that you want to pickle."""
        state = self.__dict__.copy()
        # Remove rx
        del state['_subject']
        del state['_disposable']
        del state['_write_service']
        return state

    def __setstate__(self, state):
        """Set your object with the provided dict."""
        self.__dict__.update(state)
        # Init Rx
        self.__init__(self._write_options,
                      self._point_settings,
                      success_callback=self._success_callback,
                      error_callback=self._error_callback,
                      retry_callback=self._retry_callback)

Comment thread influxdb_client_3/write_client/client/write_api.py
Comment thread influxdb_client_3/__init__.py Outdated

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 19 out of 19 changed files in this pull request and generated 2 comments.

Comments suppressed due to low confidence (3)

influxdb_client_3/write_client/client/write_api.py:1181

  • __getstate__ deletes state['_write_service'], but WriteApi no longer defines _write_service, so pickling will raise KeyError. Additionally, __setstate__ calls __init__ with the wrong signature (it now requires token, bucket, org, etc.), so unpickling will fail even if __getstate__ succeeds. Safer approach: pop() optional fields and recreate the Rx pipeline based on _write_options without re-calling __init__.
    def __getstate__(self):
        """Return a dict of attributes that you want to pickle."""
        state = self.__dict__.copy()
        # Remove rx
        del state['_subject']
        del state['_disposable']
        del state['_write_service']
        return state

    def __setstate__(self, state):
        """Set your object with the provided dict."""
        self.__dict__.update(state)
        # Init Rx
        self.__init__(self._write_options,
                      self._point_settings,
                      success_callback=self._success_callback,
                      error_callback=self._error_callback,
                      retry_callback=self._retry_callback)

tests/test_write_api.py:252

  • WriteApi.write() expects positional arguments as (bucket, org, record, ...), but this test passes them as (org, bucket, record). That swaps query params and makes the test exercise the wrong behavior. Use keyword args (or correct positional order) to match the write() signature.
    tests/test_write_api.py:294
  • This write() call also swaps (org, bucket) positional order. Since the assertion is about timeout propagation rather than parameter order, using keyword args avoids accidentally testing the wrong thing.

Comment thread influxdb_client_3/write_client/client/write_api.py
Comment thread influxdb_client_3/write_client/_sync/rest_client.py

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 19 out of 19 changed files in this pull request and generated 3 comments.

Comments suppressed due to low confidence (2)

tests/test_write_api.py:252

  • In this test, WriteApi.write() expects positional args in the order (bucket, org, record). Passing org first swaps the routing parameters and can hide bugs in request construction/error handling.
    tests/test_write_api.py:293
  • WriteApi.write() positional parameters are (bucket, org, record). This call passes org first, which makes the test exercise the wrong request routing.

Comment thread influxdb_client_3/write_client/client/write_api.py
Comment thread influxdb_client_3/write_client/client/write_api.py
Comment thread influxdb_client_3/__init__.py

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 19 out of 19 changed files in this pull request and generated 3 comments.

Comments suppressed due to low confidence (3)

influxdb_client_3/write_client/client/write_api.py:1179

  • __getstate__() deletes _write_service, but WriteApi no longer sets this attribute, so pickling will raise KeyError. Additionally, __setstate__() calls __init__() with the wrong signature (it now requires token/bucket/org/...).
    def __getstate__(self):
        """Return a dict of attributes that you want to pickle."""
        state = self.__dict__.copy()
        # Remove rx
        del state['_subject']
        del state['_disposable']
        del state['_write_service']
        return state

    def __setstate__(self, state):
        """Set your object with the provided dict."""
        self.__dict__.update(state)
        # Init Rx
        self.__init__(self._write_options,
                      self._point_settings,
                      success_callback=self._success_callback,
                      error_callback=self._error_callback,
                      retry_callback=self._retry_callback)

tests/test_write_api.py:252

  • Argument order is swapped in this write() call: WriteApi.write(bucket, org, record, ...) expects bucket first, org second, but this passes org then bucket. This makes the test less meaningful and can hide real regressions.
    tests/test_write_api.py:293
  • Argument order is swapped in this write() call: WriteApi.write(bucket, org, record, ...) expects bucket first, org second. As written, the test exercises the wrong parameter mapping (and still "works" only because values are strings).

Comment thread influxdb_client_3/write_client/client/write_api.py
Comment thread influxdb_client_3/write_client/__init__.py
Comment thread influxdb_client_3/write_client/client/write_api.py
@codecov

codecov Bot commented Jun 18, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 86.05898% with 52 lines in your changes missing coverage. Please review.
✅ Project coverage is 83.96%. Comparing base (a022daa) to head (7c2972b).

Files with missing lines Patch % Lines
influxdb_client_3/write_client/client/write_api.py 85.29% 40 Missing ⚠️
...nfluxdb_client_3/write_client/_sync/rest_client.py 88.73% 8 Missing ⚠️
...write_client/client/util/multiprocessing_helper.py 33.33% 4 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #217      +/-   ##
==========================================
+ Coverage   78.90%   83.96%   +5.05%     
==========================================
  Files          36       28       -8     
  Lines        2607     2014     -593     
==========================================
- Hits         2057     1691     -366     
+ Misses        550      323     -227     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@NguyenHoangSon96 NguyenHoangSon96 force-pushed the refactor/rest-client branch 3 times, most recently from d4ed5f3 to 6e100f8 Compare June 19, 2026 03:19
@NguyenHoangSon96 NguyenHoangSon96 force-pushed the refactor/rest-client branch 2 times, most recently from 166cec0 to 1313ede Compare June 22, 2026 08:19

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 20 out of 20 changed files in this pull request and generated 6 comments.

Comments suppressed due to low confidence (2)

tests/test_write_api.py:252

  • WriteApi.write() expects (bucket, org, record) (see examples in write_api.py). This test passes org/bucket in the opposite order, which makes the call misleading and can hide parameter-order bugs. Prefer keyword arguments here to make the intent explicit.
    tests/test_write_api.py:294
  • WriteApi.write() expects (bucket, org, record). This call passes org/bucket in the opposite order; using keyword args avoids accidentally swapping them when adding _request_timeout.

Comment thread influxdb_client_3/write_client/client/write_api.py
Comment thread influxdb_client_3/__init__.py Outdated
Comment thread influxdb_client_3/__init__.py Outdated
Comment thread influxdb_client_3/__init__.py
Comment thread influxdb_client_3/write_client/client/write_api.py
Comment thread influxdb_client_3/write_client/client/write_api.py

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 20 out of 20 changed files in this pull request and generated 1 comment.

Comments suppressed due to low confidence (4)

influxdb_client_3/write_client/client/write_api.py:362

  • WriteApi.__init__ initializes self._write_options with a default when write_options is None, but then immediately overwrites it with the raw write_options argument. When write_options is omitted, this sets self._write_options back to None, and later attribute access (for example self._write_options.write_type) will fail.
        self._point_settings = point_settings if point_settings is not None else PointSettings()
        self._write_options = write_options if write_options is not None else WriteOptions()

        self._write_options = write_options
        # TODO - callbacks seem to be used with batching type only - could they be used with sync or async?
        self._success_callback = kwargs.get('success_callback', None)
        self._error_callback = kwargs.get('error_callback', None)
        self._retry_callback = kwargs.get('retry_callback', None)

        if self._write_options.write_type is WriteType.batching:
            self._subject, self._disposable = self._create_batching_pipeline()

influxdb_client_3/write_client/client/write_api.py:1155

  • WriteApi.__getstate__ deletes _write_service, but this attribute is no longer defined on WriteApi. Pickling an instance will raise KeyError during __getstate__.
    def __getstate__(self):
        """Return a dict of attributes that you want to pickle."""
        state = self.__dict__.copy()
        # Remove rx
        del state['_subject']
        del state['_disposable']
        del state['_write_service']
        return state

tests/test_write_api.py:253

  • This call passes org and bucket positionally in the wrong order for WriteApi.write(bucket, org, record, ...), which can make the test exercise the wrong query parameters.
    tests/test_write_api.py:295
  • This call also swaps the positional bucket/org arguments for WriteApi.write(bucket, org, record, ...), which makes the test send org=bucket and bucket=org.

Comment on lines +514 to +525
try:
return await self.call_api(
resource_path=path,
method='POST',
query_params=query_params,
header_params=header_params,
body=body,
async_req=local_var_params.get('async_req'),
_request_timeout=local_var_params.get('_request_timeout'),
urlopen_kw=kwargs.get('urlopen_kw', None))
except ApiException as e:
raise self._translate_write_exception(e, use_v2_api)

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 20 out of 20 changed files in this pull request and generated 5 comments.

Comments suppressed due to low confidence (2)

tests/test_write_api.py:253

  • WriteApi.write() signature is (bucket, org, record, ...), but this test passes ("TEST_ORG", "TEST_BUCKET", ...), swapping bucket and org. This makes the test validate the wrong request parameters and may mask real issues.
    tests/test_write_api.py:294
  • This timeout test also swaps positional bucket/org arguments (write("TEST_ORG", "TEST_BUCKET", ...)). With the current WriteApi.write(bucket, org, record, ...) API, the correct order is bucket first, then org.

Comment on lines +67 to +70
try:
_HAS_DATACLASS = True
except ModuleNotFoundError:
_HAS_DATACLASS = False
Comment on lines +352 to 356
self._point_settings = point_settings if point_settings is not None else PointSettings()
self._write_options = write_options if write_options is not None else WriteOptions()

self._write_options = write_options
# TODO - callbacks seem to be used with batching type only - could they be used with sync or async?
Comment on lines 1158 to +1163
"""Set your object with the provided dict."""
self.__dict__.update(state)
# Init Rx
self.__init__(self._influxdb_client,
self._write_options,
self._point_settings,
self.__init__(token=self.token,
bucket=self.bucket,
org=self.org,
Comment on lines +47 to +49
# self.host = 'http://localhost:9000'
# self.token = 'apiv3_YFw5WFYo7m0m2A1dMV8J9SIViuPzTlvrGlF3kaQARM8efwjjdX7mrUJB6sEBC-ZIhIUr_VgeOGB96we0VtkYkw'
# self.database = 'bucket0'
Comment on lines 736 to 740
def close(self):
"""Close the client and clean up resources."""
self._write_api.close()
self._query_api.close()
self._client.close()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Refactor write HTTP stack: introduce internal _RestClient and bypass OpenAPI WriteService

2 participants