Updating Limble Asset Information through Ignition

Your LLM steered you wrong and gave you a lot more code than you need; they're quite good at that.

This is less code and does the same as what you wrote, but with better error handling and usable from any scope, not just callable from Perspective. You can drop this into the project library.

# ================================
# Limble API credentials
# ================================
# These credentials are used to authenticate with the Limble CMMS API.
# client_id and client_secret are provided when you register an application
# or integration with Limble.
__client_id = "add your client id here"
__client_secret = "add your secret token here"

__client = system.net.httpClient(username=__client_id, password=__client_secret)

__logger = system.util.getLogger("LimbleApi")

def updateAsset(value_id, new_value):
	update_url = "https://api.limblecmms.com:443/v2/assets/fields/{}/".format(value_id)

	update_data = {
		"value": new_value
	}

	try:
		update_response = __client.patch(
			url=update_url,
			data=update_data
		)

		__logger.infof("Updated %s successfully: %s", value_id, update_response.text)
	except Exception as e:
		__logger.errorf("Error updating %s: %s", value_id, e)
	except java.lang.Exception as ex:
		__logger.errorf("Error updating %s", value_id, ex)

Particular tips:

  1. Never import anything from system - the system namespace is already brought in automatically.
  2. Don't use Python's json module, use system.util.jsonEncode/system.util.jsonDecode because they're more likely to understand Ignition/Java objects than the base Python library.
  3. You don't need to manually b64 encode basic auth, system.net.httpClient can do that for you automatically by passing a username and password in either your client construction or on an individual request.
  4. Subjectively, "someString/{}/somethingElse".format(thingToInsert) is easier to read than + based concatenation.
  5. You don't need to specify a Content-Type of application/json when you're passing a dictionary as the data parameter to an HTTP client method; it's automatically set. That plus the automatic authorization header means you don't need a headers dictionary at all.
  6. Encapsulating the "external" interface via a function definition and moving this to the project library is better for maintainability and performance. You can also defer minimize excessive construction of system.net.httpClient objects, which are heavyweight.
  7. You shouldn't use system.perspective.print for logging/informational purposes - you should use loggers.
  8. Proper loggers have automatic string substitution/formatting capabilities, and can natively handle Java exceptions (which are distinct from Python exceptions in Jython, a caveat that LLMs invariably fail to account for)
6 Likes