Note that there are some explanatory texts on larger screens.

plurals
  1. POUsing JSON-RPC call from Pyjamas/PyJs with a web.py backend
    primarykey
    data
    text
    <p>This has already cost me many hours of Googling and I still cannot get it working, time to ask SO for help :-)</p> <p>I try to put together a simple test application where the frontend is written in Pyjamas, the backend is running on <a href="http://webpy.org" rel="nofollow">Web.py</a>. They are supposed to talk to each other via JSON-RPC. The desired functionality is to let the user enter a string which is then converted to uppercase. </p> <p>There is a description in the Pyjamas online book <a href="http://pyjs.org/book/Bookreader.html#Rest%20of%20the%20World" rel="nofollow">"Rest of the World"</a> on how to use JSON-RPC which presents various technologies mixed together and is therefore difficult to parse. By looking at hints e.g. from <a href="http://amundblog.blogspot.co.at/2008/12/ajax-with-python-combining-pyjs-and.html" rel="nofollow">Amund Tveit's blog</a> etc. I cobbled together the following:</p> <p>1) The <strong>server script</strong> which is really simple:</p> <pre><code>import web import json import os urls = ( '/json', 'JSONHandler', '/json/', 'JSONHandler', ) app = web.application(urls, globals()) class JSONHandler: def json_upper(self,args): return [args[0].upper()] def json_markdown(self,args): return [args[0].lower()] def POST(self): args = json.loads(web.data()) print args json_func = getattr(self, 'json_%s' % args[u"method"]) json_params = args[u"params"] json_method_id = args[u"id"] result = json_func(json_params) # reuse args to send result back args.pop(u"method") args["result"] = result[0] args["error"] = None # IMPORTANT!! web.header("Content-Type","text/html; charset=utf-8") return json.dumps(args) if __name__ == "__main__": app.run() </code></pre> <p>and it <strong>definitely works</strong>, tested with a simple query script (not shown) that relies on <a href="https://github.com/joshmarshall/jsonrpclib" rel="nofollow">Josh Marshall's JSON-RPC library</a>.</p> <p>2) The <strong>client-script for Pyjamas</strong> which is also straightforward:</p> <pre><code># Client example from Amund Tveit's blog # http://amundblog.blogspot.co.at/2008/12/ajax-with-python-combining-pyjs-and.html # note: ui and JSONService were not prefixed with pyjamas, but that's needed from pyjamas.ui import RootPanel, TextArea, Label, Button, HTML, VerticalPanel, HorizontalPanel, ListBox from pyjamas.JSONService import JSONProxy class Client: def onModuleLoad(self): self.TEXT_WAITING = "Waiting for response..." self.TEXT_ERROR = "Server Error" # This is the remote service self.remote_server = UpperService() self.status=Label() self.text_area = TextArea() self.text_area.setText(r"Please uppercase this string") self.text_area.setCharacterWidth(80) self.text_area.setVisibleLines(8) self.button_py = Button("Send to Python Service", self) buttons = HorizontalPanel() buttons.add(self.button_py) buttons.setSpacing(8) info = r'Upper-case a string using JSON-RPC' panel = VerticalPanel() panel.add(HTML(info)) panel.add(self.text_area) panel.add(buttons) panel.add(self.status) RootPanel().add(panel) def onClick(self, sender): self.status.setText(self.TEXT_WAITING) text = self.text_area.getText() # (data, response_class): if the latter is 'self', then # the response is handled by the self.onRemoteResponse() method if self.remote_server.upper(self.text_area.getText(), self) &lt; 0: self.status.setText(self.TEXT_ERROR) def onRemoteResponse(self, response, request_info): self.status.setText(response) def onRemoteError(self, code, message, request_info): self.status.setText("Server Error or Invalid Response: ERROR " + code + " - " + message) # AJAX calls must come from the same server, only the path is given here class UpperService(JSONProxy): def __init__(self): JSONProxy.__init__(self, "/json/", ["upper"]) </code></pre> <p>I compiled it with PyJs, renamed the default <code>output</code> directory to <code>static</code> so that web.py can serve it, edited <code>static/Client.html</code> so that the internal references point to <code>static</code>:</p> <pre><code>&lt;html&gt; &lt;!-- auto-generated html - You should consider editing and adapting this to suit your requirements. No doctype used here to force quirks mode; see wiki for details: http://pyjs.org/wiki/csshellandhowtodealwithit/ --&gt; &lt;head&gt; &lt;title&gt;Client (Pyjamas Auto-Generated HTML file)&lt;/title&gt; &lt;meta name="pygwt:module" content="/static/Client"&gt; &lt;!-- was content="Client" --&gt; &lt;/head&gt; &lt;body style="background-color:white"&gt; &lt;script type="text/javascript" src="/static/bootstrap.js"&gt;&lt;/script&gt; &lt;!-- was src="bootstrap.js" --&gt; &lt;iframe id="__pygwt_historyFrame" style="display:none;"&gt;&lt;/iframe&gt; &lt;/body&gt; &lt;/html&gt; </code></pre> <p>... and then pointing the browser to <code>http://localhost:8080/static/Client.html</code>. All I get is a blank page, inspecting the page source shows <code>static/Client.html</code> above so it was indeed served to the browser. The server's log also shows that at least some pages have been served:</p> <pre><code>http://0.0.0.0:8080/ 127.0.0.1:61466 - - [14/Mar/2013 13:59:39] "HTTP/1.1 GET /static/Client.html" - 200 127.0.0.1:61466 - - [14/Mar/2013 13:59:40] "HTTP/1.1 GET /static/Client.nocache.html" - 200 127.0.0.1:61466 - - [14/Mar/2013 13:59:40] "HTTP/1.1 GET /static/Client.safari.cache.html" - 200 </code></pre> <p>No indication of what went wrong, however. Tried all sorts of other combinations of URLs, renaming directories, compiling the Pyjamas part with the -d option in the hope to get a debug stack trace ... to no avail. </p> <p>Has anyone succeeded in getting Pyjamas and Web.py working together? If yes, then please share how. Thanks.</p> <p>PS: I am using web.py V0.37 and the latest Pyjamas development release. (The current stable release V0.8.1 does not work either.)</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload