Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

## 0.21.0 [unreleased]

### Bug Fixes

1. [#234](https://github.com/InfluxCommunity/influxdb3-python/pull/234): Add support for connecting to InfluxDB servers using IPv6 addresses.
- IPv6 addresses in server URLs must be enclosed in square brackets, for example, http://[2001:db8::1]:8086.
- IPv6 zone identifiers are not currently supported.

### Breaking Changes

1. [#217](https://github.com/InfluxCommunity/influxdb3-python/pull/217): Makes the writing API simpler and more consistent with other v3 clients.
Expand Down
11 changes: 6 additions & 5 deletions influxdb_client_3/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import multiprocessing

import importlib.util
import json
import multiprocessing
import os
import urllib.parse
from typing import Any, List, Literal, Optional, TYPE_CHECKING
Expand Down Expand Up @@ -209,7 +208,8 @@ def __init__(
"""
Initialize an InfluxDB client.

:param host: The hostname or IP address of the InfluxDB server.
:param host: The hostname or IP address of the InfluxDB server. IPv6 must be wrapped inside square brackets,
e.g. http://[2001:db8::1]:8086, and Zone IDs are not supported.
:type host: str
:param org: The InfluxDB organization name for operations.
:type org: str
Expand Down Expand Up @@ -306,10 +306,11 @@ def __init__(

# Parse the host input
parsed_url = urllib.parse.urlparse(host)
hostname = parsed_url.hostname if parsed_url.hostname else host
if "[" in parsed_url.netloc and "]" in parsed_url.netloc:
hostname = f"[{hostname}]"

# Determine the protocol (scheme), hostname, and port
scheme = parsed_url.scheme if parsed_url.scheme else "https"
hostname = parsed_url.hostname if parsed_url.hostname else host
port = parsed_url.port if parsed_url.port else 443

# Construct the clients using the parsed values
Expand Down
3 changes: 2 additions & 1 deletion influxdb_client_3/query/query_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,8 @@ def __init__(self,
"""
Initialize defaults.

:param connection_string: Flight/gRPC connection string
:param connection_string: Flight/gRPC connection string. IPv6 must be wrapped inside square brackets,
e.g. 'grpc+tcp://[2001:db8::1]:8086', and Zone IDs are not supported.
:param token: access token
:param flight_client_options: Flight client options
"""
Expand Down
46 changes: 46 additions & 0 deletions tests/test_influxdb_client_3.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,52 @@ def test_token_auth_scheme_default(self):
)
self.assertEqual(client.default_header['Authorization'], "Token my_token")

def test_parse_addresses(self):
tests = [
{"url": "http://192.168.0.5/db", "expect": "http://192.168.0.5:443"},
{"url": "http://192.168.0.1:80", "expect": "http://192.168.0.1:80"},
{"url": "https://[2001:db8::1]", "expect": "https://[2001:db8::1]:443"},
{"url": "https://[2001:db8::1]:8086/influx", "expect": "https://[2001:db8::1]:8086"},
{"url": "http://[2001:db8::1]:15000?token=my-token", "expect": "http://[2001:db8::1]:15000"},
{"url": "http://[2001:db8::1]", "expect": "http://[2001:db8::1]:443"},
{"url": "http://[2001:db8:a0b:12f0::1]:80", "expect": "http://[2001:db8:a0b:12f0::1]:80"},
{"url": "http://example.com", "expect": "http://example.com:443"},
{"url": "http://example.com:3000", "expect": "http://example.com:3000"},
]
for test in tests:
client = InfluxDBClient3(
host=test["url"],
org="my_org",
database="my_db",
token="my_token",
)
self.assertEqual(client.base_url, test["expect"])

@patch('influxdb_client_3._QueryApi')
def test_ipv6_QueryApi(self, mock_query_api):
tests = [
{"url": "https://[2001:db8::1]", "expect": "grpc+tls://[2001:db8::1]:443"},
{"url": "https://[2001:db8::1]:8086/influx", "expect": "grpc+tls://[2001:db8::1]:8086"},
{"url": "http://[2001:db8::1]:15000?token=my-token", "expect": "grpc+tcp://[2001:db8::1]:15000"},
{"url": "http://[2001:db8::1]", "expect": "grpc+tcp://[2001:db8::1]:443"},
{"url": "http://[2001:db8:a0b:12f0::1]:80", "expect": "grpc+tcp://[2001:db8:a0b:12f0::1]:80"},
]
for test in tests:
InfluxDBClient3(
host=test['url'],
org="my_org",
database="my_db",
token="my_token"
)
mock_query_api.assert_called_with(
connection_string=test['expect'],
token="my_token",
flight_client_options=None,
proxy=None,
options=unittest.mock.ANY
)
mock_query_api.reset_mock()

# test explicit token auth_scheme
def test_token_auth_scheme_explicit(self):
client = InfluxDBClient3(
Expand Down
Loading