diff --git a/README.rst b/README.rst index 9e7a1b2a..5cf93962 100644 --- a/README.rst +++ b/README.rst @@ -116,4 +116,20 @@ Note about types of times and binaryData 1. All times: **DatetimeWithNanoseconds** (defined in the **proto.datetime_helpers** module) 2. All **binaryData** (CONFIG, STATE etc.): **BYTE ARRAYS** -- If this environment variable is not set, or is set to any unexpeced values, then the default types listed previously are used. \ No newline at end of file +- If this environment variable is not set, or is set to any unexpeced values, then the default types listed previously are used. + +Note about running from source instead of PyPi (pip) module: +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +- To temporarily use the source code in this repo. instead of the installed PyPi (pip) module do the following: + +1. Clone this repo. +2. Checkout the desired branch using **git checkout **. +3. In your code find where **clearblade** or **clearblade.cloud** is being imported. +4. Precede that line with **import sys** and **sys.path.insert(0, )**. The path must end with "python-iot". So for example: + +.. code-block:: console + + import sys + sys.path.insert(0, "path/to/python-iot") + + from clearblade.cloud import iot_v1 \ No newline at end of file diff --git a/UPGRADING.md b/UPGRADING.md index 7815d5f2..1b711d5a 100644 --- a/UPGRADING.md +++ b/UPGRADING.md @@ -1,157 +1,151 @@ -# 2.0.0 Migration Guide - -The 2.0 release of the `google-cloud-iot` client is a significant upgrade based on a [next-gen code generator](https://github.com/googleapis/gapic-generator-python), and includes substantial interface changes. Existing code written for earlier versions of this library will likely require updates to use this version. This document describes the changes that have been made, and what you need to do to update your usage. - -If you experience issues or have questions, please file an [issue](https://github.com/googleapis/python-iot/issues). - -## Supported Python Versions - -> **WARNING**: Breaking change - -The 2.0.0 release requires Python 3.6+. - + -## Method Calls - -> **WARNING**: Breaking change - -Methods expect request objects. We provide a script that will convert most common use cases. - -* Install the library with `libcst`. - -```py -python3 -m pip install google-cloud-iot[libcst] -``` - -* The script `fixup_iot_v1_keywords.py` is shipped with the library. It expects -an input directory (with the code to convert) and an empty destination directory. +# 2.0.0 Migration Guide -```sh -$ fixup_iot_v1_keywords.py --input-directory .samples/ --output-directory samples/ -``` +The 2.0 release of the `clearblade-cloud-iot` client is a significant upgrade based on addition of two new classes in **iot_v1**: -**Before:** -```py -from google.cloud import iot_v1 +- **DeviceCredential** +- **PublicKeyCredential** -client = iot_v1.DeviceManagerClient() +The release also includes enhancements to these classes already present in **iot_v1**: -registry = client.get_device_registry("registry_name") -``` +- **DeviceConfig** +- **DeviceState** +The version was made with the intent of minimizing required code changes. **However these changes should be considrered Breaking changes**. -**After:** -```py -from google.cloud import iot_v1 +# -client = iot_v1.DeviceManagerClient() +1. If **device** is an object of class **Device**. -registry = client.get_device_registry(request={'name': "registry_name"}) -``` + **Before**: + device.credentials is of type **[dict]** (i.e. list of dicts). -### More Details + **After**: + device.credentials is of type **[DeviceCredential]** (i.e. list of objects of class DeviceCredential). -In `google-cloud-iot<2.0.0`, parameters required by the API were positional parameters and optional parameters were keyword parameters. + The **DeviceCredential** class has these features for usability: -**Before:** -```py - def create_device( - self, - parent, - device, - retry=google.api_core.gapic_v1.method.DEFAULT, - timeout=google.api_core.gapic_v1.method.DEFAULT, - metadata=None, - ): -``` + - A **get** method that mimics the **get** method of a dict. + - Allows accessing attributes using dot notation OR square-brackets. + - Supports camel-case as well as snake-case for accessing attributes: -In the 2.0.0 release, all methods have a single positional parameter `request`. Method docstrings indicate whether a parameter is required or optional. + e.g. All these are valid for retrieving the public key: -Some methods have additional keyword only parameters. The available parameters depend on the `google.api.method_signature` annotation specified by the API producer. + - **public_key = device.credentials[0]['publicKey']** + - **public_key = device.credentials[0]['public_key']** + - **public_key = device.credentials[0].get('publicKey')** + - **public_key = device.credentials[0].get('public_key')** + - **public_key = device.credentials[0].publicKey** + - **public_key = device.credentials[0].public_key** +# -**After:** -```py - def create_device( - self, - request: device_manager.CreateDeviceRequest = None, - *, - parent: str = None, - device: resources.Device = None, - retry: retries.Retry = gapic_v1.method.DEFAULT, - timeout: float = None, - metadata: Sequence[Tuple[str, str]] = (), - ) -> resources.Device: -``` +2. This refers to pub_key mentioned in the previous section. -> **NOTE:** The `request` parameter and flattened keyword parameters for the API are mutually exclusive. -> Passing both will result in an error. + **Before**: + public_key was of type **dict**. + **After**: + public_key is an object of class **PublicKeyCredential**. -Both of these calls are valid: + The **PublicKeyCredential** class has these features for usability: -```py -response = client.create_device( - request={ - "parent": parent, - "device": device, - } -) -``` + - A **get** method that mimics the **get** method of a dict. + - Allows accessing attributes using dot notation OR square-brackets. -```py -response = client.create_device( - parent=parent, - device=device, -) -``` + e.g. All these are valid for retrieving the public key format: -This call is invalid because it mixes `request` with a keyword argument `device`. Executing this code -will result in an error. + - **format = public_key['format']** + - **format = public_key.get('format')** + - **format = public_key.format** -```py -response = client.create_device( - request={ - "parent": parent, - }, - device=device -) -``` +# +3. This section refers to **dev_config** which holds device config. + **Before**: + dev_config is of type **dict**. -## Enums and Types + **After**: + dev_config is an object of class **DeviceConfig**. + The **DeviceConfig** class has these features for usability: -> **WARNING**: Breaking change + - A **get** method that mimics the **get** method of a dict. + - Allows accessing attributes using dot notation OR square-brackets. + - Supports camel-case as well as snake-case for accessing attributes: -The submodules `enums` and `types` have been removed. + e.g. All these are valid for retrieving the cloud_update_time: -**Before:** -```py -from google.cloud import iot_v1 + - **cloud_update_time = device.credentials[0]['cloudUpdateTime']** + - **cloud_update_time = device.credentials[0]['cloud_update_time']** + - **cloud_update_time = device.credentials[0].get('cloudUpdateTime')** + - **cloud_update_time = device.credentials[0].get('cloud_update_time')** + - **cloud_update_time = device.credentials[0].cloudUpdateTime** + - **cloud_update_time = device.credentials[0].cloud_update_time** -gateway_type = iot_v1.enums.GatewayType.GATEWAY -device = iot_v1.types.Device(name="name") -``` +# +4. This section refers to **dev_state** which contains device state. -**After:** -```py -from google.cloud import iot_v1 + **Before**: + dev_state is of type **dict**. -gateway_type = iot_v1.GatewayType.GATEWAY -device = iot_v1.Device(name="name") -``` + **After**: + dev_state is an object of class **DeviceState**. -## Location Path Helper Method + The **DeviceState** class has these features for usability: -Location path helper method has been removed. Please construct -the path manually. + - A **get** method that mimics the **get** method of a dict. + - Allows accessing attributes using dot notation OR square-brackets. + - Supports camel-case as well as snake-case for accessing attributes: -```py -project = 'my-project' -location = 'location' + e.g. All these are valid for retrieving the binary_data: -location_path = f'projects/{project}/locations/{location}' -``` + - **binary_data = device.credentials[0]['binaryData']** + - **binary_data = device.credentials[0]['binary_data']** + - **binary_data = device.credentials[0].get('binaryData')** + - **binary_data = device.credentials[0].get('binary_data')** + - **binary_data = device.credentials[0].binaryData** + - **binary_data = device.credentials[0].binary_data** diff --git a/clearblade/cloud/iot_v1/__init__.py b/clearblade/cloud/iot_v1/__init__.py index 86561049..fd1f559c 100644 --- a/clearblade/cloud/iot_v1/__init__.py +++ b/clearblade/cloud/iot_v1/__init__.py @@ -1,3 +1,47 @@ +""" +"Copyright 2023 ClearBlade Inc." + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at +https://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +Copyright 2018 Google LLC +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at +https://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +Copyright 2023 ClearBlade Inc. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at +https://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +Copyright 2018 Google LLC +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at +https://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +""" + from .client import DeviceManagerClient, DeviceManagerAsyncClient from .device_types import * from .registry_types import * diff --git a/clearblade/cloud/iot_v1/client.py b/clearblade/cloud/iot_v1/client.py index f81d27f2..20303f21 100644 --- a/clearblade/cloud/iot_v1/client.py +++ b/clearblade/cloud/iot_v1/client.py @@ -1,3 +1,47 @@ +""" +"Copyright 2023 ClearBlade Inc." + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at +https://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +Copyright 2018 Google LLC +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at +https://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +Copyright 2023 ClearBlade Inc. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at +https://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +Copyright 2018 Google LLC +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at +https://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +""" + from .device_types import * from .devices import * from .registry import * diff --git a/clearblade/cloud/iot_v1/config.py b/clearblade/cloud/iot_v1/config.py index cf0ea130..d3ec7d40 100644 --- a/clearblade/cloud/iot_v1/config.py +++ b/clearblade/cloud/iot_v1/config.py @@ -1,3 +1,47 @@ +""" +"Copyright 2023 ClearBlade Inc." + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at +https://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +Copyright 2018 Google LLC +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at +https://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +Copyright 2023 ClearBlade Inc. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at +https://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +Copyright 2018 Google LLC +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at +https://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +""" + class ClearBladeConfig: def __init__(self, system_key:str = None, auth_token:str = None, diff --git a/clearblade/cloud/iot_v1/config_manager.py b/clearblade/cloud/iot_v1/config_manager.py index 738f18aa..fb8cd559 100644 --- a/clearblade/cloud/iot_v1/config_manager.py +++ b/clearblade/cloud/iot_v1/config_manager.py @@ -1,3 +1,47 @@ +""" +"Copyright 2023 ClearBlade Inc." + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at +https://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +Copyright 2018 Google LLC +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at +https://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +Copyright 2023 ClearBlade Inc. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at +https://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +Copyright 2018 Google LLC +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at +https://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +""" + import json import os diff --git a/clearblade/cloud/iot_v1/developer_tests.py b/clearblade/cloud/iot_v1/developer_tests.py index cb5daa34..c12d152f 100644 --- a/clearblade/cloud/iot_v1/developer_tests.py +++ b/clearblade/cloud/iot_v1/developer_tests.py @@ -1,3 +1,47 @@ +""" +"Copyright 2023 ClearBlade Inc." + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at +https://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +Copyright 2018 Google LLC +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at +https://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +Copyright 2023 ClearBlade Inc. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at +https://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +Copyright 2018 Google LLC +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at +https://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +""" + from client import DeviceManagerClient, DeviceManagerAsyncClient from device_types import * from registry import * diff --git a/clearblade/cloud/iot_v1/device_types.py b/clearblade/cloud/iot_v1/device_types.py index a24218a3..9e109bd9 100644 --- a/clearblade/cloud/iot_v1/device_types.py +++ b/clearblade/cloud/iot_v1/device_types.py @@ -1,39 +1,62 @@ -# -*- coding: utf-8 -*- -# Copyright 2023 ClearBlade Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# Copyright 2022 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# +""" +"Copyright 2023 ClearBlade Inc." + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at +https://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +Copyright 2018 Google LLC +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at +https://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +Copyright 2023 ClearBlade Inc. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at +https://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +Copyright 2018 Google LLC +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at +https://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +""" + from typing import List -from .resources import GatewayType, LogLevel +from .resources import GatewayType, LogLevel, PublicKeyFormat, PublicKeyCredential, DeviceCredential from .utils import get_value import os from proto.datetime_helpers import DatetimeWithNanoseconds import base64 +def convertCredentialsFormatsFromString(credentials): + # Converts public Key Format from string to object of class PublicKeyFormat + for index, credential in enumerate(credentials): + if 'publicKey' in credential: + credential['publicKey']['format'] = PublicKeyFormat(credential['publicKey']['format']) + credentials[index] = DeviceCredential(credential) + return credentials + class Device(): """ Data class for Clearblade Device @@ -93,26 +116,10 @@ def from_json(json): last_config_send_time = lastConfigSendTimeFromJson last_error_time = lastErrorTimeFromJson - if (configFromJson): - deviceConfig = DeviceConfig.from_json(configFromJson) - config = { "version": deviceConfig.version, "cloudUpdateTime": deviceConfig.cloud_update_time } - if (deviceConfig.binary_data not in [None, ""]): - config["binaryData"] = deviceConfig.binary_data - if (deviceConfig.device_ack_time not in [None, ""]): - config["deviceAckTime"] = deviceConfig.device_ack_time - else: - config = configFromJson - - if (stateFromJson): - deviceState = DeviceState.from_json(stateFromJson) - state = { "updateTime": deviceState.update_time, "binaryData": deviceState.binary_data } - else: - state = stateFromJson - return Device( id=get_value(json, 'id'), num_id=get_value(json, 'numId'), - credentials=get_value(json, 'credentials'), + credentials=convertCredentialsFormatsFromString(get_value(json, 'credentials')), last_heartbeat_time=last_heartbeat_time, last_event_time=last_event_time, last_state_time=last_state_time, @@ -121,8 +128,8 @@ def from_json(json): last_error_time=last_error_time, blocked=get_value(json, 'blocked'), last_error_status_code=get_value(json, 'lastErrorStatus'), - config=config, - state=state, + config=DeviceConfig.from_json(configFromJson), + state=DeviceState.from_json(stateFromJson), log_level=get_value(json, 'logLevel'), meta_data=get_value(json, 'metadata'), gateway_config=get_value(json, 'gatewayConfig') @@ -221,16 +228,22 @@ def blocked(self, blocked): class DeviceState(): def __init__(self, update_time: str = None, binary_data:str = None) -> None: - self._update_time = update_time - self._binary_data = binary_data + self.updateTime = update_time + self.binaryData = binary_data + + def __getitem__(self, arg): + return getattr(self, arg) + + def get(self, arg): + return getattr(self, arg) @property def update_time(self): - return self._update_time + return self.updateTime @property def binary_data(self): - return self._binary_data + return self.binaryData @staticmethod def from_json(response_json): @@ -254,8 +267,7 @@ def from_json(response_json): return DeviceState(update_time=update_time, binary_data=binary_data) - - + class Request(): def __init__(self, parent) -> None: self._parent = parent @@ -318,9 +330,15 @@ def __init__(self, name, binary_data) -> None: super().__init__(name) self._version = version - self._cloud_update_time = cloud_update_time - self._device_ack_time = device_ack_time - self._binary_data = binary_data + self.cloudUpdateTime = cloud_update_time + self.deviceAckTime = device_ack_time + self.binaryData = binary_data + + def __getitem__(self, arg): + return getattr(self, arg) + + def get(self, arg): + return getattr(self, arg) @property def version(self): @@ -328,15 +346,15 @@ def version(self): @property def cloud_update_time(self): - return self._cloud_update_time + return self.cloudUpdateTime @property def device_ack_time(self): - return self._device_ack_time + return self.deviceAckTime @property def binary_data(self): - return self._binary_data + return self.binaryData @staticmethod def from_json(json): @@ -493,8 +511,8 @@ def _prepare_params_body_for_update(self): body['metadata'] = self._device.meta_data if self._device._blocked is not None: body['blocked'] = self._device._blocked - if self._device.credentials is not None: - body['credentials'] = self._device.credentials + if self._device._credentials is not None: + body['credentials'] = DeviceCredential.convert_credentials_for_create_update(self._device._credentials) return params, body diff --git a/clearblade/cloud/iot_v1/devices.py b/clearblade/cloud/iot_v1/devices.py index 42ebbe4a..97633860 100644 --- a/clearblade/cloud/iot_v1/devices.py +++ b/clearblade/cloud/iot_v1/devices.py @@ -1,38 +1,53 @@ -# -*- coding: utf-8 -*- -# Copyright 2023 ClearBlade Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# Copyright 2022 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# +""" +"Copyright 2023 ClearBlade Inc." + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at +https://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +Copyright 2018 Google LLC +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at +https://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +Copyright 2023 ClearBlade Inc. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at +https://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +Copyright 2018 Google LLC +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at +https://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +""" + from .config_manager import ClearBladeConfigManager from .device_types import * from .http_client import AsyncClient, SyncClient from .pagers import ListDevicesAsyncPager, ListDevicesPager import base64 - +from .resources import DeviceCredential class ClearBladeDeviceManager(): @@ -61,7 +76,7 @@ def _prepare_for_send_command(self, def _create_device_body(self, device: Device) : return {'id':device.id, - 'credentials':device.credentials, + 'credentials':DeviceCredential.convert_credentials_for_create_update(device.credentials), 'config':device.config, 'blocked': device.blocked, 'logLevel':device.log_level, 'metadata':device.meta_data, diff --git a/clearblade/cloud/iot_v1/http_client.py b/clearblade/cloud/iot_v1/http_client.py index 182c0c70..ddb002fd 100644 --- a/clearblade/cloud/iot_v1/http_client.py +++ b/clearblade/cloud/iot_v1/http_client.py @@ -1,3 +1,47 @@ +""" +"Copyright 2023 ClearBlade Inc." + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at +https://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +Copyright 2018 Google LLC +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at +https://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +Copyright 2023 ClearBlade Inc. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at +https://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +Copyright 2018 Google LLC +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at +https://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +""" + import json import httpx from .config import * diff --git a/clearblade/cloud/iot_v1/pagers.py b/clearblade/cloud/iot_v1/pagers.py index 1ba3bd29..622768c2 100644 --- a/clearblade/cloud/iot_v1/pagers.py +++ b/clearblade/cloud/iot_v1/pagers.py @@ -1,3 +1,47 @@ +""" +"Copyright 2023 ClearBlade Inc." + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at +https://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +Copyright 2018 Google LLC +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at +https://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +Copyright 2023 ClearBlade Inc. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at +https://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +Copyright 2018 Google LLC +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at +https://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +""" + from .device_types import Device, ListDevicesResponse, ListDevicesRequest from .registry_types import DeviceRegistry, ListDeviceRegistriesRequest, ListDeviceRegistriesResponse from typing import Any, Awaitable, AsyncIterator, Callable diff --git a/clearblade/cloud/iot_v1/registry.py b/clearblade/cloud/iot_v1/registry.py index 900defbb..972215c1 100644 --- a/clearblade/cloud/iot_v1/registry.py +++ b/clearblade/cloud/iot_v1/registry.py @@ -1,3 +1,47 @@ +""" +"Copyright 2023 ClearBlade Inc." + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at +https://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +Copyright 2018 Google LLC +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at +https://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +Copyright 2023 ClearBlade Inc. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at +https://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +Copyright 2018 Google LLC +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at +https://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +""" + from .config_manager import ClearBladeConfigManager from .http_client import AsyncClient, SyncClient from .pagers import ListDeviceRegistriesAsyncPager, ListDeviceRegistryPager diff --git a/clearblade/cloud/iot_v1/registry_types.py b/clearblade/cloud/iot_v1/registry_types.py index 1e65a278..01bbd51f 100644 --- a/clearblade/cloud/iot_v1/registry_types.py +++ b/clearblade/cloud/iot_v1/registry_types.py @@ -1,3 +1,47 @@ +""" +"Copyright 2023 ClearBlade Inc." + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at +https://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +Copyright 2018 Google LLC +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at +https://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +Copyright 2023 ClearBlade Inc. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at +https://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +Copyright 2018 Google LLC +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at +https://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +""" + from .utils import get_value from .resources import HttpState, MqttState, LogLevel diff --git a/clearblade/cloud/iot_v1/resources.py b/clearblade/cloud/iot_v1/resources.py index 0989f754..1246819b 100644 --- a/clearblade/cloud/iot_v1/resources.py +++ b/clearblade/cloud/iot_v1/resources.py @@ -1,3 +1,49 @@ +""" +"Copyright 2023 ClearBlade Inc." + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at +https://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +Copyright 2018 Google LLC +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at +https://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +Copyright 2023 ClearBlade Inc. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at +https://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +Copyright 2018 Google LLC +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at +https://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +""" + +from enum import Enum +from datetime import datetime class MqttState(): r"""Indicates whether an MQTT connection is enabled or disabled. @@ -56,10 +102,70 @@ class PublicKeyCertificateFormat(): X509_CERTIFICATE_PEM = "X509_CERTIFICATE_PEM" -class PublicKeyFormat: +class PublicKeyFormat(Enum): r"""The supported formats for the public key.""" UNSPECIFIED_PUBLIC_KEY_FORMAT = "UNSPECIFIED_PUBLIC_KEY_FORMAT" RSA_PEM = "RSA_PEM" RSA_X509_PEM = "RSA_X509_PEM" ES256_PEM = "ES256_PEM" ES256_X509_PEM = "ES256_X509_PEM" + +class PublicKeyCredential(): + def __init__(self, format: PublicKeyFormat, key: bytes): + self.format = format + self.key = key + + def __getitem__(self, arg): + return getattr(self, arg) + + def get(self, arg): + return getattr(self, arg) + + +class DeviceCredential(): + def __init__(self, public_key, expiration_time=''): + if isinstance(public_key, dict): + self.publicKey = PublicKeyCredential(public_key['publicKey']['format'], public_key['publicKey']['key']) + else: + self.publicKey = public_key + self.expirationTime = expiration_time + + def __getitem__(self, arg): + return getattr(self, arg) + + def get(self, arg): + return getattr(self, arg) + + @property + def public_key(self): + return self.publicKey + + @property + def expiration_time(self): + return self.expirationTime + + @classmethod + def convert_credentials_for_create_update(cls, credentials): + for index, credential in enumerate(credentials): + # Convert credential to dict if it is not + updateDeviceCredential = False + if (isinstance(credential, DeviceCredential)): + credential = credential.__dict__ + updateDeviceCredential = True + + if 'publicKey' in credential: + if (isinstance(credential['publicKey'], PublicKeyCredential)): + credential['publicKey'] = credential['publicKey'].__dict__ + # Convert PublicKeyFormat to string + credential['publicKey']['format'] = PublicKeyFormat(credential['publicKey']['format']).value + updateDeviceCredential = True + + if 'expirationTime' in credential: + if (isinstance(credential['expirationTime'], datetime)): + credential['expirationTime'] = credential['expirationTime'].strftime('%Y-%m-%dT%H:%M:%SZ') + updateDeviceCredential = True + + if updateDeviceCredential: + credentials[index] = credential + + return credentials \ No newline at end of file diff --git a/clearblade/cloud/iot_v1/utils.py b/clearblade/cloud/iot_v1/utils.py index 9b3b0de6..72c7d938 100644 --- a/clearblade/cloud/iot_v1/utils.py +++ b/clearblade/cloud/iot_v1/utils.py @@ -1,3 +1,47 @@ +""" +"Copyright 2023 ClearBlade Inc." + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at +https://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +Copyright 2018 Google LLC +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at +https://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +Copyright 2023 ClearBlade Inc. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at +https://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +Copyright 2018 Google LLC +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at +https://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +""" + from typing import Any def find_project_region_registry_from_parent(parent):