JSON validation using Introspect() - Printable Version +- Kodi Community Forum (https://forum.kodi.tv) +-- Forum: Development (https://forum.kodi.tv/forumdisplay.php?fid=32) +--- Forum: Kodi Application (https://forum.kodi.tv/forumdisplay.php?fid=93) +---- Forum: JSON-RPC (https://forum.kodi.tv/forumdisplay.php?fid=174) +---- Thread: JSON validation using Introspect() (/showthread.php?tid=190653) |
JSON validation using Introspect() - DjKarras - 2014-03-28 Dear all, I am trying to write yet another python wrapper for the XBMC JSON-RPC so I can send commands and also subscribe to notifications. The reason for this is that I am working on a larger project in which I want to be able to control my HTPC and everything that happens in it (torrent downloading, xbmc updates, etc.) from a single place (you can see the progress in https://github.com/apuignav/pythonhtpc (xbmc is in pythonhtpc/rpcs/xbmclib.py). I wanted to add automatic validation of the parameters passed to methods and the responses from XBMC in combination with "discovery" using JSONRPC.Introspect(). As far as I understand, this call should return a valid JSON schema to validate against, but I have not been able to manage to do so in a general way. I think I am probably making a mistake or I am not understanding what to expect from this function, so let me try to give some examples that will clarify my problems: Code: from validictory import validate Code: validictory.validator.FieldValidationError: Required field 'major' is missing However, if i do Code: from validictory import validate In the first case, the returns variable contains Code: {u'version': {u'major': 6, u'minor': 0, u'patch': 3}} Code: u'pong' In the case of version, I can solve it with Code: from validictory import validate In addition to this, I have problems in validating parameters, since 'params' is a list that needs to be converted to Code: {'type': 'object', 'properties': params} Code: {'param1': value, 'param2': value} Can somebody point me to the right path? I have the feeling there is something very stupid I am not understanding... There a few other things I don't understand, but I think if you can help me solve these fundamental problems I will be able to move forward and understand the rest. Thanks you very much in advance, Albert PS: I've found that JSONRPC.Introspect doesn't contain information on the OnScreensaverActivated and OnScreensaverDeactivated notifications, at least in my XBMC version. Is this known? Code: >>> xbmc.execute_method('JSONRPC.Introspect')['notifications']['GUI.OnScreensaverActivated'] RE: JSON validation using Introspect() - Montellese - 2014-03-29 Introspect will tell you whether the returned value is just a string or an object/dictionary. But I don't know anything about validictory etc so I can't say what happens in there. Btw you can do filtering by methods in JSONRPC.Introspect. It looks like you currently always retrieve the full introspect (which is pretty big) and then get the method's "returns" part. I don't really understand your issue with "params". Are you talking about "params" from introspect or the "params" you specify in your requests? Maybe you could re-phrase your question under the assumption that I know nothing about the tools you use. And thanks for the hint concerning OnScreensaverActivated/OnScreensaverDeactivated. They are really missing from introspect. RE: JSON validation using Introspect() - DjKarras - 2014-03-29 Hi, yes, you are right! Sorry, my post was indeed too obscure and failed completely to convey my question. Let me retry :-) Let me start with JSONRPC.Ping. From Introspect (I know it can be called just method by method, in my previous post I just did that to go faster) I get Code: "JSONRPC.Ping": { So I make a JSON call with the following configuration Code: {u'jsonrpc': u'2.0', u'id': 0, 'method': u'JSONRPC.Ping', 'params':{}} Code: {u'jsonrpc': u'2.0', u'id': 0, u'result': u'pong'} Now, if I go to JSONRPC.Version: Code: "JSONRPC.Version": { I can make a call such as Code: {u'jsonrpc': u'2.0', u'id': 1, 'method': u'JSONRPC.Version', 'params':{}} Code: {u'jsonrpc': u'2.0', u'id': 1, u'result': {u'version': {u'major': 6, u'minor': 0, u'patch': 3}}} Code: "returns": { If I have understood correctly (and probably I haven't), to be consistent with that schema the answer should be Code: {u'jsonrpc': u'2.0', u'id': 1, u'result': {u'major': 6, u'minor': 0, u'patch': 3}} Alternatively, one could define the 'returns' with an object inside an object, something along the lines of Code: "returns": { So, I was wondering if I am just misunderstanding how this works, how JSON schema works, or I am just trying to use Introspect for something it was not designed to do... Regarding the params issue I mentioned, in JSONRPC.Ping, for example, the method params are defined as Code: "params": [] Code: "params": {'type': 'array'} Code: "params": {'type': 'object'} In more complex cases, for example Code: "JSONRPC.NotifyAll": { I see that 'params' doesn't really look like a JSON schema. Looking and understanding what the JSONRPC server wants, I think the correct schema for the 'params' in this case would be something like Code: "params": { "type": "object", As you can see, I am very confused on how to interpret the Introspect results, and I have the strong feeling I am just looking at them the wrong way. Could you please help me? Thanks a lot, Albert RE: JSON validation using Introspect() - Montellese - 2014-03-29 Hehe you were a bit unlucky in trying your work on JSONRPC.Version because that one was broken until a few weeks ago. The schema has since been fixed to contain the "version" property in the "returns" object. Concerning "params": You're assumption that the whole method definition is JSON schema is not correct. It's based on "JSON Service Description" which vanished in the meantime. There have been some new approaches to this but I haven't seen anything yet that really covers the full JSON-RPC 2.0 specification. The main problem is that the JSON-RPC 2.0 specification dictates that "params" must either be an array or an object. So when doing a request you have the choice between passing your parameters as an array in the right order (without a name) or as an object with the properties being in any order but with a specific name. Therefore the API definition cannot just use JSON schema's "type": "object" because in a JSON object the properties don't have an absolute order which must be the case to fulfill the JSON-RPC 2.0 specification. But you also can't use JSON schema's "type": "array" because JSON schema doesn't allow the definition of the object instances in an array (it does but only very generically). So in the end the JSON-RPC API definition is a combination of "JSON service description" for methods, notifications, parameters and the type containers and of "JSON schema" for the definition of the actual types. RE: JSON validation using Introspect() - Montellese - 2014-03-29 Actually I just found a website that took over the "JSON service description" specification at http://www.simple-is-better.org/json-rpc/jsonrpc20-schema-service-descriptor.html RE: JSON validation using Introspect() - DjKarras - 2014-03-29 Hi! Thanks a lot, now I understand... So, it is clearly more difficult than I thought, unfortunately. Anyway, I am left with one doubt about the whole params business: does your explanation mean that parameters need to be passed in the specified order when making the RPC call? Thanks a lot for all the help, Albert RE: JSON validation using Introspect() - Montellese - 2014-03-29 Only if you pass them in as an array (i.e. "params" is an array). If you pass them in as properties of the "params" object they can be in any order. RE: JSON validation using Introspect() - DjKarras - 2014-03-29 OK! Now I understand! Then this is easily hackable :-) Thanks, Albert |