List Thing Properties via the Python API

I'm trying to list the properties of a Thing using the Python API, but I'm having a bit of trouble.

Firstly, I'm running Python 3.10.5 on a Windows 11 PC. To test my set-up I first ran the example in the API github repo here and it correctly generates an access token and then lists my devices. So my set-up is showing signs of working.

I then combined the access key generation section of that same example with the Python example of how to use the propertiesV2List method which I found in the API reference here.

This is the resulting code:

import time
from pprint import pprint
import iot_api_client as iot
import openapi_client
from openapi_client.rest import ApiException
from oauthlib.oauth2 import BackendApplicationClient
from requests_oauthlib import OAuth2Session

###################################################################################
# Secret keys and stuff
###################################################################################
CLIENT_ID = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
CLIENT_SECRET = "YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY"
DEVICE_ID = "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"

###################################################################################
# Generate an access token
# Follows example from:
# https://github.com/arduino/iot-client-py/blob/master/example/main.py
###################################################################################
# Setup the OAuth2 session that'll be used to request the server an access token
oauth_client = BackendApplicationClient(client_id=CLIENT_ID)
token_url = "https://api2.arduino.cc/iot/v1/clients/token"
oauth = OAuth2Session(client=oauth_client)

# This will fire an actual HTTP call to the server to exchange client_id and
# client_secret with a fresh access token
token = oauth.fetch_token(
    token_url=token_url,
    client_id=CLIENT_ID,
    client_secret=CLIENT_SECRET,
    include_client_id=True,
    audience="https://api2.arduino.cc/iot",
)

# If we get here we got the token, print its expiration time
print("Got a token, expires in {} seconds".format(token.get("expires_in")))

######################################################################
# Fetch the properties of my Thing.
# Follows example from Aduino IoT API documentation:
# https://www.arduino.cc/reference/en/iot/api/#api-DevicesV2-devicesV2GetProperties
######################################################################

# Configure OAuth2 access token for authorization: oauth2
openapi_client.configuration.access_token = token.get("access_token")

# create an instance of the API class
api_instance = openapi_client.PropertiesV2Api()

# Boolean | If true, shows the soft deleted properties (optional) (default to false)
showDeleted = True

try: 
    # list properties_v2
    api_response = api_instance.properties_v2_list(DEVICE_ID, showDeleted=showDeleted)
    pprint(api_response)
except ApiException as e:
    print("Exception when calling PropertiesV2Api->propertiesV2List: %s\n" % e)

When I run it, I get the error message below telling me that 'openapi_client' has no attribute 'PropertiesV2Api'

Got a token, expires in 300 seconds
Traceback (most recent call last):
  File "c:\Users\robsm\OneDrive\Documents\Proj\Python_VS\arduino-api\blink.py", line 49, in <module>
    api_instance = openapi_client.PropertiesV2Api()
AttributeError: module 'openapi_client' has no attribute 'PropertiesV2Api'

That line is copied straight out of the reference example, so I'm not sure what is going on.

Can anyone help with this?

If I list the attributes of openapi_client using print(dir(openapi_client)) I get the response below.

['ApiAttributeError', 'ApiClient', 'ApiException', 'ApiKeyError', 'ApiTypeError', 'ApiValueError', 'Configuration', 'OpenApiException', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__path__', '__spec__', '__version__', 'api_client', 'configuration', 'exceptions', 'model_utils', 'rest']

So I agree with the error message that 'openapi_client' has no attribute 'PropertiesV2Api' and I
begin to wonder how the example in the API reference ever worked.

I note that the Python example contains true instead of True, so it has never actually been executed.

It looks like the Python examples in the in the API reference are wrong. Well the ones I have tried at least.

I took the github example as a model for other commands and it sprang to life. Here is the working method to list the properties of a Thing:

from pprint import pprint
import iot_api_client as iot
from openapi_client.rest import ApiException
from oauthlib.oauth2 import BackendApplicationClient
from requests_oauthlib import OAuth2Session

###################################################################################
# Secret keys and stuff
###################################################################################
CLIENT_ID     = "XXXXXXXXXXXXXXXXXXXX"
CLIENT_SECRET = "YYYYYYYYYYYYYYYYYYYY"
THING_ID      = "ZZZZZZZZZZZZZZZZZZZZ"

###################################################################################
# Generate an access token
# Follows example from:
# https://github.com/arduino/iot-client-py/blob/master/example/main.py
###################################################################################
# Setup the OAuth2 session that'll be used to request the server an access token
oauth_client = BackendApplicationClient(client_id=CLIENT_ID)
token_url = "https://api2.arduino.cc/iot/v1/clients/token"
oauth = OAuth2Session(client=oauth_client)

# This will fire an actual HTTP call to the server to exchange client_id and
# client_secret with a fresh access token
token = oauth.fetch_token(
    token_url=token_url,
    client_id=CLIENT_ID,
    client_secret=CLIENT_SECRET,
    include_client_id=True,
    audience="https://api2.arduino.cc/iot",
)

# If we get here we got the token, print its expiration time
print("Got a token, expires in {} seconds".format(token.get("expires_in")))

######################################################################
# List the properties of my Thing.
#
# Do not follow the example from Arduino IoT API documentation. It doesn't work:
# https://www.arduino.cc/reference/en/iot/api/#api-PropertiesV2-propertiesV2List
#
# Use this as a model instead:
# https://github.com/arduino/iot-client-py/blob/master/example/main.py
######################################################################

# Now we setup the iot-api Python client, first of all create a
# configuration object. The access token goes in the config object.
client_config = iot.Configuration(host="https://api2.arduino.cc/iot")
# client_config.debug = True
client_config.access_token = token.get("access_token")
# Create the iot-api Python client with the given configuration
client = iot.ApiClient(client_config)

properties = iot.PropertiesV2Api(client)

try:
    resp = properties.properties_v2_list(THING_ID)
    print("Response from server:")
    print(resp)
except iot.ApiException as e:
    print("An exception occurred: {}".format(e))

To whom should I report documentation issues?

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.

Hello,

Wanted to ask if you’re still using this API code in Python with success. I copied it and ran it on a new server running Python 3.11. The code aborts during the line,

resp = properties.properties_v2_list(THING_ID)

I have similar Python scripts using other API functions that are working on the new server. But properties_v2_list is giving me problems.

Thanks!

Hello,

No, I don’t use that API any more. I have my Raspberry Pi registered as a Thing these days.

Funny, I went the other way, using RPi before IOT Cloud.

If it’s of interest on the API and to help update the thread, I came up with a work-around using the Curl API and embedding into Python. Very easy and more intuitive IMHO, less import libraries too!

https://forum.arduino.cc/t/python-iot-api-client-exceptions-apiexception-405/1401401/3

1 Like