All
I am trying to make a Json call to an instance of XBMC running on another machine on my network. Below is the code I am using. When I run this I get the following error. Any input would be appreciated.
Error Message
{"error":{"code":-32700,"message":"Parse error."},"id":null,"jsonrpc":"2.0"}
PHP Code:
import urllib
import urllib2
host = '192.168.0.50'
port = '8080'
url = 'http://%s:%s/jsonrpc' %(host, port)
user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'
values = {"jsonrpc": "2.0", "method": "JSONRPC.Introspect", "id": "1"}
headers = { 'User-Agent' : user_agent }
data = urllib.urlencode(values)
req = urllib2.Request(url, data, headers)
response = urllib2.urlopen(req)
the_page = response.read()
file = "C:\\test\\test_output.txt"
f = open(file,"w")
f.write(the_page)
f.close
Looks like it didn't receive a valid JSON string. I think JSONRPC.Introspect requires a filter parameter. Try this:
{ "jsonrpc": "2.0", "method": "JSONRPC.Introspect", "params": { "filter": { "id": "AudioLibrary.GetSongs", "type": "method" } }, "id": 1 }
That gives me the exact same error message.
In order to check the validity of the JSON strings, I ran both your and mine in an addon using xbmc.executeJSONRPC and both worked successfully.
So it looks like the issue is somewhere else in the code.
Knew I should have waited and tested that lol
try changing headers to:
headers = {"Content-Type":"application/json"}
That should only matter in pre-Frodo, but could be it.
Afraid not. :-(
Still getting the same error.
I'm not too familiar with using the JSON API, however in your example code you are not POSTing JSON. You are incorrectly calling urlencode which creates a query string. You want to use json.dumps(values) for your data variable.
jbel's got it, this works:
Code:
import json
import urllib2
host = 'someip'
port = '8080'
url = 'http://%s:%s/jsonrpc' %(host, port)
user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'
values = {"jsonrpc": "2.0", "method": "JSONRPC.Introspect", "id": "1"}
headers = { 'User-Agent' : user_agent }
data = json.dumps(values)
req = urllib2.Request(url, data, headers)
response = urllib2.urlopen(req)
the_page = response.read()
file = "test_output.txt"
f = open(file,"w")
f.write(the_page)
f.close
right, duh. I think you can also drop the user-agent as I'm pretty sure xbmc just ignores it
Thanks to everyone, It is working now.
I've wrapped it into a function. Any suggestions for improved would still be appreciated.
PHP Code:
import json
import urllib2
def getJsonRemote(host,port,method,params=None):
url = 'http://%s:%s/jsonrpc' %(host, port)
values ={}
values["jsonrpc"] = "2.0"
values["method"] = method
if params is not None:
values["params"] = params
values["id"] = "1"
headers = {"Content-Type":"application/json"}
data = json.dumps(values)
req = urllib2.Request(url, data, headers)
response = urllib2.urlopen(req)
return response.read()
You might change it to
response = urllib2.urlopen(req)
response = response.read()
return json.loads(response)
That way you get back actual objects instead of a string. I doubt you'll have a use for the string besides converting it to objects
I keep getting a 401 Unauthorized. How do I send the user/password along to the remote instance?
No that doesn't work here. I assume I need to send it as a parameter somehow, like with Curl, "-u"
base64string = base64.encodestring('%s:%s' % (username, password)).replace('\n', '')
req.add_header("Authorization", "Basic %s" % base64string)
works.
This looks exactly what i'm looking for. How can we use this for multiple hosts?