Skip to content

refactor: rest client#217

Open
NguyenHoangSon96 wants to merge 20 commits into
mainfrom
refactor/rest-client
Open

refactor: rest client#217
NguyenHoangSon96 wants to merge 20 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, so their relations are something like this InfluxDBClient3 -> WriteApi -> RestClient.

Removed features:

  • _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 Outdated
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

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 21 out of 21 changed files in this pull request and generated 4 comments.

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 CHANGELOG.md 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 21 out of 21 changed files in this pull request and generated 3 comments.

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
@NguyenHoangSon96

Copy link
Copy Markdown
Contributor Author

Hi guys, based on Jakub's new comments, I have tried to work on the refactor of rest client first then working on Multiprocessing help class later.
I have fixed all "High" priorities issues from Copilot.
Please review this PR again. I don't want to continue trigger Copilot reviews because I don't want to drain all credits
like the last month.

@bednar bednar left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I found two remaining issues around pickle support.

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 21 out of 21 changed files in this pull request and generated 4 comments.

Comment thread influxdb_client_3/write_client/client/write_api.py
Comment thread influxdb_client_3/write_client/client/util/multiprocessing_helper.py Outdated
Comment thread influxdb_client_3/__init__.py
Comment thread influxdb_client_3/__init__.py
@NguyenHoangSon96

Copy link
Copy Markdown
Contributor Author

@bednar
I edited code based on your suggestions.
Additionally, I edited the code based on two new suggestions from Copilot.
#217 (comment)
#217 (comment)

@bednar bednar left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

One batching pickle regression remains.

Comment thread influxdb_client_3/write_client/client/write_api.py

@bednar bednar left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Two additional backward-compatibility requirements remain.

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

@bednar bednar left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The changelog needs to describe the public compatibility impact of this refactor.

Comment thread CHANGELOG.md 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 22 out of 22 changed files in this pull request and generated 6 comments.

Comment thread influxdb_client_3/write_client/_sync/rest_client.py
Comment thread influxdb_client_3/write_client/client/write_api.py
Comment thread influxdb_client_3/write_client/client/write_api.py
Comment thread CHANGELOG.md Outdated
Comment on lines +315 to +331
org = 'my-org'
writer = MultiprocessingWriter(
host=self.host,
database=self.database,
token=self.token,
org=org,
write_options=WriteOptions(batch_size=1))
writer.start()
measurement = f'test{random_hex(6)}'.lower()
for x in range(1, 10):
time.sleep(0.2)
writer.write(
bucket=self.database,
record=f"{measurement},tag=a value=\"number{x}\" {time.time_ns()}"
)
writer.__del__()

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Will fix this later.

Comment on lines 193 to 194
self.write_api.__del__()
self.write_api = None

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Will fix this later.

@bednar bednar left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Two debug compatibility issues remain in the new RestClient.

self.cert_file = cert_file
self.cert_key_file = cert_key_file
self.cert_key_password = cert_key_password
self.debug = debug

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This stores the debug flag, but it still does not enable the HTTP debug logger the way the previous Configuration.debug path did. On main, InfluxDBClient3(..., debug=True).write(...) sets influxdb_client.client.http to DEBUG, attaches the stdout handler, and emits the >>> Request/headers/body logs. With this PR the logger remains at WARNING, so the RestClient.log_*() calls are silent and debug=True still does not provide the existing low-level write HTTP debug output. Please have the new RestClient preserve the old debug=True behavior, including logger level/handler setup.

"""Set your object with the provided dict."""
self.__dict__.update(state)
# Init Pool manager
self.__init__(

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

RestClient.__setstate__() drops the newly added debug state. RestClient(..., debug=True) becomes debug=False after pickle.loads(pickle.dumps(...)), and the same happens through a pickled WriteApi.rest_client. Please pass debug=self.debug when rebuilding the client so pickle/unpickle preserves the configured debug behavior.

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 22 out of 22 changed files in this pull request and generated 2 comments.

Comment thread influxdb_client_3/__init__.py
Comment thread influxdb_client_3/write_client/_sync/rest_client.py
@NguyenHoangSon96

Copy link
Copy Markdown
Contributor Author

@bednar

  • Logger has been setting properly when debug=True in RestClient class.
  • Added debug to __setstate__().

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

5 participants