Code Monkey home page Code Monkey logo

thingsboard-python-rest-client's Introduction

ThingsBoard Python REST API client

The ThingsBoard REST API Client helps you interact with ThingsBoard REST API from your Python script.
With Python Rest Client you can programmatically create assets, devices, customers, users and other entities and their relations in ThingsBoard.

The recommended method for installing the Rest Client is a pip.

The Python version of the REST API client is under developing. If you have discovered any bug, please write us using email or by opening the issue.

Installation

In order to install the ThingsBoard REST client, you should use the following command:

pip3 install tb-rest-client
Examples

You can find the examples of the usage in the "examples" folder or on the our website.

Note: There are 2 REST clients for ThingsBoard, they are depend on version of the ThingsBoard, you use.

  • If you use the ThingsBoard Community Edition (ThingsBoard CE) - please use the following command to import the REST client into your script:
    from tb_rest_client.rest_client_ce import *
    The REST client class has name "RestClientCE".

  • If you use the ThingsBoard Professional Edition (ThingsBoard PE) - please use the following command to import the REST client into your script:
    from tb_rest_client.rest_client_pe import *
    The REST client class has name "RestClientPE".

If you use the wrong version of the REST client, it could work unexpectedly.

Support

Don't forget to star the repository to show your ❤️ and support.

Licenses

This project is released under Apache 2.0 License.

thingsboard-python-rest-client's People

Contributors

ashvayka avatar cchildress-gsu avatar d34dplayer avatar djexp avatar francesco-midokura avatar imbeacon avatar jernkuan avatar nolat avatar samson0v avatar shawnshank avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

thingsboard-python-rest-client's Issues

Unable to get user activation link

HI Team,
When ever I am trying to get activation link by using below code

**userid = UserId(id="xxxxxx-xxx-xxx-xxx-xxxxxx",
entity_type="USER")

user_activation_link = rest_client.get_activation_link(user_id=userid)**

I am getting below error

HTTP response body: b'{"status":406,"message":"Could not find acceptable representation","errorCode":31,"timestamp":"2022-09-05T17:05:17.448+00:00","subscriptionErrorCode":null,"subscriptionEntry":null,"subscriptionValue":null}'

Can you please check and fix the issue as early as possible?

NameError: name 'TenantProfile' is not defined

Traceback (most recent call last):
File "create-device.py", line 2, in
from tb_rest_client.rest_client_ce import *
File "", line 991, in _find_and_load
File "", line 975, in _find_and_load_unlocked
File "", line 655, in _load_unlocked
File "", line 618, in _load_backward_compatible
File "", line 259, in load_module
File "/home/administrator/.pyenv/versions/3.8.11/lib/python3.8/site-packages/tb_rest_client-1.1.1-py3.8.egg/tb_rest_client/rest_client_ce.py", line 17, in
File "", line 991, in _find_and_load
File "", line 975, in _find_and_load_unlocked
File "", line 655, in _load_unlocked
File "", line 618, in _load_backward_compatible
File "", line 259, in load_module
File "/home/administrator/.pyenv/versions/3.8.11/lib/python3.8/site-packages/tb_rest_client-1.1.1-py3.8.egg/tb_rest_client/rest_client_base.py", line 32, in
File "/home/administrator/.pyenv/versions/3.8.11/lib/python3.8/site-packages/tb_rest_client-1.1.1-py3.8.egg/tb_rest_client/rest_client_base.py", line 772, in RestClientBase
NameError: name 'TenantProfile' is not defined

get_timeseries_keys() - 'str' object has no attribute 'entity_type'

Hi I'm trying to fetch get_temeseries_keys but get an AttributeError in the call chain.

My calling code:

        rest_client.login(username=username, password=password)

        device = rest_client.get_tenant_device("Thermometer 1")
        print(device)
        rest_client.get_timeseries_keys(device.id.id)

Output:

{'additional_info': None,
 'created_time': 1596020419660,
 'customer_id': {'entity_type': 'CUSTOMER',
                 'id': '13814000-1dd2-11b2-8080-808080808080'},
 'id': {'entity_type': 'DEVICE', 'id': 'b12f98c0-d18a-11ea-a2d4-05d67df22d46'},
 'label': None,
 'name': 'Thermometer 1',
 'owner_id': None,
 'tenant_id': {'entity_type': 'TENANT',
               'id': '1a3b3000-d18a-11ea-a2d4-05d67df22d46'},
 'type': 'thermometer'}
