1
0
Эх сурвалжийг харах

Restructure nicegui json module + tidying up minor things

Rino Beeli 2 жил өмнө
parent
commit
93be198b36

+ 8 - 9
nicegui/elements/plotly.py

@@ -1,4 +1,4 @@
-from typing import Union
+from typing import Dict, Union
 
 import plotly.graph_objects as go
 
@@ -10,10 +10,11 @@ register_component('plotly', __file__, 'plotly.vue', [], ['lib/plotly.min.js'])
 
 class Plotly(Element):
 
-    def __init__(self, figure: Union[dict, go.Figure]) -> None:
+    def __init__(self, figure: Union[Dict, go.Figure]) -> None:
         """Plotly Element
 
-        Renders a Plotly chart. There are two ways to pass a Plotly figure for rendering, see parameter `figure`:
+        Renders a Plotly chart.
+        There are two ways to pass a Plotly figure for rendering, see parameter `figure`:
 
         * Pass a `go.Figure` object, see https://plotly.com/python/
 
@@ -30,10 +31,8 @@ class Plotly(Element):
         self._props['lib'] = [d.import_path for d in js_dependencies.values() if d.path.name == 'plotly.min.js'][0]
         self.update()
 
-    def update_figure(self, figure: Union[dict, go.Figure]):
-        """
-        Overrides figure instance of this Plotly chart and updates chart on client side.
-        """
+    def update_figure(self, figure: Union[Dict, go.Figure]):
+        """Overrides figure instance of this Plotly chart and updates chart on client side."""
         self.figure = figure
         self.update()
 
@@ -41,7 +40,7 @@ class Plotly(Element):
         self._props['options'] = self._get_figure_json()
         self.run_method('update', self._props['options'])
 
-    def _get_figure_json(self) -> dict:
+    def _get_figure_json(self) -> Dict:
         if isinstance(self.figure, go.Figure):
             # convert go.Figure to dict object which is directly JSON serializable
             # orjson supports numpy array serialization
@@ -51,4 +50,4 @@ class Plotly(Element):
             # already a dict object with keys: data, layout, config (optional)
             return self.figure
 
-        raise ValueError(f"Plotly figure is of unknown type '{self.figure.__class__.__name__}'.")
+        raise ValueError(f'Plotly figure is of unknown type "{self.figure.__class__.__name__}".')

+ 3 - 3
nicegui/elements/plotly.vue

@@ -11,10 +11,9 @@ export default {
         Plotly.newPlot(this.$el.id, this.options.data, this.options.layout, this.options.config);
 
         // register resize observer on parent div to auto-resize Plotly chart
-        let doResize = () => {
+        const doResize = () => {
           // only call resize if actually visible, otherwise error in Plotly.js internals
           if (this.isHidden(this.$el)) return;
-          // console.log("Resize plot");
           Plotly.Plots.resize(this.$el);
         };
 
@@ -37,6 +36,8 @@ export default {
 
   methods: {
     isHidden(gd) {
+      // matches plotly's implementation, as it needs to in order
+      // to only resize the plot when plotly is rendering it.
       // https://github.com/plotly/plotly.js/blob/e1d94b7afad94152db004b3bd5e6060010fbcc28/src/lib/index.js#L1278
       var display = window.getComputedStyle(gd).display;
       return !display || display === "none";
@@ -48,7 +49,6 @@ export default {
     },
 
     update(options) {
-      console.log("UPDATE called");
       // ensure Plotly imported, otherwise first plot will fail in update call
       // because library not loaded yet
       this.ensureLibLoaded().then(() => {

+ 8 - 29
nicegui/json/__init__.py

@@ -1,36 +1,15 @@
 """
 Custom json module. Provides dumps and loads implementations
-wrapping orjson.
+wrapping the `orjson` package.
 
 Custom module required in order to override json-module used
-in socketio.AsyncServer.
+in socketio.AsyncServer, which expects a module as parameter
+to override Python's default json module.
 """
 
-from typing import Any
+from nicegui.json.orjson_wrapper import dumps, loads
 
-import orjson
-from fastapi import Response
-
-ORJSON_OPTS = orjson.OPT_SERIALIZE_NUMPY | orjson.OPT_NON_STR_KEYS
-
-
-def dumps(obj, sort_keys=False, separators=None):
-    """
-    Serializes a Python object to a JSON-encoded string.
-    By default, this function supports serializing numpy arrays.
-    """
-    return orjson.dumps(obj, option=ORJSON_OPTS).decode('utf-8')
-
-
-def loads(value):
-    """
-    Deserializes a JSON-encoded string to a corresponding Python object/value.
-    """
-    return orjson.loads(value)
-
-
-class NiceGUIJSONResponse(Response):
-    media_type = "application/json"
-
-    def render(self, content: Any) -> bytes:
-        return orjson.dumps(content, option=ORJSON_OPTS)
+__all__ = [
+    'dumps',
+    'loads'
+]

+ 13 - 0
nicegui/json/fastapi.py

@@ -0,0 +1,13 @@
+from typing import Any
+
+import orjson
+from fastapi import Response
+
+from nicegui.json.orjson_wrapper import ORJSON_OPTS
+
+
+class NiceGUIJSONResponse(Response):
+    media_type = 'application/json'
+
+    def render(self, content: Any) -> bytes:
+        return orjson.dumps(content, option=ORJSON_OPTS)

+ 36 - 0
nicegui/json/orjson_wrapper.py

@@ -0,0 +1,36 @@
+from typing import Any, Optional, Tuple
+
+import orjson
+
+ORJSON_OPTS = orjson.OPT_SERIALIZE_NUMPY | orjson.OPT_NON_STR_KEYS
+
+
+def dumps(obj: Any, sort_keys: bool = False, separators: Optional[Tuple[str, str]] = None):
+    """Serializes a Python object to a JSON-encoded string.
+
+    By default, this function supports serializing numpy arrays,
+    which Python's json module does not.
+
+    Uses package `orjson` internally.
+    """
+    # note that parameters `sort_keys` and `separators` are required by AsyncServer's
+    # internal calls, which match Python's default `json.dumps` API.
+    assert separators is None or separators == (',', ':'), \
+        f'NiceGUI JSON serializer only supports Python''s default ' +\
+        f'JSON separators "," and ":", but got {separators} instead.'
+
+    opts = ORJSON_OPTS
+
+    # flag for sorting by object keys
+    if sort_keys:
+        opts |= orjson.OPT_SORT_KEYS
+
+    return orjson.dumps(obj, option=opts).decode('utf-8')
+
+
+def loads(value: str) -> Any:
+    """Deserialize a JSON-encoded string to a corresponding Python object/value.
+
+    Uses package `orjson` internally.
+    """
+    return orjson.loads(value)

+ 2 - 1
nicegui/nicegui.py

@@ -10,6 +10,7 @@ from fastapi.responses import FileResponse, Response
 from fastapi.staticfiles import StaticFiles
 
 from nicegui import json
+from nicegui.json.fastapi import NiceGUIJSONResponse
 from nicegui.socket_manager import SocketManager
 
 from . import background_tasks, binding, globals, outbox
@@ -21,7 +22,7 @@ from .error import error_content
 from .helpers import safe_invoke
 from .page import page
 
-globals.app = app = App(default_response_class=json.NiceGUIJSONResponse)
+globals.app = app = App(default_response_class=NiceGUIJSONResponse)
 socket_manager = SocketManager(app=app, json=json)  # custom json module (wraps orjson)
 globals.sio = sio = app.sio