Posted on 08-13-2014 08:46 AM
Hello, I am just starting to use the API queries with python.
I am having some difficulty getting anything to 'PUT' changes for existing devices. I keep getting a HTTP Error 500: Internal Server Error.
I am unsure where to check for logs on the server side for API access attempts or if there even are any such logs.
I have tried multiple attributes but keep getting the same error, here is a sample below.
I have a test.xml file and in that test.xml I have the following
<mobile_device><location><username>testusername</username></location></mobile_device>
code as follows:
------
from urllib2 import urlopen, URLError, HTTPError, Request
from xml.dom import minidom
import base64
my_xml_doc = minidom.parse("test.xml")
url="https://myserver:8443/JSSResource/mobiledevices/id/9999"
req = Request(url, data=my_xml_doc.toprettyxml())
req.add_header('Content-Type','text/xml')
req.get_method=lambda: 'PUT'
base64string=base64.encodestring('myuseraccount:mypassword')
authheader="Basic %s" % base64string
req.add_header("Authorization", authheader)
xmldata = urlopen(req)
-----------------
Since I have never accessed the API before, I am unsure of what I am doing wrong. Does anyone see what I am doing wrong for the following updates? In this case I am trying to update the username to "testusername" on an existing device id 9999
Any assistance in this issue would be appreaciated.
Solved! Go to Solution.
Posted on 08-13-2014 12:06 PM
500 errors can sometimes be attributed to the JSS trying to parse your input XML and failing.
This line here:
req = Request(url, data=my_xml_doc.toprettyxml())
You don't need to prettyprint the XML that you're passing to the request. The extra spacing and newline characters that are being added might be a factor in the error. The original XML string you used works fine.
Try the code below. Its a little simplified down and works against a test instance I have.
import urllib2
import base64
xml = "<mobile_device><location><username>new.user</username></location></mobile_device>"
request = urllib2.Request('https://myjss.com/JSSResource/..')
request.add_header('Authorization', 'Basic ' + base64.b64encode('jssusername:jsspassword'))
request.add_header('Content-Type', 'text/xml')
request.get_method = lambda: 'PUT'
response = urllib2.urlopen(request, xml)
Posted on 08-13-2014 12:06 PM
500 errors can sometimes be attributed to the JSS trying to parse your input XML and failing.
This line here:
req = Request(url, data=my_xml_doc.toprettyxml())
You don't need to prettyprint the XML that you're passing to the request. The extra spacing and newline characters that are being added might be a factor in the error. The original XML string you used works fine.
Try the code below. Its a little simplified down and works against a test instance I have.
import urllib2
import base64
xml = "<mobile_device><location><username>new.user</username></location></mobile_device>"
request = urllib2.Request('https://myjss.com/JSSResource/..')
request.add_header('Authorization', 'Basic ' + base64.b64encode('jssusername:jsspassword'))
request.add_header('Content-Type', 'text/xml')
request.get_method = lambda: 'PUT'
response = urllib2.urlopen(request, xml)
Posted on 08-13-2014 03:09 PM
Thank you, this definitely led me in the right direction. Your code worked for me.
I also tried changing my original code to .toxml() but it still did not work. After further examination I noticed you used base64.b64encode whereas I was using base64.encodestring.
I tested to the two and the difference turned out to be that the base64.encodestring actually appends a newline ' ' at the end.
Posted on 05-05-2017 02:56 PM
That moment when you've spent the last hour trying to figure out what the heck was wrong with your code..... and it was in jamfnation all along......
Thank you!
Also, @brysontyrrell I just finished watching the JNUC 2016 "Intro to Webhooks" on YouTube. It was very good! I can see where webhooks would be very useful but at this point it's a bit over my head. Something to look forward to though!
Posted on 05-09-2017 08:33 PM
Glad you found it useful. If you're writing Python code that's running on your clients and you need to stay within the confines of the standard library, continue to use urllib2
. If you're writing Python code that isn't going to run on your clients, use pip
to install requests
and use that. You'll find loads of examples all over the place on using it, it's much easier, and far more powerful a library!
If you're interested in learning more about webhooks you're going to have a couple of opportunities coming up. I'll be giving a workshop at Penn State MacAdmins this year all about building Jamf Pro integrations using webhooks.
Posted on 06-19-2017 01:02 PM
That's awesome, I looked all over Texas for conferences and always ended up back at MacAdmins so I pitched it to my supervisor and got it approved. I appreciate the heads up and the extra info. Apparently I've become fairly notorious at jamf for blowing our server up so I'm still very much a novice when it comes to management of iOS and macOS but I love to learn all the abilities of the JSS, especially anything that can be automated like the APIs, webhooks, etc.
I'll see you at MacAdmins.