Json Call to remote instance

  Thread Rating:
  • 0 Votes - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Post Reply
DecK Offline
Senior Member
Posts: 136
Joined: Nov 2008
Reputation: 4
Location: Round Rock, TX
Post: #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 
find quote
Bstrdsmkr Offline
Posting Freak
Posts: 803
Joined: Oct 2010
Reputation: 17
Post: #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 }
find quote
DecK Offline
Senior Member
Posts: 136
Joined: Nov 2008
Reputation: 4
Location: Round Rock, TX
Post: #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.
find quote
Bstrdsmkr Offline
Posting Freak
Posts: 803
Joined: Oct 2010
Reputation: 17
Post: #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.
find quote
DecK Offline
Senior Member
Posts: 136
Joined: Nov 2008
Reputation: 4
Location: Round Rock, TX
Post: #5
Afraid not. :-(
Still getting the same error.
find quote
jbel Offline
Senior Member
Posts: 109
Joined: Apr 2009
Reputation: 5
Location: nyc
Post: #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.
find quote
paddycarey Offline
Senior Member
Posts: 246
Joined: Sep 2009
Reputation: 8
Post: #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
(This post was last modified: 2012-04-05 05:18 by paddycarey.)
find quote
Bstrdsmkr Offline
Posting Freak
Posts: 803
Joined: Oct 2010
Reputation: 17
Post: #8
right, duh. I think you can also drop the user-agent as I'm pretty sure xbmc just ignores it
find quote
DecK Offline
Senior Member
Posts: 136
Joined: Nov 2008
Reputation: 4
Location: Round Rock, TX
Post: #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() 
find quote
Bstrdsmkr Offline
Posting Freak
Posts: 803
Joined: Oct 2010
Reputation: 17
Post: #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
find quote
djon Offline
Senior Member
Posts: 180
Joined: Oct 2004
Reputation: 1
Post: #11
I keep getting a 401 Unauthorized. How do I send the user/password along to the remote instance?
find quote
pkscout Offline
Posting Freak
Posts: 1,087
Joined: Jan 2011
Reputation: 23
Location: Honolulu, HI
Post: #12
You can pass it as part of the URL. http://user:pass@host
find quote
djon Offline
Senior Member
Posts: 180
Joined: Oct 2004
Reputation: 1
Post: #13
No that doesn't work here. I assume I need to send it as a parameter somehow, like with Curl, "-u"
find quote
djon Offline
Senior Member
Posts: 180
Joined: Oct 2004
Reputation: 1
Post: #14
base64string = base64.encodestring('%s:%s' % (username, password)).replace('\n', '')
req.add_header("Authorization", "Basic %s" % base64string)

works.
find quote
schumi2004 Offline
Posting Freak
Posts: 1,344
Joined: Aug 2011
Reputation: 14
Post: #15
This looks exactly what i'm looking for. How can we use this for multiple hosts?
find quote
Post Reply