JSONRPC Query to Python DICT.
#1
With the HTTP API lifespan coming to an end soon(true it may be Post Eden) I thought I might supply a small bit of code that I use for getting the results from a JSON RPC query into a useful Python DICT. Nuka had provided the general code, I just made it work for my needs.

Code:
def retrieve_json_dict(json_query, items='items', force_log=False ):
    """ retrieve_json_dict()
        This function returns the response from a json rpc query in a dict(hash) form

        requirements:
            json_query - a properly formed json rpc request for return
            items - the specific key being looked for, example for VideoLibrary.GetMovies - 'movies' is the key, 'items' is a common response(can be left blank then)
            force_log - Setting this to True will send the JSONRPC reponse to the log(this can be a lot of information, slowing down XBMC) Default is False
    """
    xbmc.log( "[json_utils.py] - JSONRPC Query -\n%s" % json_query, level=xbmc.LOGDEBUG )
    true = True
    false = False
    null = None
    json_response = xbmc.executeJSONRPC(json_query)
    # Enable debug logging for the JSONRPC response
    if force_log:
        xbmc.log( "[json_utils.py] - retrieve_json_dict - JSONRPC -\n%s" % json_response, level=xbmc.LOGDEBUG )
    if json_response.startswith( "{" ):
        response = eval( json_response )
    try:
        result = response['result']
        json_dict = result[items]   # use what is stored in items as a 'Key'
        return json_dict
    except:
        #traceback.print_exc()
        xbmc.log( "[json_utils.py] - retrieve_json_dict - Error trying to get json response", level=xbmc.LOGDEBUG )
        return None

For instance to get all the file paths for an album(using the database id):

Code:
json_query = '{"jsonrpc": "2.0", "method": "AudioLibrary.GetSongs", "params": {"albumid": 30, "fields": ["file"] }, "id": 1}'
file_paths =  retrieve_json_dict(json_query, items='songs', force_log=False )

The full JSONRPC response may look like this:

Code:
{
   "id" : 1,
   "jsonrpc" : "2.0",
   "result" : {
      "limits" : {
         "end" : 10,
         "start" : 0,
         "total" : 10
      },
      "songs" : [
         {
            "file" : "/media/freenas/MP3 Music/Full Albums/ACDC/Highway To Hell/01 - Highway to Hell.flac",
            "label" : "Highway to Hell",
            "songid" : 362
         },
         {
            "file" : "/media/freenas/MP3 Music/Full Albums/ACDC/Highway To Hell/02 - Girls Got Rhythm.flac",
            "label" : "Girls Got Rhythm",
            "songid" : 363
         },
         {
            "file" : "/media/freenas/MP3 Music/Full Albums/ACDC/Highway To Hell/03 - Walk All Over You.flac",
            "label" : "Walk All Over You",
            "songid" : 364
         },
         {
            "file" : "/media/freenas/MP3 Music/Full Albums/ACDC/Highway To Hell/04 - Touch Too Much.flac",
            "label" : "Touch Too Much",
            "songid" : 365
         },
         {
            "file" : "/media/freenas/MP3 Music/Full Albums/ACDC/Highway To Hell/05 - Beating Around the Bush.flac",
            "label" : "Beating Around the Bush",
            "songid" : 366
         },
         {
            "file" : "/media/freenas/MP3 Music/Full Albums/ACDC/Highway To Hell/06 - Shot Down in Flames.flac",
            "label" : "Shot Down in Flames",
            "songid" : 367
         },
         {
            "file" : "/media/freenas/MP3 Music/Full Albums/ACDC/Highway To Hell/07 - Get It Hot.flac",
            "label" : "Get It Hot",
            "songid" : 368
         },
         {
            "file" : "/media/freenas/MP3 Music/Full Albums/ACDC/Highway To Hell/08 - If You Want Blood (You've Got It).flac",
            "label" : "If You Want Blood (You've Got It)",
            "songid" : 369
         },
         {
            "file" : "/media/freenas/MP3 Music/Full Albums/ACDC/Highway To Hell/09 - Love Hungry Man.flac",
            "label" : "Love Hungry Man",
            "songid" : 370
         },
         {
            "file" : "/media/freenas/MP3 Music/Full Albums/ACDC/Highway To Hell/10 - Night Prowler.flac",
            "label" : "Night Prowler",
            "songid" : 371
         }
      ]
   }
}

Notice that the Info we want is after "songs": hence the
Code:
items="songs"
in the 'retrieve_json_dict' call.

The procedure will create a DICT(also know as a Hash) similar to the following:

Code:
[{'songid': 362, 'file': '/media/freenas/MP3 Music/Full Albums/ACDC/Highway To Hell/01 - Highway to Hell.flac', 'label': 'Highway to Hell'}, {'songid': 363, 'file': '/media/freenas/MP3 Music/Full Albums/ACDC/Highway To Hell/02 - Girls Got Rhythm.flac', 'label': 'Girls Got Rhythm'},  ...... }]

Which is a form that is really easy to use in Python.
Reply
#2
Wonder if the executeJSONRPC perhaps should take a dict and return a dict? I opted for the lazy version when I implemented the python thing.
If you have problems please read this before posting

Always read the XBMC online-manual, FAQ and search the forum before posting.
Do not e-mail XBMC-Team members directly asking for support. Read/follow the forum rules.
For troubleshooting and bug reporting please make sure you read this first.

Image

"Well Im gonna download the code and look at it a bit but I'm certainly not a really good C/C++ programer but I'd help as much as I can, I mostly write in C#."
Reply
#3
topfs2 Wrote:Wonder if the executeJSONRPC perhaps should take a dict and return a dict? I opted for the lazy version when I implemented the python thing.

I don't feel it needs to change. Being in this form allows the command to be more versatile. It took me a little while to figure out the proper forming of a Query(thanks to the Simple REST Client in Google Chrome).
Reply
#4
I've just been using a json.loads() to convert my responses to dicts. Is using eval() any better or quicker?
Reply
#5
hippojay Wrote:I've just been using a json.loads() to convert my responses to dicts. Is using eval() any better or quicker?

Off hand I'm not sure...

Didn't know about json.loads(), so I just tried it and haven't been successful putting the response from executeJSONRPC() into it(errors out, though eval() motors through the same response)

Once I figure out how to get the response from executeJSONRPC() I can time it.. and put up a comparisim between the two...

for instance, using the following query:

Code:
{"jsonrpc": "2.0", "method": "VideoLibrary.GetMovies", "params": {"fields": ["title", "thumbnail", "file", "plot", "plotoutline", "rating", "runtime", "director", "genre", "mpaa", "votes", "trailer", "tagline", "top250", "studio", "year", "writer", "streamDetails" ] }, "id": 1}

it took eval() 0.690 seconds to change to a DICT. ( 1083 movies )
Reply

Logout Mark Read Team Forum Stats Members Help
JSONRPC Query to Python DICT.0