changeset 1347:48e2a8b07c0b

browser: async version of bridge
author Goffi <goffi@goffi.org>
date Sat, 05 Sep 2020 21:59:11 +0200
parents cda5537c71d6
children c74e5a488af6
files libervia/pages/_browser/aio_bridge.py libervia/pages/_browser/tmp_aio.py
diffstat 2 files changed, 81 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libervia/pages/_browser/aio_bridge.py	Sat Sep 05 21:59:11 2020 +0200
@@ -0,0 +1,55 @@
+from browser import window, aio
+import javascript
+
+
+class BridgeException(Exception):
+    """An exception which has been raised from the backend and arrived to the frontend."""
+
+    def __init__(self, name, message="", condition=""):
+        """
+
+        @param name (str): full exception class name (with module)
+        @param message (str): error message
+        @param condition (str) : error condition
+        """
+        Exception.__init__(self)
+        self.fullname = str(name)
+        self.message = str(message)
+        self.condition = str(condition) if condition else ""
+        self.module, __, self.classname = str(self.fullname).rpartition(".")
+
+    def __str__(self):
+        message = (": %s" % self.message) if self.message else ""
+        return self.classname + message
+
+    def __eq__(self, other):
+        return self.classname == other
+
+
+class Bridge:
+
+    def __getattr__(self, attr):
+        return lambda *args, **kwargs: self.call(attr, *args, **kwargs)
+
+    async def call(self, method_name, *args, **kwargs):
+        data = javascript.JSON.stringify({
+            "args": args,
+            "kwargs": kwargs,
+        })
+        url = f"/_bridge/{method_name}"
+        r = await aio.post(
+            url,
+            headers={
+                'X-Csrf-Token': window.csrf_token,
+            },
+            data=data,
+        )
+
+        if r.status == 200:
+            return javascript.JSON.parse(r.data)
+        elif r.status == 502:
+            ret = javascript.JSON.parse(r.data)
+            raise BridgeException(ret['fullname'], ret['message'], ret['condition'])
+        else:
+            print(f"bridge called failed: code: {r.status}, text: {r.statusText}")
+            raise BridgeException("InternalError", r.statusText)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libervia/pages/_browser/tmp_aio.py	Sat Sep 05 21:59:11 2020 +0200
@@ -0,0 +1,26 @@
+from browser import window
+
+"""Q&D module to do ajax requests with data types currently unsupported by Brython"""
+# FIXME: remove this module when official aio module allows to work with blobs
+
+window.eval("""
+var _tmp_ajax = function(method, url, format, data){
+    return new Promise(function(resolve, reject){
+        var xhr = new XMLHttpRequest()
+        xhr.open(method, url, true)
+        xhr.responseType = format
+        xhr.onreadystatechange = function(){
+            if(this.readyState == 4){
+                resolve(this)
+            }
+        }
+        if(data){
+            xhr.send(data)
+        }else{
+            xhr.send()
+        }
+    })
+}
+""")
+
+ajax = window._tmp_ajax