Traceback (most recent call last):
  File "test.py", line 27, in <module>
    rest_client.get_timeseries_keys(device.id.id)
  File "/usr/local/lib/python3.8/site-packages/tb_rest_client/rest_client_base.py", line 622, in get_timeseries_keys
    return self.telemetry_controller.get_timeseries_keys_using_get(entity_type=entity_id.entity_type,
AttributeError: 'str' object has no attribute 'entity_type'

When using a device.id object instead I get another error:

My calling code:

        rest_client.login(username=username, password=password)

        device = rest_client.get_tenant_device("Thermometer 1")
        print(device)
        rest_client.get_timeseries_keys(device.id)

Output:

{'additional_info': None,
 'created_time': 1596020419660,
 'customer_id': {'entity_type': 'CUSTOMER',
                 'id': '13814000-1dd2-11b2-8080-808080808080'},
 'id': {'entity_type': 'DEVICE', 'id': 'b12f98c0-d18a-11ea-a2d4-05d67df22d46'},
 'label': None,
 'name': 'Thermometer 1',
 'owner_id': None,
 'tenant_id': {'entity_type': 'TENANT',
               'id': '1a3b3000-d18a-11ea-a2d4-05d67df22d46'},
 'type': 'thermometer'}
Traceback (most recent call last):
  File "/usr/local/lib/python3.8/site-packages/tb_rest_client/api_client.py", line 316, in __deserialize
    found_class = getattr(tb_rest_client.models.models_pe, klass)
AttributeError: module 'tb_rest_client.models.models_pe' has no attribute 'DeferredResultResponseEntity'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "test.py", line 27, in <module>
    rest_client.get_timeseries_keys(device.id)
  File "/usr/local/lib/python3.8/site-packages/tb_rest_client/rest_client_base.py", line 622, in get_timeseries_keys
    return self.telemetry_controller.get_timeseries_keys_using_get(entity_type=entity_id.entity_type,
  File "/usr/local/lib/python3.8/site-packages/tb_rest_client/api/api_ce/telemetry_controller_api.py", line 944, in get_timeseries_keys_using_get
    (data) = self.get_timeseries_keys_using_get_with_http_info(entity_type, entity_id, **kwargs)  # noqa: E501
  File "/usr/local/lib/python3.8/site-packages/tb_rest_client/api/api_ce/telemetry_controller_api.py", line 1010, in get_timeseries_keys_using_get_with_http_info
    return self.api_client.call_api(
  File "/usr/local/lib/python3.8/site-packages/tb_rest_client/api_client.py", line 390, in call_api
    return self.__call_api(resource_path, method,
  File "/usr/local/lib/python3.8/site-packages/tb_rest_client/api_client.py", line 205, in __call_api
    return_data = self.deserialize(response_data, response_type)
  File "/usr/local/lib/python3.8/site-packages/tb_rest_client/api_client.py", line 287, in deserialize
    return self.__deserialize(data, response_type)
  File "/usr/local/lib/python3.8/site-packages/tb_rest_client/api_client.py", line 327, in __deserialize
    if all(attr in list(found_class.attribute_map.values()) for attr in list(data.keys())):
AttributeError: 'list' object has no attribute 'keys'

Am I doing it wrong? Missing a lot of documentation on how to use the API.

[Feature Request] Access raw json of requests instead of Object form

When using the rest client, is it possible to just have the commands return raw json? The client is extremely hard to use because an Object Oriented approach has been forced into it, which results in more complex code to extract usable information. Take the following process:
I want to get all my data converters and iterate over them

converters = rest_client.get_converters("1000","0")
for idx, converter in enumerate(converters['data']):
   pass

# Fails with error
# TypeError: 'PageDataConverter' object is not subscriptable

The above code will not work. This is because the rest client converts the default json response into an object PageDataConverter.

I'm not sure why this needs to be an object. It's just a json response from the server, which should be really easy to work with. Instead for every single request I need to add this function.

def toJson(input):
    return ast.literal_eval(str(input))

converters = toJson(rest_client.get_converters("1000","0"))
for idx, converter in enumerate(converters['data']):
   pass

# Works

Can we just have access to the raw response?

token is not saved into token_info

It seems that token_info is never filled with the actual token (guess it should be at login, shouldn't it?).
So get_token() always returns an empty string. Is this the expected behaviour?

rest_client.get_timeseries() return

RestClient.get_timeseries() method returns an object of type DeferredResultResponseEntity which always has following properties:

{
    'result': None,
    'set_or_expired': None
}

I have tried the same requests to same urls and same parameters using plain python requests library and I get correct results (actual timeseries data I have saved in thingsboard), so I dont know why the result property is None when I use get_timeseries() method. What is the correct way of extracting the result from DeferredResultResponseEntity object?

get_tenant_devices() always return invalid UUID

i want to get devices list, but always return like this

HTTP response body: {"status":400,"message":"Invalid UUID string: devices","errorCode":31,"timestamp":"2020-07-15T01:43:38.331+0000"}

[Bug] entity group controller get_entity_groups_by_type error

Describe the bug
*The get_entity_groups_by_type returns a list of error messages instead of a list of groups. The length of the list of errors is the same as the number of groups in the tenant.

Your Server Environment

  • cloud.thingsboard.io

Your Client Environment

  • tb_rest_client-1.4-py3.7

  • OS: Amazon Linux

To Reproduce
Steps to reproduce the behavior:

  1. Log in to the rest client rest_client_tb.login(username=credentials["user"], password=credentials["password"])
  2. Call the function:
res = rest_client_tb.get_entity_groups_by_type('DEVICE')
log_TB.debug("get groups result (%i): \n%s", len(res),str(res))
  1. Observe the result. Note that the length of the list is the same as the number of groups in the tenant:
get groups result (123): 
[AttributeError("module 'tb_rest_client.models.models_ce' has no attribute 'EntityGroupId'"), 
AttributeError("module 'tb_rest_client.models.models_ce' has no attribute 'EntityGroupId'"),
...
AttributeError("module 'tb_rest_client.models.models_ce' has no attribute 'EntityGroupId'")]

Expected behavior
I expect the result to be a list of groups like so:

[
    {
        "id": {
            "entityType": "ENTITY_GROUP",
            "id": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
        },
        "createdTime": 1637742034126,
        "type": "DEVICE",
        "name": "All",
        "ownerId": {
            "entityType": "TENANT",
            "id": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
        },
        "additionalInfo": null,
        "configuration": {
            "columns": [
                {
                    "type": "ENTITY_FIELD",
                    "key": "created_time",
                    "sortOrder": "DESC"
                },
                {
                    "type": "ENTITY_FIELD",
                    "key": "name",
                    "sortOrder": "NONE"
                },
                {
                    "type": "ENTITY_FIELD",
                    "key": "device_profile",
                    "sortOrder": "NONE"
                },
                {
                    "type": "ENTITY_FIELD",
                    "key": "label",
                    "sortOrder": "NONE"
                }
            ],
            "settings": {},
            "actions": {}
        },
        "externalId": null,
        "ownerIds": [
            {
                "entityType": "TENANT",
                "id": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
            }
        ],
        "edgeGroupAll": false,
        "groupAll": true
    },
    {
        "id": {
            "entityType": "ENTITY_GROUP",
            "id": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
        },
        "createdTime": 1637829142713,
        "type": "DEVICE",
        "name": "Advantage.Li",
        "ownerId": {
            "entityType": "TENANT",
            "id": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
        },
        "additionalInfo": null,
        "configuration": {
            "columns": [
                {
                    "type": "ENTITY_FIELD",
                    "key": "created_time",
                    "sortOrder": "DESC"
                },
                {
                    "type": "ENTITY_FIELD",
                    "key": "name",
                    "sortOrder": "NONE"
                },
                {
                    "type": "ENTITY_FIELD",
                    "key": "device_profile",
                    "sortOrder": "NONE"
                },
                {
                    "type": "ENTITY_FIELD",
                    "key": "label",
                    "sortOrder": "NONE"
                }
            ],
            "settings": {},
            "actions": {}
        },
        "externalId": null,
        "ownerIds": [
            {
                "entityType": "TENANT",
                "id": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
            }
        ],
        "edgeGroupAll": false,
        "groupAll": false
    },
...
]

handle_two_way_device_rpc_request_v1 fails when trying to call rpc_v_2_controller

Hello,

When trying to implement an rpc request with the sdk, I got the following error:

> return self.rpc_v_2_controller.handle_two_way_device_rpc_request_using_post1(body=body, device_id=device_id)
E AttributeError: 'TBClient' object has no attribute 'rpc_v_2_controller'

TBclient is a custom class that inherits from RestClientPE

In ret_client_base.py, the method handle_two_way_device_rpc_request_v1 use the the controller rpc_v_2_controller :

def handle_two_way_device_rpc_request_v1(self, body: str, device_id: DeviceId):
    device_id = self.get_id(device_id)
    return self.rpc_v_2_controller.handle_two_way_device_rpc_request_using_post1(body=body, device_id=device_id)

yet the rpc_v_2_controller is initialized as follow in rest_client_base.py l.908:

self.rpc_v2_controller = RpcV2ControllerApi(self.api_client)

It seems that a '_' has appeared magically in :
return self.rpc_v_2_controller.handle_two_way_device_rpc_request_using_post1(body=body, device_id=device_id) ?
Is it a bug or did I miss something important ?

Thank you for your help !

[BUG] entity group controller get_entities module 'tb_rest_client.models.models_ce' has no attribute 'ShortEntityView'

Describe the bug

  • the get_entities call returns the error module 'tb_rest_client.models.models_ce' has no attribute 'ShortEntityView' May be related to #75

Your Server Environment

  • cloud.thingsboard.io

Your Client Environment

  • tb_rest_client-1.4-py3.7
  • OS: Amazon Linux

To Reproduce
Steps to reproduce the behavior:

  1. Log in to the rest client 'rest_client_tb.login(username=credentials["user"], password=credentials["password"])'
  2. Call the function:
res = rest_client_tb.get_entities(entity_group_id = "XXXXXXXXXXXXXXXXXXXXXXXXXXX",page_size="500", page="0", sort_property = 'name', sort_order = 'ASC')
log_TB.debug("get group devices result: \n%s", str(res))
  1. Observe the result:
2022-08-11 15:29:12,761    DEBUG __main__.Thingsboard | get group devices result: 
module 'tb_rest_client.models.models_ce' has no attribute 'ShortEntityView'

Expected behavior
I expect the result to be a list of groups like so (from Postman):

{
    "data": [
        {
            "id": {
                "entityType": "DEVICE",
                "id": "XXXXXXXXXXXXXXXXXXXXXXXXXXX"
            },
            "name": "12E22WT002",
            "created_time": "1649324729839",
            "name": "12E22WT002",
            "device_profile": "Motive.Li",
            "label": "Merlog_WT(4)"
        },
...
        {
            "id": {
                "entityType": "DEVICE",
                "id": "XXXXXXXXXXXXXXXXXXXXXXXXXXX"
            },
            "name": "02H33ESR006",
            "created_time": "1649103598563",
            "name": "02H33ESR006",
            "device_profile": "Motive.Li",
            "label": "Boxer Polokwane ESR 6"
        }
    ],
    "totalPages": 29,
    "totalElements": 283,
    "hasNext": true
}

Rest Client uses different naming conventions

If I download a device profile for example, all fields are returned as camelCase, however if I use the rest client to extract data, the result is returned underscore_separated. This makes no sense.

Also, when I use the API to get the device profile, I get a bunch of additional information that is no present when downloading directly from the Thingsboard UI. This means that I can't use the rest client to easily download a device profile, save it to a .json file, and immediately import it into my project.

Below compares what I get from downloading from UI and Rest Client:
image

The problem is that the rest client uses an older naming convention.

For reference, this is what the swagger for TB3.3.2 returns (using the example because it's not currently working see issue #5598 in main repo)

{
      "id": {
        "id": "784f394c-42b6-435a-983c-b7beff2784f9",
        "entityType": "DEVICE_PROFILE"
      },
      "createdTime": 1609459200000,
      "tenantId": {
        "id": "784f394c-42b6-435a-983c-b7beff2784f9",
        "entityType": "TENANT"
      },
      "name": "Moisture Sensor",
      "default": false,
      "defaultDashboardId": {
        "id": "784f394c-42b6-435a-983c-b7beff2784f9",
        "entityType": "DASHBOARD"
      },
      "defaultRuleChainId": {
        "id": "784f394c-42b6-435a-983c-b7beff2784f9",
        "entityType": "RULE_CHAIN"
      },
      "defaultQueueName": "string",
      "firmwareId": {
        "id": "784f394c-42b6-435a-983c-b7beff2784f9",
        "entityType": "OTA_PACKAGE"
      },
      "softwareId": {
        "id": "784f394c-42b6-435a-983c-b7beff2784f9",
        "entityType": "OTA_PACKAGE"
      },
      "description": "string",
      "image": "string",
      "provisionDeviceKey": "string",
      "transportType": "COAP",
      "provisionType": "ALLOW_CREATE_NEW_DEVICES",
      "profileData": {
        "configuration": {},
        "transportConfiguration": {},
        "provisionConfiguration": {
          "provisionDeviceSecret": "string"
        },
        "alarms": [
          {
            "id": "highTemperatureAlarmID",
            "alarmType": "High Temperature Alarm",
            "createRules": {
              "additionalProp1": {
                "condition": {
                  "condition": [
                    {
                      "key": {
                        "type": "TIME_SERIES",
                        "key": "temp"
                      },
                      "valueType": "NUMERIC",
                      "value": {},
                      "predicate": {}
                    }
                  ],
                  "spec": {}
                },
                "schedule": {
                  "type": "ANY_TIME"
                },
                "alarmDetails": "string",
                "dashboardId": {
                  "id": "784f394c-42b6-435a-983c-b7beff2784f9",
                  "entityType": "DASHBOARD"
                }
              },
              "additionalProp2": {
                "condition": {
                  "condition": [
                    {
                      "key": {
                        "type": "TIME_SERIES",
                        "key": "temp"
                      },
                      "valueType": "NUMERIC",
                      "value": {},
                      "predicate": {}
                    }
                  ],
                  "spec": {}
                },
                "schedule": {
                  "type": "ANY_TIME"
                },
                "alarmDetails": "string",
                "dashboardId": {
                  "id": "784f394c-42b6-435a-983c-b7beff2784f9",
                  "entityType": "DASHBOARD"
                }
              },
              "additionalProp3": {
                "condition": {
                  "condition": [
                    {
                      "key": {
                        "type": "TIME_SERIES",
                        "key": "temp"
                      },
                      "valueType": "NUMERIC",
                      "value": {},
                      "predicate": {}
                    }
                  ],
                  "spec": {}
                },
                "schedule": {
                  "type": "ANY_TIME"
                },
                "alarmDetails": "string",
                "dashboardId": {
                  "id": "784f394c-42b6-435a-983c-b7beff2784f9",
                  "entityType": "DASHBOARD"
                }
              }
            },
            "clearRule": {
              "condition": {
                "condition": [
                  {
                    "key": {
                      "type": "TIME_SERIES",
                      "key": "temp"
                    },
                    "valueType": "NUMERIC",
                    "value": {},
                    "predicate": {}
                  }
                ],
                "spec": {}
              },
              "schedule": {
                "type": "ANY_TIME"
              },
              "alarmDetails": "string",
              "dashboardId": {
                "id": "784f394c-42b6-435a-983c-b7beff2784f9",
                "entityType": "DASHBOARD"
              }
            },
            "propagate": true,
            "propagateRelationTypes": [
              "string"
            ]
          }
        ]
      },
      "type": "DEFAULT"
    }

self.token_info['exp'] never written

Why is the self.token_info['exp'] variable never written? Shouldn't it be set to the timeout variable of the jwt Token + actual time on getting a new key? Otherwise it will update every second to a new key or am I wrong with that?

No module named 'requests'

I installed with pip the tb-rest-client and i have already run the example.py but i take this unexpected error:

Traceback (most recent call last): File "C:\Users\apsir\Desktop\REST API.py", line 1, in <module> from tb_rest_client.rest_client_ce import * File "C:\Users\apsir\AppData\Local\Programs\Python\Python310\lib\site-packages\tb_rest_client\rest_client_ce.py", line 18, in <module> from tb_rest_client.rest_client_base import * File "C:\Users\apsir\AppData\Local\Programs\Python\Python310\lib\site-packages\tb_rest_client\rest_client_base.py", line 20, in <module> from requests import post ModuleNotFoundError: No module named 'requests'

Cannot use get_entity_groups_by_type() method

Version 1.3.2

Running method
dashboard_groups = rest_client.get_entity_groups_by_type('DASHBOARD')

Resulting error

Traceback (most recent call last):
  File "C:\Users\JacksonBowe\Envs\myinsightplatform\lib\site-packages\tb_rest_client\api_client.py", line 338, in __deserialize
    found_class = getattr(tb_rest_client.models.models_ce, klass)
AttributeError: module 'tb_rest_client.models.models_ce' has no attribute 'EntityGroupInfo'

I'm noticing this error is fairly common, where the CE and PE clients are so intertwined that some methods are defaulting to CE without being possible. E.g. same issue happens with get_integrations_get() method.

save_device_attributes not sending data as json object

Example code

      res = rest_client.save_device_attributes(
          body=json.dumps(claiming_json),
          device_id=device.id,
          scope='SERVER_SCOPE'
def save_device_attributes(self, body: str, device_id: DeviceId, scope: str):

requires a string type, but the final call to the rest endpoint, it uses json.dumps again

https://github.com/thingsboard/thingsboard-python-rest-client/blob/master/tb_rest_client/rest.py#L163

                if re.search('json', headers['Content-Type'], re.IGNORECASE):
                    request_body = '{}'
                    if body is not None:
                        request_body = json.dumps(body)

Reason:
HTTP response headers: HTTPHeaderDict({'vary': 'Origin, Access-Control-Request-Method, Access-Control-Request-Headers', 'x-content-type-options': 'nosniff', 'x-xss-protection': '1; mode=block', 'cache-control': 'no-cache, no-store, max-age=0, must-revalidate', 'pragma': 'no-cache', 'expires': '0', 'strict-transport-security': 'max-age=31536000 ; includeSubDomains', 'content-type': 'text/plain;charset=UTF-8', 'content-length': '28', 'date': 'Sat, 09 Oct 2021 05:35:40 GMT'})
HTTP response body: Request is not a JSON object

Probably this is affecting multiple API that are expecting body as string type.

503 error for rest_client.get_attributes

Trying get attributes of customer entity
none of below working

customerId=CustomerId("CUSTOMER","bcba4d70-e778-11eb-93f6-e9c8947e0202")
rest_client.get_attributes(entity_id=customerId,kwargs='{"keys":"asdf"}')
or
customerId=CustomerId("CUSTOMER","bcba4d70-e778-11eb-93f6-e9c8947e0202")
rest_client.get_attributes(entity_id=customerId,kwargs='{"keys":"asdf"}')

gives 503 error
what is right way to call get_attributes for tb_rest_client32.rest_client_ce?

Thanks

Bug: Unhandled exception in rest_client_base.py

When there is a problem with network (or no connection at all), the post function inside login function (rest_client_base.py file) is creating unhandled exceptions. I thing this post function needs timeout, and this function needs to be encapsulated in a try except condition.
tb_rest_client version is 1.3.2

The steps to reproduce:
1- Without and active internet connection, call rest_client.login(username=self.username, password=self.password)
2- you will get error like this:

Aug  8 14:05:33 gasgw-b827ebcd0c4f python3[3420]:     conn.connect()
Aug  8 14:05:33 gasgw-b827ebcd0c4f python3[3420]:   File "/usr/lib/python3/dist-packages/urllib3/connection.py", line 353, in connect
Aug  8 14:05:33 gasgw-b827ebcd0c4f python3[3420]:     conn = self._new_conn()
Aug  8 14:05:33 gasgw-b827ebcd0c4f python3[3420]:   File "/usr/lib/python3/dist-packages/urllib3/connection.py", line 181, in _new_conn
Aug  8 14:05:33 gasgw-b827ebcd0c4f python3[3420]:     raise NewConnectionError(
Aug  8 14:05:33 gasgw-b827ebcd0c4f python3[3420]: urllib3.exceptions.NewConnectionError: <urllib3.connection.HTTPSConnection object at 0xb43c71c0>: Failed to establish a new connection: [Errno 113] No route to host
Aug  8 14:05:33 gasgw-b827ebcd0c4f python3[3420]: During handling of the above exception, another exception occurred:
Aug  8 14:05:33 gasgw-b827ebcd0c4f python3[3420]: Traceback (most recent call last):
Aug  8 14:05:33 gasgw-b827ebcd0c4f python3[3420]:   File "/usr/lib/python3/dist-packages/requests/adapters.py", line 439, in send
Aug  8 14:05:33 gasgw-b827ebcd0c4f python3[3420]:     resp = conn.urlopen(
Aug  8 14:05:33 gasgw-b827ebcd0c4f python3[3420]:   File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 755, in urlopen
Aug  8 14:05:33 gasgw-b827ebcd0c4f python3[3420]:     retries = retries.increment(
Aug  8 14:05:33 gasgw-b827ebcd0c4f python3[3420]:   File "/usr/lib/python3/dist-packages/urllib3/util/retry.py", line 574, in increment
Aug  8 14:05:33 gasgw-b827ebcd0c4f python3[3420]:     raise MaxRetryError(_pool, url, error or ResponseError(cause))
Aug  8 14:05:33 gasgw-b827ebcd0c4f python3[3420]: urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='[load.molisens.com](http://load.molisens.com/)', port=443): Max retries exceeded with url: /api/auth/login (Caused by NewConnectionError('<urllib3.connection.HTTPSConnection object at 0xb43c71c0>: Failed to establish a new connection: [Errno 113] No route to host'))
Aug  8 14:05:33 gasgw-b827ebcd0c4f python3[3420]: During handling of the above exception, another exception occurred:
Aug  8 14:05:33 gasgw-b827ebcd0c4f python3[3420]: Traceback (most recent call last):
Aug  8 14:05:33 gasgw-b827ebcd0c4f python3[3420]:   File "/usr/local/lib/python3.9/dist-packages/tb_rest_client/rest_client_base.py", line 56, in run
Aug  8 14:05:33 gasgw-b827ebcd0c4f python3[3420]:     self.login(self.username, self.password)
Aug  8 14:05:33 gasgw-b827ebcd0c4f python3[3420]:   File "/usr/local/lib/python3.9/dist-packages/tb_rest_client/rest_client_base.py", line 83, in login
Aug  8 14:05:33 gasgw-b827ebcd0c4f python3[3420]:     token_json = post(self.base_url + "/api/auth/login", json={"username": username, "password": password},
Aug  8 14:05:33 gasgw-b827ebcd0c4f python3[3420]:   File "/usr/lib/python3/dist-packages/requests/api.py", line 119, in post
Aug  8 14:05:33 gasgw-b827ebcd0c4f python3[3420]:     return request('post', url, data=data, json=json, **kwargs)
Aug  8 14:05:33 gasgw-b827ebcd0c4f python3[3420]:   File "/usr/lib/python3/dist-packages/requests/api.py", line 61, in request
Aug  8 14:05:33 gasgw-b827ebcd0c4f python3[3420]:     return session.request(method=method, url=url, **kwargs)
Aug  8 14:05:33 gasgw-b827ebcd0c4f python3[3420]:   File "/usr/lib/python3/dist-packages/requests/sessions.py", line 542, in request
Aug  8 14:05:33 gasgw-b827ebcd0c4f python3[3420]:     resp = self.send(prep, **send_kwargs)
Aug  8 14:05:33 gasgw-b827ebcd0c4f python3[3420]:   File "/usr/lib/python3/dist-packages/requests/sessions.py", line 655, in send
Aug  8 14:05:33 gasgw-b827ebcd0c4f python3[3420]:     r = adapter.send(request, **kwargs)
Aug  8 14:05:33 gasgw-b827ebcd0c4f python3[3420]:   File "/usr/lib/python3/dist-packages/requests/adapters.py", line 516, in send
Aug  8 14:05:33 gasgw-b827ebcd0c4f python3[3420]:     raise ConnectionError(e, request=request)

New release anytime soon?

Hi,

I'm using the rest-client in some of my azure-functions.
Unfortunately the newly added token-login method is not part of the most recent pypi-package.
Are there any plans to publish the latest code to pypi anytime soon or can you suggest a workaround?

Tenant Model: ValueError('Invalid value for label, must not be None')

The Tenant Model required fields should line up with the required fields in ThingsBoard.

According to ThingsBoard only Title and Tenant Profile are required in the CE edition.

Could the required values for country, state, city, address, address2, zip, phone and email be removed?

I don't know if changing Title to required will break anything else.

Put in PR #86

Release 1.2 files are wrong

Hi!

Just discovered that the files included in the 1.2 version release is from a previous release (1.1.1 in the setup file).

How to reproduce:

Under the tags view (https://github.com/thingsboard/python_tb_rest_client/tags) we can also see that tag 1.1.2 and 1.2 have the same date and commit hash.

This can be fixed by updating the 1.2 release files to the correct ones.

Have a nice day!

Could not resolve subtype of [simple type, class org.thingsboard.server.common.data.query.EntityFilter]: missing type id property \'type\'

----code start ----------
import logging
from json import load

Importing models and REST client class from Professional Edition version

from tb_rest_client.rest_client_pe import *
from tb_rest_client.rest import ApiException

logging.basicConfig(level=logging.DEBUG,
format='%(asctime)s - %(levelname)s - %(module)s - %(lineno)d - %(message)s',
datefmt='%Y-%m-%d %H:%M:%S')

ThingsBoard REST API URL

url = "http://localhost:8080"

Default Tenant Administrator credentials

username = "[email protected]"
password = "tenant"

Creating the REST client object with context manager to get auto token refresh

with RestClientPE(base_url=url) as rest_client:
try:
# Auth with credentials
rest_client.login(username=username, password=password);

    #// Create entity filter to get all devices
    typeFilter = EntityTypeFilter(entity_type = 'DEVICE');
    #logging.info(typeFilter);

    totalDevicesQuery = EntityCountQuery(entity_filter = typeFilter );
    logging.info(totalDevicesQuery);
    #{'entity_filter': {'entity_type': 'DEVICE'}}
    #totalDevicesCount = rest_client.count_entities_by_query(totalDevicesQuery);
    #logging.info("Total devices by the first query:  \n%r", totalDevicesCount);

except ApiException as e:
	
    logging.exception(e)

---------------code end-------

图片

rest_client.download_ota_package : UnicodeDecodeError: 'utf-8' codec can't decode byte 0x8b in position 1: invalid start byte

While trying to download a gz file as OTA package thanks to thingsboard-python-rest-client
I have this error

Traceback (most recent call last):
  File "ota.py", line 31, in <module>
    downloads=rest_client.download_ota_package(str(first_package.id.id))
  File "/home/ysimonx/Developpement/thingsboard_ota_py/env/lib/python3.8/site-packages/tb_rest_client/rest_client_ce.py", line 589, in download_ota_package
    return self.ota_package_controller.download_ota_package_using_get(ota_package_id=ota_package_id)
  File "/home/ysimonx/Developpement/thingsboard_ota_py/env/lib/python3.8/site-packages/tb_rest_client/api/api_ce/ota_package_controller_api.py", line 142, in download_ota_package_using_get
    (data) = self.download_ota_package_using_get_with_http_info(ota_package_id, **kwargs)  # noqa: E501
  File "/home/ysimonx/Developpement/thingsboard_ota_py/env/lib/python3.8/site-packages/tb_rest_client/api/api_ce/ota_package_controller_api.py", line 201, in download_ota_package_using_get_with_http_info
    return self.api_client.call_api(
  File "/home/ysimonx/Developpement/thingsboard_ota_py/env/lib/python3.8/site-packages/tb_rest_client/api_client.py", line 409, in call_api
    return self.__call_api(resource_path, method,
  File "/home/ysimonx/Developpement/thingsboard_ota_py/env/lib/python3.8/site-packages/tb_rest_client/api_client.py", line 193, in __call_api
    response_data = self.request(
  File "/home/ysimonx/Developpement/thingsboard_ota_py/env/lib/python3.8/site-packages/tb_rest_client/api_client.py", line 431, in request
    return self.rest_client.GET(url,
  File "/home/ysimonx/Developpement/thingsboard_ota_py/env/lib/python3.8/site-packages/tb_rest_client/rest.py", line 237, in GET
    return self.request("GET", url,
  File "/home/ysimonx/Developpement/thingsboard_ota_py/env/lib/python3.8/site-packages/tb_rest_client/rest.py", line 225, in request
    r.data = r.data.decode('utf8')
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x8b in position 1: invalid start byte


The firmware package is a gz file

and of course, this file can not be considered as a "utf-8" string,

It should not be decoded in line 225 of rest.py

` if _preload_content:
r = RESTResponse(r)

        # In the python 3, the response.data is bytes.
        # we need to decode it to string.
        if six.PY3:
            r.data = r.data.decode('utf8')

`

How to reproduce it :



with RestClientCE(base_url=url) as rest_client:
    try:
       
        rest_client.login(username=username, password=password)

       
        packs = rest_client.get_ota_packages_v1(100,0,None, None, None)

        package = packs.data[0]
        
        downloads=rest_client.download_ota_package(package.id.id)

        print(downloads)
        
    except ApiException as e:
        logging.exception(e)


Cannot import 'EntityId' from partially initialized module

Hi,

I've just imported the tb-rest-client on a fresh virtual environment and attempted to run it.
import logging
from tb_rest_client.rest_client_pe import *

I get the following error:
ImportError: cannot import name 'EntityId' from partially initialized module 'tb_rest_client.models.models_ce' (most likely due to a circular import)

from the file
\env\lib\site-packages\tb_rest_client\models\models_ce\__init__.py

Are there additional prerequisite steps that I need to take for this to work?

Cheers

Bug in example_application.py

Hello together,
When running the example_application.py I have the following traceback:

2020-12-20 16:28:09 - INFO - test - 57 -  Device was created:
AttributeError("'str' object has no attribute 'swagger_types'")

Traceback (most recent call last):
  File "C:/Users/vcmorini/Anaconda3/envs/iot/Lib/site-packages/tb_rest_client/models/models_ce/test.py", line 60, in <module>
    relation = EntityRelation(_from=asset.id, to=device.id, type="Contains")
AttributeError: 'AttributeError' object has no attribute 'id'

The error occurs in this line:
device = rest_client.save_device(device)
Any suggestions?

Asset Model expects label to always be not None

If an asset has been created within Thingsboard and saved without a Label value, then you cannot access this object via the Python API.
A ValueError is raised within this file on line 234.

I assume the fix here is to change the swagger definition held elsewhere?

Incomplete EntityFilter Class

Describe the bug
When using the example provided on Python Rest Client - Count entities using Entity Data Query API Example this will result in a JSON parse error.

2022-04-26 09:42:48 - ERROR - Thingsboard_Python_Rest_Example - 38 - (400)
Reason:
HTTP response headers: HTTPHeaderDict({'Date': 'Tue, 26 Apr 2022 07:42:48 GMT', 'Content-Type': 'application/json', 'Transfer-Encoding': 'chunked', 'Connection': 'keep-alive', 'Vary': 'Origin, Access-Control-Request-Method, Access-Control-Request-Headers', 'X-Content-Type-Options': 'nosniff', 'X-XSS-Protection': '1; mode=block', 'Cache-Control': 'no-cache, no-store, max-age=0, must-revalidate', 'Pragma': 'no-cache', 'Expires': '0', 'Strict-Transport-Security': 'max-age=15724800; includeSubDomains'})
HTTP response body: {"status":400,"message":"JSON parse error: Missing type id when trying to resolve subtype of [simple type, class org.thingsboard.server.common.data.query.EntityFilter]: missing type id property 'type' (for POJO property 'entityFilter'); nested exception is com.fasterxml.jackson.databind.exc.InvalidTypeIdException: Missing type id when trying to resolve subtype of [simple type, class org.thingsboard.server.common.data.query.EntityFilter]: missing type id property 'type' (for POJO property 'entityFilter')\n at [Source: (PushbackInputStream); line: 1, column: 19] (through reference chain: org.thingsboard.server.common.data.query.EntityCountQuery[\"entityFilter\"])","errorCode":31,"timestamp":"2022-04-26T07:42:48.286+00:00","subscriptionErrorCode":null,"subscriptionEntry":null,"subscriptionValue":null}
Traceback (most recent call last):
  File "C:\Users\vos\source\repos\Thingsboard Python Rest Example\Thingsboard Python Rest Example\Thingsboard_Python_Rest_Example.py", line 34, in <module>
    devices_count = client.count_entities_by_query(devices_query)
  File "C:\Users\vos\AppData\Local\Programs\Python\Python310\lib\site-packages\tb_rest_client\rest_client_base.py", line 788, in count_entities_by_query
    return self.entity_query_controller.count_entities_by_query_using_post(body=body)
  File "C:\Users\vos\AppData\Local\Programs\Python\Python310\lib\site-packages\tb_rest_client\api\api_ce\entity_query_controller_api.py", line 53, in count_entities_by_query_using_post
    (data) = self.count_entities_by_query_using_post_with_http_info(body, **kwargs)  # noqa: E501
  File "C:\Users\vos\AppData\Local\Programs\Python\Python310\lib\site-packages\tb_rest_client\api\api_ce\entity_query_controller_api.py", line 116, in count_entities_by_query_using_post_with_http_info
    return self.api_client.call_api(
  File "C:\Users\vos\AppData\Local\Programs\Python\Python310\lib\site-packages\tb_rest_client\api_client.py", line 409, in call_api
    return self.__call_api(resource_path, method,
  File "C:\Users\vos\AppData\Local\Programs\Python\Python310\lib\site-packages\tb_rest_client\api_client.py", line 193, in __call_api
    response_data = self.request(
  File "C:\Users\vos\AppData\Local\Programs\Python\Python310\lib\site-packages\tb_rest_client\api_client.py", line 451, in request
    return self.rest_client.POST(url,
  File "C:\Users\vos\AppData\Local\Programs\Python\Python310\lib\site-packages\tb_rest_client\rest.py", line 272, in POST
    return self.request("POST", url,
  File "C:\Users\vos\AppData\Local\Programs\Python\Python310\lib\site-packages\tb_rest_client\rest.py", line 231, in request
    raise ApiException(http_resp=r)
tb_rest_client.rest.ApiException: (400)
Reason:
HTTP response headers: HTTPHeaderDict({'Date': 'Tue, 26 Apr 2022 07:42:48 GMT', 'Content-Type': 'application/json', 'Transfer-Encoding': 'chunked', 'Connection': 'keep-alive', 'Vary': 'Origin, Access-Control-Request-Method, Access-Control-Request-Headers', 'X-Content-Type-Options': 'nosniff', 'X-XSS-Protection': '1; mode=block', 'Cache-Control': 'no-cache, no-store, max-age=0, must-revalidate', 'Pragma': 'no-cache', 'Expires': '0', 'Strict-Transport-Security': 'max-age=15724800; includeSubDomains'})
HTTP response body: {"status":400,"message":"JSON parse error: Missing type id when trying to resolve subtype of [simple type, class org.thingsboard.server.common.data.query.EntityFilter]: missing type id property 'type' (for POJO property 'entityFilter'); nested exception is com.fasterxml.jackson.databind.exc.InvalidTypeIdException: Missing type id when trying to resolve subtype of [simple type, class org.thingsboard.server.common.data.query.EntityFilter]: missing type id property 'type' (for POJO property 'entityFilter')\n at [Source: (PushbackInputStream); line: 1, column: 19] (through reference chain: org.thingsboard.server.common.data.query.EntityCountQuery[\"entityFilter\"])","errorCode":31,"timestamp":"2022-04-26T07:42:48.286+00:00","subscriptionErrorCode":null,"subscriptionEntry":null,"subscriptionValue":null}

Reason
The EntityFilter() Class is incomplete - it is missing all required properties/attributes. It seems that the swagger definition does not specify the model and therefore the generated code is missing stuff.

Cheers

https failed

os: win10
server: CE 3.2.0
client: pip install tb_rest_client32

problem:

from tb_rest_client32.rest_client_ce import *
from tb_rest_client32.rest import ApiException
base_url = "https://test2.bj-jiashi.com:10005"
rest_client = RestClientCE(base_url=base_url)
rest_client.configuration.verify_ssl=r'config\rootCA.pem'
rest_client.login(username="[email protected]", password="xxx") # works

# Creating an Asset
asset = Asset(name="Building 1", type="building")
asset = rest_client.save_asset(asset) # raise error

error:

2021-03-07 11:17:24,254 WARNING Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError(SSLError("bad handshake: Error([('SSL routines', 'tls_process_server_certificate', 'certificate verify failed')])"))': /api/asset
2021-03-07 11:17:24,303 WARNING Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError(SSLError("bad handshake: Error([('SSL routines', 'tls_process_server_certificate', 'certificate verify failed')])"))': /api/asset
2021-03-07 11:17:24,354 WARNING Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError(SSLError("bad handshake: Error([('SSL routines', 'tls_process_server_certificate', 'certificate verify failed')])"))': /api/asset
Traceback (most recent call last):
  File "C:\ProgramData\Miniconda3\lib\site-packages\urllib3\contrib\pyopenssl.py", line 485, in wrap_socket
    cnx.do_handshake()
  File "C:\ProgramData\Miniconda3\lib\site-packages\OpenSSL\SSL.py", line 1934, in do_handshake
    self._raise_ssl_error(self._ssl, result)
  File "C:\ProgramData\Miniconda3\lib\site-packages\OpenSSL\SSL.py", line 1671, in _raise_ssl_error
    _raise_current_error()
  File "C:\ProgramData\Miniconda3\lib\site-packages\OpenSSL\_util.py", line 54, in exception_from_error_queue
    raise exception_type(errors)
OpenSSL.SSL.Error: [('SSL routines', 'tls_process_server_certificate', 'certificate verify failed')]

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\ProgramData\Miniconda3\lib\site-packages\urllib3\connectionpool.py", line 672, in urlopen
    chunked=chunked,
  File "C:\ProgramData\Miniconda3\lib\site-packages\urllib3\connectionpool.py", line 376, in _make_request
    self._validate_conn(conn)
  File "C:\ProgramData\Miniconda3\lib\site-packages\urllib3\connectionpool.py", line 994, in _validate_conn
    conn.connect()
  File "C:\ProgramData\Miniconda3\lib\site-packages\urllib3\connection.py", line 360, in connect
    ssl_context=context,
  File "C:\ProgramData\Miniconda3\lib\site-packages\urllib3\util\ssl_.py", line 370, in ssl_wrap_socket
    return context.wrap_socket(sock, server_hostname=server_hostname)
  File "C:\ProgramData\Miniconda3\lib\site-packages\urllib3\contrib\pyopenssl.py", line 491, in wrap_socket
    raise ssl.SSLError("bad handshake: %r" % e)
ssl.SSLError: ("bad handshake: Error([('SSL routines', 'tls_process_server_certificate', 'certificate verify failed')])",)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\ProgramData\Miniconda3\lib\site-packages\tb_rest_client32\rest_client_base.py", line 118, in save_asset
    return self.asset_controller.save_asset_using_post(asset, **kwargs)
  File "C:\ProgramData\Miniconda3\lib\site-packages\tb_rest_client32\api\api_ce\asset_controller_api.py", line 1371, in save_asset_using_post
    (data) = self.save_asset_using_post_with_http_info(asset, **kwargs)  # noqa: E501
  File "C:\ProgramData\Miniconda3\lib\site-packages\tb_rest_client32\api\api_ce\asset_controller_api.py", line 1443, in save_asset_using_post_with_http_info     
    collection_formats=collection_formats)
  File "C:\ProgramData\Miniconda3\lib\site-packages\tb_rest_client32\api_client.py", line 423, in call_api
    _preload_content, _request_timeout)
  File "C:\ProgramData\Miniconda3\lib\site-packages\tb_rest_client32\api_client.py", line 198, in __call_api
    _request_timeout=_request_timeout)
  File "C:\ProgramData\Miniconda3\lib\site-packages\tb_rest_client32\api_client.py", line 466, in request
    body=body)
  File "C:\ProgramData\Miniconda3\lib\site-packages\tb_rest_client32\rest.py", line 278, in POST
    body=body)
  File "C:\ProgramData\Miniconda3\lib\site-packages\tb_rest_client32\rest.py", line 170, in request
    headers=headers)
  File "C:\ProgramData\Miniconda3\lib\site-packages\urllib3\request.py", line 80, in request
    method, url, fields=fields, headers=headers, **urlopen_kw
  File "C:\ProgramData\Miniconda3\lib\site-packages\urllib3\request.py", line 171, in request_encode_body
    return self.urlopen(method, url, **extra_kw)
  File "C:\ProgramData\Miniconda3\lib\site-packages\urllib3\poolmanager.py", line 330, in urlopen
    response = conn.urlopen(method, u.request_uri, **kw)
  File "C:\ProgramData\Miniconda3\lib\site-packages\urllib3\connectionpool.py", line 760, in urlopen
    **response_kw
  File "C:\ProgramData\Miniconda3\lib\site-packages\urllib3\connectionpool.py", line 760, in urlopen
    **response_kw
  File "C:\ProgramData\Miniconda3\lib\site-packages\urllib3\connectionpool.py", line 760, in urlopen
    **response_kw
  File "C:\ProgramData\Miniconda3\lib\site-packages\urllib3\connectionpool.py", line 720, in urlopen
    method, url, error=e, _pool=self, _stacktrace=sys.exc_info()[2]
  File "C:\ProgramData\Miniconda3\lib\site-packages\urllib3\util\retry.py", line 436, in increment
    raise MaxRetryError(_pool, url, error or ResponseError(cause))
urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='test2.bj-jiashi.com', port=10005): Max retries exceeded with url: /api/asset (Caused by SSLError(SSLError("bad handshake: Error([('SSL routines', 'tls_process_server_certificate', 'certificate verify failed')])")))

discuss:
requests works for some cases

# works if ignore https
requests.get(base_url,verify=False)
# works if using rootCA.pem generated by mkcert
requests.get(base_url,verify=r'config\rootCA.pem')
# work if using chrome exported cert in base64 format
requests.get(base_url,verify=r'config\base64_x509_rootCA.cer')
# fail if using chrome exported cert in der format
requests.get(base_url,verify=r'config\der_x509_rootCA.cer')

[SelfHosted]RestClientCE no attribute 'auth_controller' TB version 3.3.4, TB-Client versin 1.3.2

Having a error using scripts from official documentation.

OS: Windows 10 Python: 3.10.1

Traceback (most recent call last):
  File "D:\Python projecs\pythonProject\main.py", line 37, in <module>
    user = rest_client.get_user()
  File "C:\Users\User\AppData\Roaming\Python\Python310\site-packages\tb_rest_client\rest_client_ce.py", line 316, in get_user
    return self.auth_controller.get_user_using_get()
AttributeError: 'RestClientCE' object has no attribute 'auth_controller'

Some times get error with ssl certification
ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:997)

When I start script sever die for 30-45mins

bug: EntityGroupId model does not fit api response

Hi,

while working with RestClientPE I used the method get_entity_groups_by_type("DEVICE"), as a result I received a list with this:
AttributeError("module 'tb_rest_client.models.models_ce' has no attribute 'EntityGroupId'")

When I started to look into it with the debugger I discovered, that the error happens in api_client.py in the method def __deserialize(self, data, klass): .

My guess is that the API send back this response:

[
  {
    "id": {
      "entityType": "ENTITY_GROUP",
      "id": "---"
    },
    "createdTime": 1648113081174,
    "type": "DEVICE",
    "name": "All",
    "ownerId": {
      "entityType": "TENANT",
      "id": "---"
    },
    "additionalInfo": null,
    "configuration": {
      "columns": [
        {
          "type": "ENTITY_FIELD",
          "key": "created_time",
          "sortOrder": "DESC"
        },
...

but in the entity_group_id model there is no field entityType only id , so this does not fit and provoke the error

Token get expired even though the thread is started

The problem is that thread function

 def run(self):
        self.stopped = False
        while not self.stopped:
            try:
                check_time = time()
                if check_time >= self.token_info["refreshToken"] and self.logged_in:
                    if self.username and self.password:
                        self.login(self.username, self.password)
                    else:
                        logger.error("No username or password provided!")
                sleep(1)
            except Exception as e:
                logger.exception(e)
                break
            except KeyboardInterrupt:
                break

checks the self.token_info["refreshToken"], but self.token_info attribute is not updated in the login method:

    def login(self, username, password):
        """Authorization on the host and saving the toke information"""
        if self.username is None and self.password is None:
            self.username = username
            self.password = password
            self.logged_in = True

        token_json = post(self.base_url + "/api/auth/login", json={"username": username, "password": password}).json()
        token = None
        if isinstance(token_json, dict) and token_json.get("token") is not None:
            token = token_json["token"]
        self.configuration.api_key_prefix["X-Authorization"] = "Bearer"
        self.configuration.api_key["X-Authorization"] = token

        self.api_client = ApiClient(self.configuration)
        self.__load_controllers()

I presume that token_json variable here and following lines - was meant to be self.token_info and all would be working fine.

Update:

it will not work, it is also needed to parse the token expiration from the token.

Connection Reset by Peer when using example code

used tb_rest_client: pip install tb_rest_client
as well as: pip install tb_rest_client32
(V1.2)

tested operating systems:
Windows10 and Ubuntu 18.04

code:

import logging
# Importing models and REST client class from Community Edition version
from tb_rest_client.rest_client_ce import *
from tb_rest_client.rest import ApiException
#from tb_rest_client32.rest_client_ce import *
#from tb_rest_client32.rest import ApiException

logging.basicConfig(level=logging.DEBUG,
                    format='%(asctime)s - %(levelname)s - %(module)s - %(lineno)d - %(message)s',
                    datefmt='%Y-%m-%d %H:%M:%S')

# ThingsBoard REST API URL
url = "http://XXX:8080"

# Default Tenant Administrator credentials
username = "[email protected]"
password = "tenant"

# Creating the REST client object with context manager to get auto token refresh
with RestClientCE(base_url=url) as rest_client:
    try:
        # Auth with credentials
        rest_client.login(username=username, password=password)
        user = rest_client.get_user()
        print(user)
    except ApiException as e:
        logging.exception(e)

behavior:
requests.exceptions.ConnectionError: ('Connection aborted.', ConnectionResetError(10054, 'Eine vorhandene Verbindung wurde vom Remotehost geschlossen', None, 10054, None))
raise ConnectionError(err, request=request)
requests.exceptions.ConnectionError: ('Connection aborted.', ConnectionResetError(104, 'Connection reset by peer'))

expected behavior:
no Exception and simple login.

test with curl:

curl -X POST --header "Content-Type: application/json" --header "Accept: application/json" -d "{\"username\":\"[email protected]\", \"password\":\"tenant\"}" "http://XXX.com:8080/api/auth/login"

returns the token

(you could use the " in your guide for curl to make it natively work with windows which is default for many first time users out there I guess)

audit log:
shows success on login with python client:

  "browser": "Python Requests 2.25",
  "os": "Other",
  "device": "Other"

sysadmin-panel:
base-url is still localhost - should this be edited?

Incorrect parsing of "Device" json data

The json data, containing device data, returned by the device_controller functions (for example get_tenant_device, get_customer_devices, etc..) is not being mappedn/parsed correctly to a Device class. That is because of the function __deserialie(self, data, klass) of the class ApiClient (api_client.py), which cannot determine the correct class to which to desiarilize:

...
                    found_class = getattr(tb_rest_client.models.models_pe, klass)
                    # if sorted(list(found_class.attribute_map.values())) == sorted(list(data.keys())):
                    if all(attr in list(found_class.attribute_map.values()) for attr in list(data.keys())):
                        klass = found_class

Here the code is unable to match the attributes of the model class to those of the pre-parsed data and thus is not able to parse it further to Device class, using the __deserialize_data,which should call __deserialize_model with klass from type Device, but calls it with type "string" instead ('Device')

TB Version is 3.2.1

AttributeError: 'RestClientCE' object has no attribute 'auth_controller'

Attempting to run through the examples using Python 3 on Mac OS and am getting AttributeErrors. All the examples fail but the most recent is:

>>> with RestClientCE(base_url=url) as rest_client:
...     user = rest_client.get_user()
...     print(user)
... 
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
  File "/usr/local/lib/python3.9/site-packages/tb_rest_client/rest_client_base.py", line 220, in get_user
    return self.auth_controller.get_user_using_get()
AttributeError: 'RestClientCE' object has no attribute 'auth_controller'

Version information:
Python 3.9.5 (default, May 4 2021, 03:33:11)
[Clang 12.0.0 (clang-1200.0.32.29)] on darwin

Installed with pip3 install tb-rest-client

Output of pip3 list:

Package                       Version
----------------------------- ---------
alabaster                     0.7.12
arlo                          1.2.47
attrs                         21.2.0
Babel                         2.9.1
beautifulsoup4                4.9.3
breathe                       4.30.0
bs4                           0.0.1
certifi                       2020.12.5
chardet                       4.0.0
docutils                      0.16
exhale                        0.2.3
idna                          2.10
imagesize                     1.2.0
Jinja2                        3.0.1
jsonschema                    4.2.1
lxml                          4.6.3
MarkupSafe                    2.0.1
monotonic                     1.6
packaging                     20.9
paho-mqtt                     1.5.1
pip                           21.3.1
Pygments                      2.9.0
pyparsing                     2.4.7
pyrsistent                    0.18.0
PySocks                       1.7.1
python-dateutil               2.8.2
pytz                          2021.1
requests                      2.25.1
setuptools                    56.0.0
six                           1.16.0
snowballstemmer               2.1.0
soupsieve                     2.2.1
Sphinx                        4.0.2
sphinx-rtd-theme              0.5.2
sphinxcontrib-applehelp       1.0.2
sphinxcontrib-devhelp         1.0.2
sphinxcontrib-htmlhelp        2.0.0
sphinxcontrib-jsmath          1.0.1
sphinxcontrib-qthelp          1.0.3
sphinxcontrib-serializinghtml 1.1.5
sseclient                     0.0.22
tb-mqtt-client                1.2
tb-rest-client                1.3.2
urllib3                       1.26.4
wheel                         0.36.2

Sample application fails: def load_user_group_permission_infos TypeError: 'type' object is not subscriptable

Upgraded to the newest version using
pip3 install --upgrade tb-rest-client

Running the example application results in the following error:

# python3 ./example_application_2.py 
Traceback (most recent call last):
  File "./example_application_2.py", line 5, in <module>
    from tb_rest_client.rest_client_pe import *
  File "/usr/local/lib/python3.7/dist-packages/tb_rest_client/rest_client_pe.py", line 26, in <module>
    class RestClientPE(RestClientBase):
  File "/usr/local/lib/python3.7/dist-packages/tb_rest_client/rest_client_pe.py", line 331, in RestClientPE
    def load_user_group_permission_infos(self, body: list[GroupPermission]):
TypeError: 'type' object is not subscriptable

This issue persists even if using tb_rest_client.rest_client_ce:

# python3 ./example_application_2.py 
Traceback (most recent call last):
  File "./example_application_2.py", line 5, in <module>
    from tb_rest_client.rest_client_ce import *
  File "/usr/local/lib/python3.7/dist-packages/tb_rest_client/rest_client_ce.py", line 22, in <module>
    class RestClientCE(RestClientBase):
  File "/usr/local/lib/python3.7/dist-packages/tb_rest_client/rest_client_ce.py", line 482, in RestClientCE
    def add_dashboard_customers(self, body: list[str], dashboard_id: DashboardId):
TypeError: 'type' object is not subscriptable

This issue persists even if using the latest master via # python3 -m pip install git+https://github.com/thingsboard/thingsboard-python-rest-client.

Error about invalid "device_profile_id" value when creating device via API

We have some BLE sniffers to detect devices that send out advertising packets. I want to use the ThingsBoard REST client to add these devices to our server, and am following this Python API example: https://thingsboard.io/docs/reference/python-rest-client

However, the script gives me a ValueError when the Device constructor is called:

ValueError: Invalid value for `device_profile_id`, must not be `None`

It appears a DeviceProfileId object needs to be passed to the constructor as the device_profile_id parameter. But none of the examples do this. I tried to create a new DeviceProfileId object with a dummy UUID, but the API returns an error saying the UUID string is invalid or that the device is referencing a non-existent profile.

Am I doing something wrong? Or is the DeviceProfileId object a new requirement that was added in recent API versions?

ValueError('Invalid value for `label`, must not be `None`')

Hi I'm trying to run some old-ish (a couple of months) script I had to download data from a thingsboard instance.
Whenever I try to list devices, e.g. with get_customer_devices or get_tenant_devices I get the error in subject.

My devices never had the label field set and up until now I never thought it to be mandatory, did anything change in this sense or maybe it's some recent regression?

I'm using current master

Sample code fails: ImportError: cannot import name 'EntityId' from 'tb_rest_client.models.models_ce'

Running pip3 install tb-rest-client, then running the sample applications after adapting the REST API URL and Tenant Administrator credentials gives the following error message:

user@machine:~/thb-demo# /usr/bin/python3 ./thb-demo.py 
Traceback (most recent call last):
  File "./thb-demo.py", line 5, in <module>
    from tb_rest_client.rest_client_ce import *
  File "/usr/local/lib/python3.7/dist-packages/tb_rest_client/rest_client_ce.py", line 17, in <module>
    from tb_rest_client.rest_client_base import *
  File "/usr/local/lib/python3.7/dist-packages/tb_rest_client/rest_client_base.py", line 24, in <module>
    from tb_rest_client.api.api_ce import *
  File "/usr/local/lib/python3.7/dist-packages/tb_rest_client/api/api_ce/__init__.py", line 1, in <module>
    from .o_auth_2_config_template_controller_api import OAuth2ConfigTemplateControllerApi
  File "/usr/local/lib/python3.7/dist-packages/tb_rest_client/api/api_ce/o_auth_2_config_template_controller_api.py", line 20, in <module>
    from tb_rest_client.api_client import ApiClient
  File "/usr/local/lib/python3.7/dist-packages/tb_rest_client/api_client.py", line 32, in <module>
    import tb_rest_client.models.models_ce
  File "/usr/local/lib/python3.7/dist-packages/tb_rest_client/models/models_ce/__init__.py", line 3, in <module>
    from .admin_settings_id import AdminSettingsId
  File "/usr/local/lib/python3.7/dist-packages/tb_rest_client/models/models_ce/admin_settings_id.py", line 17, in <module>
    from . import EntityId
ImportError: cannot import name 'EntityId' from 'tb_rest_client.models.models_ce' (/usr/local/lib/python3.7/dist-packages/tb_rest_client/models/models_ce/__init__.py)

The same issue persists regardless of whether tb_rest_client.rest_client_ce or tb_rest_client.rest_client_pe are imported.

[Feature] Support exporting of telemetry data using python PE rest client

Description:
Currently we are missing support for some important feature in the python tb rest client version 1.4 , for eg: getting telemetry data

As i can see in github source code, we are not loading this telemetry module
[1] https://github.com/thingsboard/thingsboard-python-rest-client/blob/master/tb_rest_client/rest_client_pe.py#L1567&#L1608

Expected behavior:
User should be able to get telemetry data using python rest client.

Additional Information:
python rest client version: 1.4

there is no public login method

Hi, I recently discovered that the REST Api allows public login with a request on api/auth/login/public with a payload {publicId: my-public-customer-id}.

Then I can query assets, devices and timeseries using my public customer id.

Is there a way to do this from tb-rest-client? it shouldn't be that hard, something like this should work:

def public_login(self, publicId):
        token_json = post(self.base_url + "/api/auth/login/public", json={"publicId": publicId},
                          verify=self.configuration.verify_ssl).json()
        token = None
        if isinstance(token_json, dict) and token_json.get("token") is not None:
            token = token_json["token"]
        self.configuration.api_key_prefix["X-Authorization"] = "Bearer"
        self.configuration.api_key["X-Authorization"] = token
        self.token_info['token'] = token

        self.api_client = ApiClient(self.configuration)
        self.load_controllers()

I could open a pull request if there's any interest... not sure if missing username and password would upset anything in RestClientBase though.

List object has no attribute 'keys' in __deserialize() in api_client.py

steps to reproduce:
call rest_client.get_attributes_by_scope(id, 'SERVER_SCOPE', 'active')

exception output:

Exception has occurred: AttributeError 'list' object has no attribute 'keys' File "/home/jaime/.pyenv/versions/prosegur3.8/lib/python3.8/site-packages/tb_rest_client/api_client.py", line 327, in __deserialize if all(attr in list(found_class.attribute_map.values()) for attr in list(data.keys())): File "/home/jaime/.pyenv/versions/prosegur3.8/lib/python3.8/site-packages/tb_rest_client/api_client.py", line 287, in deserialize return self.__deserialize(data, response_type) File "/home/jaime/.pyenv/versions/prosegur3.8/lib/python3.8/site-packages/tb_rest_client/api_client.py", line 205, in __call_api return_data = self.deserialize(response_data, response_type) File "/home/jaime/.pyenv/versions/prosegur3.8/lib/python3.8/site-packages/tb_rest_client/api_client.py", line 390, in call_api return self.__call_api(resource_path, method, File "/home/jaime/.pyenv/versions/prosegur3.8/lib/python3.8/site-packages/tb_rest_client/api/api_ce/telemetry_controller_api.py", line 695, in get_attributes_by_scope_using_get_with_http_info return self.api_client.call_api( File "/home/jaime/.pyenv/versions/prosegur3.8/lib/python3.8/site-packages/tb_rest_client/api/api_ce/telemetry_controller_api.py", line 619, in get_attributes_by_scope_using_get (data) = self.get_attributes_by_scope_using_get_with_http_info(entity_type, entity_id, scope, **kwargs) # noqa: E501 File "/home/jaime/.pyenv/versions/prosegur3.8/lib/python3.8/site-packages/tb_rest_client/rest_client_base.py", line 617, in get_attributes_by_scope return self.telemetry_controller.get_attributes_by_scope_using_get(entity_id=entity_id.id, File "/home/jaime/XXX/XXX/thingsboard-scheduler/TbScheduler/TbScheduler.py", line 30, in reset_status semaphore['status'] = self.rest_client.get_attributes_by_scope(id, 'SERVER_SCOPE', 'active') File "/home/jaime/XXX/XXX/thingsboard-scheduler/TbScheduler/TbInterface.py", line 70, in inner return func(*args, **kwargs) File "/home/jaime/XXX/XXX/thingsboard-scheduler/main.py", line 13, in <module> tb_scheduler.reset_status() File "/usr/lib/python3.8/runpy.py", line 87, in _run_code exec(code, run_globals) File "/usr/lib/python3.8/runpy.py", line 194, in _run_module_as_main return _run_code(code, main_globals, None, File "/usr/lib/python3.8/runpy.py", line 87, in _run_code exec(code, run_globals) File "/usr/lib/python3.8/runpy.py", line 194, in _run_module_as_main return _run_code(code, main_globals, None,

Error when using "get_integrations_get"

I'm unable to use the titled feature. Below is the code I am running

with RestClientPE(base_url=url) as rest_client:
    try:
        rest_client.login(username=username, password=password)
        logging.info('Logging in')
        integrations = rest_client.get_integrations_get(1000, 0)
        print(integrations)
        print(type(integrations))

Produces the following error:

2021-09-10 10:40:31 - INFO - 3_1_1_main - 140 - Logging in
module 'tb_rest_client.models.models_ce' has no attribute 'Integration'
<class 'AttributeError'>

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.