Picture courtesy of http://vitaminsea.typepad.com/vitaminsea/2007/10/index.html
Posting JSON-RPC requests from a prolog program
This tutorial basically performs the opposite of the previous blog entry. We will make a prolog client that talks to a python JSON-RPC service.Creating the python server
There are several options to create a python JSON-RPC server. One is getting the jsonrpclib library, another one is using a web application framework with support for JSON-RPC - the easiest to learn and use by far being web2py: just unpack the source code, python web2py.py and you can immediately start. No configuration or additional dependencies needed. In web2py, you click a single button to create a simple application named simple_json_server (or any name you like ;) ), then click one button to edit the controller code and add the following code: And that's it! Now we have a fully functioning json-rpc server living at URL 'http://127.0.0.1:5000/simple_json_server/default/call/jsonrpc'.Creating the prolog client
Creating the prolog client is just as simple.Practical issues when using JSON-RPC from prolog
Talking to different JSON-RPC servers may result in receiving different replies for the same question:- The ordering of the terms in the json([...]) reply can vary from server to server. Swi-prolog chose to optimize for speed, and doesn't provide any tools to cope with such variations, assuming that the reply from one given server would always return terms in the same order.
- Servers that serve JSON-RPC 1.1 are allowed to leave out the "jsonrpc"="1.1" from their reply. They can apparantly also can add "error"="null" to indicate that no error occurred.
So in real-life usage of JSON-RPC we have to deal with varying ordering of fields, and with optional fields. For JSON-RPC requests without nested parameters, I found it beneficial to convert the JSON-RPC reply to an association list first, from which then all fields we're interested in can be retrieved and processed.
Note that failing to configure a correct content type when interacting with the server, will cause your reply to show up as a prolog atom instead of a parsed prolog representation. A bit to my surprise, web2py responded with a content-type "'text/html'; charset=utf-8" instead of the expected "application/json". (Edited to add: this was a bug in web2py version <= 1.98.2 - the development version now will return "application/json; charset=utf-8") To make sure that 'text/html; charset=utf-8' is parsed as a JSON-RPC request, we can make the parser believe that this is a valid JSON-RPC reply: http_json:json_type("'text/html'; charset=utf-8"), or in the case of web2py > 1.98.2: http_json:json_type("application/json; charset=utf-8". Perhaps the swi prolog json parser could be made a little bit smarter to ignore the charset definition (Edited to add: this was solved after a bug report. Should be available in swi-prolog versions > 5.11.26)
So does it run web pages? If so, I think I'll use it to run my blog.
ReplyDeleteAs far as I know, the SWI-PROLOG website (http://www.swi-prolog.org/ ) is written in SWI-PROLOG.
Delete