I’ve got to retrieve information from a REST API. If I run this query in ARC, I get the information and the world is an awesome place:


My “attempt” at writing the script is:

response ='http://devapp1:8080/cellfusion/api/v1/orders/details?sales-order=001000018898')
token = cfapiKnJ4Td2WQ8hf
data = system.util.jsonDecode(response)
print data

I get a “401” error. I can program the heck out of PLCs, but this scripting stuff is killing me. Any ideas?

You aren’t passing the token in as far as I can see, which is why you’re getting 401 Unauthorized.

Great news! Uh… how do I pass the token?

1 Like

You’re defining token out as a variable, not adding it to the URL. The API you’re talking to appears to just want the token as a URL parameter, so you can just add it to the URL like you have in your example URL:

response ='http://devapp1:8080/cellfusion/api/v1/orders/details?sales-order=001000018898&token=<token>')

If you want to make it more dynamic, you can use Python’s string manipulation…in technically, quite a few different ways:

#standard string interpolation, works basically everwhere
print "http://devapp1:8080/cellfusion/api/v1/orders/details?sales-order=%s&token=%s" % ("001000018898", "token")

# only in Ignition 8.0.0+:
#print "http://devapp1:8080/cellfusion/api/v1/orders/details?sales-order={0}&token={1}".format("001000018898", "token")
#args = {"sales-order": "001000018898", "token": "token"}
#print "http://devapp1:8080/cellfusion/api/v1/orders/details?sales-order={sales-order}&token={token}".format(**args)

#or, using a standard library function: 
from urllib import urlencode
args = {"sales-order": "001000018898", "token": "token"}
print "http://devapp1:8080/cellfusion/api/v1/orders/details?" + urlencode(args)
1 Like

Outstanding! This:

response =‘http://devapp1:8080/cellfusion/api/v1/orders/details?sales-order=001000018898&token=cfapiKnJ4Td2WQ8hf’)
data = system.util.jsonDecode(response)
print data

retrieved the expected results. How do I expose the data in a table or?

Easy answer: Use Perspective, because the table component natively accepts JSON data, and there’s also an HTTP binding type.

Harder answer: If you’re using Vision, or just want to translate this into a dataset somehow, then you will need to decide how to map your JSON structure to a dataset.
system.dataset.toDataSet() takes two arguments - a string “array” (technically, a Python list) of column names, and then a 2D (nested) “array” of data objects. Something like this - you’ll have to manipulate your JSON object (which system.util.jsonDecode should give you as a Python datastructure):

headers = ["city", "state", "population"]

data = [
	["New York", "New York", "7000000"], #row 1
	["Los Angeles", "California", "8000000"], #row 2
	["Podunk", "Alaska", "8"] #row 3

dataset = system.dataset.toDataSet(headers, data)
1 Like

Thanks so much for all your help. I’ve been trying to get this to work for a couple days, even submitted a help desk ticket. You’ve solved my basic issues.

1 Like