PAC data using RESTful Python

Lately I’ve been working in Python on a Raspberry Pi and I have some data I need available on a PAC controller, I found using the requests Python library to get and post the data through the RESTful API is a fast and clean way to get it done.
If you want to do the same you’ll want to know a few things before you hit up Python: your controller IP, some variable to write to, an authentication key:value pair from http://<ControllerIP>/admin/keys, and finally pip install requests if you do not already have the package.

For my application, the controller is a Learning Center at 10.192.58.11, which has a strategy containing a string variable status, in my case to hold hold four characters “test”, “pass”, “fail”, or “done”, and finally I have made and enabled a authentication pair (python, permit).

How those parts go together for a hard-coded post and get:

p = requests.post("http://10.192.58.11/api/v1/device/strategy/vars/strings/status", "{\"value\":\"test\"}", auth=('python','permit'))
g = requests.get("http://10.192.58.11/api/v1/device/strategy/vars/strings/status", auth=('python','permit'))

or…

import requests  # be sure to import the package
variable = "status"
host = "10.192.58.11"
creds = ('python','permit')
url = "http://" + host + "/api/v1/device/strategy/vars/strings/" + variable

post = "\"test\""
data = "{\"value\":" + post + "}"

p = requests.post(url, data, auth=creds)  # auth= is required
print((repr(p.status_code) + ", " + p.reason))

g = requests.get(url, auth=creds)  # no need for data on a 'get' call
print((repr(g.status_code) + ", " + g.reason + ": " + g.content.decode()))

SNAP PAC REST API call extensions are listed here for everything from strings to int32 tables.

It is important that the data you post is formatted as a JSON key:value pair in the string format {"value":<data>}, in this case data I want to post is the string “test”, so I write the line "\"test\"" using the quote character \" to ensure that a string is written, if instead I was doing a number like 42 I would need data = "{\"value\":" + repr(42)+ "}" to result in {"value":42}. Match your number/string formatting to your data type!

Now to see what is returned by the get I use g.headers and g.content.decode() – decode is to turn the data from bytes into a string.

Here is a short Python3 script that writes the current four-character time to the status string, reads it, and then prints it so we can have some real data moving around.

which outputs:

Note that the request.post data is the JSON key:value pair, and I made sure to put quotes around the value and what I am passing in using the quote character \" since it is stored as a string, otherwise I get a bad request error 400 for trying to put an int in a string.

I have been using this to send reports from my Raspberry Pi to my PAC controller with RESTful API calls very quickly and easily, with no third-party program shuffling my data around!

Happy coding!

3 Likes

Thanks for the excellent post. I’m beginning to use a Raspberry Pi and will keep this post close by.