From df12e0b2efa0250bb5c138b3b9bd272b8a827948 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Bedn=C3=A1=C5=99?= Date: Tue, 27 Dec 2022 10:44:03 +0100 Subject: [PATCH 1/4] fix: numpy no longer supports `np.float` type (#543) For more info see - https://numpy.org/doc/stable/release/1.24.0-notes.html --- tests/test_WriteApiDataFrame.py | 2 +- tests/test_point.py | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/tests/test_WriteApiDataFrame.py b/tests/test_WriteApiDataFrame.py index 71132b88..3675519a 100644 --- a/tests/test_WriteApiDataFrame.py +++ b/tests/test_WriteApiDataFrame.py @@ -327,7 +327,7 @@ def test_write_num_py_floats(self): from influxdb_client.extras import pd, np now = pd.Timestamp('2020-04-05 00:00+00:00') - float_types = [np.float, np.float16, np.float32, np.float64] + float_types = [np.float16, np.float32, np.float64] if hasattr(np, 'float128'): float_types.append(np.float128) for np_float_type in float_types: diff --git a/tests/test_point.py b/tests/test_point.py index cee602db..992ac354 100644 --- a/tests/test_point.py +++ b/tests/test_point.py @@ -399,7 +399,6 @@ def test_numpy_types(self): point = Point.measurement("h2o") \ .tag("location", "europe") \ - .field("np.float1", np.float(1.123)) \ .field("np.float2", np.float16(2.123)) \ .field("np.float3", np.float32(3.123)) \ .field("np.float4", np.float64(4.123)) \ @@ -413,7 +412,7 @@ def test_numpy_types(self): .field("np.uint4", np.uint64(8)) self.assertEqual( - "h2o,location=europe np.float1=1.123,np.float2=2.123,np.float3=3.123,np.float4=4.123,np.int1=1i,np.int2=2i,np.int3=3i,np.int4=4i,np.uint1=5i,np.uint2=6i,np.uint3=7i,np.uint4=8i", + "h2o,location=europe np.float2=2.123,np.float3=3.123,np.float4=4.123,np.int1=1i,np.int2=2i,np.int3=3i,np.int4=4i,np.uint1=5i,np.uint2=6i,np.uint3=7i,np.uint4=8i", point.to_line_protocol()) def test_from_dictionary_custom_measurement(self): From d13debe6db643332a8a16a8867da509107c70be9 Mon Sep 17 00:00:00 2001 From: Pitastic Date: Wed, 21 Dec 2022 18:18:07 +0100 Subject: [PATCH 2/4] Create and Delete DB via v1 --- influxdb_client/client/bucket_api.py | 80 ++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/influxdb_client/client/bucket_api.py b/influxdb_client/client/bucket_api.py index 47763bee..ca9ffebc 100644 --- a/influxdb_client/client/bucket_api.py +++ b/influxdb_client/client/bucket_api.py @@ -58,6 +58,51 @@ def create_bucket(self, bucket=None, bucket_name=None, org_id=None, retention_ru return self._buckets_service.post_buckets(post_bucket_request=bucket) + def create_database(self, database=None, retention_rules=None): + """Create a database at the v1 api (legacy). + + :param database_name: name of the new database + :param retention_rules: retention rules array or single BucketRetentionRules + :return: Tuple (response body, status code, header dict)""" + if database is None: + raise ValueError("Invalid value for `database`, must be defined.") + + if retention_rules is None: + retention_rules = [] + + rules = [] + + if isinstance(retention_rules, list): + rules.extend(retention_rules) + else: + rules.append(retention_rules) + + # Hedaer and local_var_params for standard procedures only + header_params = {} + header_params['Accept'] = self._influxdb_client.api_client.select_header_accept( + ['application/json']) + header_params['Content-Type'] = self._influxdb_client.api_client.select_header_content_type( + ['application/json']) + local_var_params = locals() + local_var_params['kwargs'] = {} + all_params = [] + self._buckets_service._check_operation_params( + "create_database", all_params, local_var_params + ) + + return self._influxdb_client.api_client.call_api( + '/query', 'POST', + header_params=header_params, + path_params={}, post_params=[], + files={}, auth_settings=[], collection_formats={}, + query_params={'q': f'CREATE DATABASE {database}'}, + async_req=local_var_params.get('async_req'), + _return_http_data_only=local_var_params.get('_return_http_data_only'), # noqa: E501 + _preload_content=local_var_params.get('_preload_content', True), + _request_timeout=local_var_params.get('_request_timeout'), + urlopen_kw=None + ) + def update_bucket(self, bucket: Bucket) -> Bucket: """Update a bucket. @@ -83,6 +128,41 @@ def delete_bucket(self, bucket): return self._buckets_service.delete_buckets_id(bucket_id=bucket_id) + def delete_database(self, database=None): + """Delete a database at the v1 api (legacy). + + :param database_name: name of the database to delete + :param retention_rules: retention rules array or single BucketRetentionRules + :return: Tuple (response body, status code, header dict)""" + if database is None: + raise ValueError("Invalid value for `database`, must be defined.") + + # Hedaer and local_var_params for standard procedures only + header_params = {} + header_params['Accept'] = self._influxdb_client.api_client.select_header_accept( + ['application/json']) + header_params['Content-Type'] = self._influxdb_client.api_client.select_header_content_type( + ['application/json']) + local_var_params = locals() + local_var_params['kwargs'] = {} + all_params = [] + self._buckets_service._check_operation_params( + "drop_database", all_params, local_var_params + ) + + return self._influxdb_client.api_client.call_api( + '/query', 'POST', + header_params=header_params, + path_params={}, post_params=[], + files={}, auth_settings=[], collection_formats={}, + query_params={'q': f'DROP DATABASE {database}'}, + async_req=local_var_params.get('async_req'), + _return_http_data_only=local_var_params.get('_return_http_data_only'), + _preload_content=local_var_params.get('_preload_content', True), + _request_timeout=local_var_params.get('_request_timeout'), + urlopen_kw=None + ) + def find_bucket_by_id(self, id): """Find bucket by ID. From 90a7c62f926037056b43d5682903629f4f604169 Mon Sep 17 00:00:00 2001 From: Pitastic Date: Wed, 21 Dec 2022 21:40:49 +0100 Subject: [PATCH 3/4] Auto fallback when buckets not supported --- influxdb_client/client/bucket_api.py | 35 +++++++++++++--------------- 1 file changed, 16 insertions(+), 19 deletions(-) diff --git a/influxdb_client/client/bucket_api.py b/influxdb_client/client/bucket_api.py index ca9ffebc..392f5546 100644 --- a/influxdb_client/client/bucket_api.py +++ b/influxdb_client/client/bucket_api.py @@ -5,7 +5,7 @@ A bucket belongs to an organization. """ import warnings - +from influxdb_client.rest import ApiException from influxdb_client import BucketsService, Bucket, PostBucketRequest, PatchBucketRequest from influxdb_client.client.util.helpers import get_org_query_param @@ -20,20 +20,19 @@ def __init__(self, influxdb_client): def create_bucket(self, bucket=None, bucket_name=None, org_id=None, retention_rules=None, description=None, org=None) -> Bucket: - """Create a bucket. + """Create a bucket. Database creation via v1 API as fallback. :param Bucket|PostBucketRequest bucket: bucket to create :param bucket_name: bucket name :param description: bucket description :param org_id: org_id - :param bucket_name: bucket name :param retention_rules: retention rules array or single BucketRetentionRules :param str, Organization org: specifies the organization for create the bucket; Take the ``ID``, ``Name`` or ``Organization``. If not specified the default value from ``InfluxDBClient.org`` is used. - :return: Bucket + :return: Bucket or the request thread when falling back. If the method is called asynchronously, - returns the request thread. + returns also the request thread. """ if retention_rules is None: retention_rules = [] @@ -56,7 +55,12 @@ def create_bucket(self, bucket=None, bucket_name=None, org_id=None, retention_ru client=self._influxdb_client, required_id=True)) - return self._buckets_service.post_buckets(post_bucket_request=bucket) + try: + return self._buckets_service.post_buckets(post_bucket_request=bucket) + except ApiException as ex: + # Fall back to v1 API if buckets are not supported + database_name = bucket_name if bucket_name is not None else bucket + return self.create_database(database=database_name, retention_rules=retention_rules) def create_database(self, database=None, retention_rules=None): """Create a database at the v1 api (legacy). @@ -67,16 +71,6 @@ def create_database(self, database=None, retention_rules=None): if database is None: raise ValueError("Invalid value for `database`, must be defined.") - if retention_rules is None: - retention_rules = [] - - rules = [] - - if isinstance(retention_rules, list): - rules.extend(retention_rules) - else: - rules.append(retention_rules) - # Hedaer and local_var_params for standard procedures only header_params = {} header_params['Accept'] = self._influxdb_client.api_client.select_header_accept( @@ -116,17 +110,20 @@ def update_bucket(self, bucket: Bucket) -> Bucket: return self._buckets_service.patch_buckets_id(bucket_id=bucket.id, patch_bucket_request=request) def delete_bucket(self, bucket): - """Delete a bucket. + """Delete a bucket. Delete a database via v1 API as fallback. :param bucket: bucket id or Bucket - :return: Bucket + :return: Bucket or the request thread when falling back """ if isinstance(bucket, Bucket): bucket_id = bucket.id else: bucket_id = bucket - return self._buckets_service.delete_buckets_id(bucket_id=bucket_id) + try: + return self._buckets_service.delete_buckets_id(bucket_id=bucket_id) + except ApiException as ex: + return self.delete_database(database=bucket_id) def delete_database(self, database=None): """Delete a database at the v1 api (legacy). From 69b608978033d0452f3863727e86de687be68d03 Mon Sep 17 00:00:00 2001 From: Pitastic Date: Wed, 21 Dec 2022 22:07:43 +0100 Subject: [PATCH 4/4] Clean up coding style --- influxdb_client/client/bucket_api.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/influxdb_client/client/bucket_api.py b/influxdb_client/client/bucket_api.py index 392f5546..f195a417 100644 --- a/influxdb_client/client/bucket_api.py +++ b/influxdb_client/client/bucket_api.py @@ -57,17 +57,18 @@ def create_bucket(self, bucket=None, bucket_name=None, org_id=None, retention_ru try: return self._buckets_service.post_buckets(post_bucket_request=bucket) - except ApiException as ex: + except ApiException: # Fall back to v1 API if buckets are not supported database_name = bucket_name if bucket_name is not None else bucket return self.create_database(database=database_name, retention_rules=retention_rules) def create_database(self, database=None, retention_rules=None): """Create a database at the v1 api (legacy). - + :param database_name: name of the new database :param retention_rules: retention rules array or single BucketRetentionRules - :return: Tuple (response body, status code, header dict)""" + :return: Tuple (response body, status code, header dict) + """ if database is None: raise ValueError("Invalid value for `database`, must be defined.") @@ -122,15 +123,16 @@ def delete_bucket(self, bucket): try: return self._buckets_service.delete_buckets_id(bucket_id=bucket_id) - except ApiException as ex: + except ApiException: return self.delete_database(database=bucket_id) def delete_database(self, database=None): """Delete a database at the v1 api (legacy). - + :param database_name: name of the database to delete :param retention_rules: retention rules array or single BucketRetentionRules - :return: Tuple (response body, status code, header dict)""" + :return: Tuple (response body, status code, header dict) + """ if database is None: raise ValueError("Invalid value for `database`, must be defined.")