Json Call to remote instance
#1
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' %(hostport
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(urldataheaders)
response urllib2.urlopen(req)
the_page response.read()

file "C:\\test\\test_output.txt"
open(file,"w")
f.write(the_page)
f.close 

Reply
#2
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 }
Reply
#3
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.
Reply
#4
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.
Reply
#5
Afraid not. :-(
Still getting the same error.
Reply
#6
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.
Reply
#7
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
Reply
#8
right, duh. I think you can also drop the user-agent as I'm pretty sure xbmc just ignores it
Reply
#9
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' %(hostport
    
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(urldataheaders)
    
response urllib2.urlopen(req)
    return 
response.read() 
Reply
#10
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
Reply
#11
I keep getting a 401 Unauthorized. How do I send the user/password along to the remote instance?
Reply
#12
You can pass it as part of the URL. http://user:pass@HOST
Reply
#13
No that doesn't work here. I assume I need to send it as a parameter somehow, like with Curl, "-u"
Reply
#14
base64string = base64.encodestring('%s:%s' % (username, password)).replace('\n', '')
req.add_header("Authorization", "Basic %s" % base64string)

works.
Reply
#15
This looks exactly what i'm looking for. How can we use this for multiple hosts?
Reply

Logout Mark Read Team Forum Stats Members Help
Json Call to remote instance0