Преглед на файлове

add type hinting for plotly (#4279)

* add type hinting for plotly

* fix merge
Khaleel Al-Adhami преди 6 месеца
родител
ревизия
3bd35f53f2
променени са 2 файла, в които са добавени 124 реда и са изтрити 103 реда
  1. 78 77
      reflex/components/plotly/plotly.py
  2. 46 26
      reflex/components/plotly/plotly.pyi

+ 78 - 77
reflex/components/plotly/plotly.py

@@ -2,12 +2,13 @@
 
 from __future__ import annotations
 
-from typing import Any, Dict, List
+from typing import Any, Dict, List, Tuple, Union
+
+from typing_extensions import TypedDict, TypeVar
 
-from reflex.base import Base
 from reflex.components.component import Component, NoSSRComponent
 from reflex.components.core.cond import color_mode_cond
-from reflex.event import EventHandler
+from reflex.event import EventHandler, no_args_event_spec
 from reflex.utils import console
 from reflex.vars.base import LiteralVar, Var
 
@@ -21,19 +22,7 @@ except ImportError:
     Template = Any  # type: ignore
 
 
-def _event_data_signature(e0: Var) -> List[Any]:
-    """For plotly events with event data and no points.
-
-    Args:
-        e0: The event data.
-
-    Returns:
-        The event key extracted from the event data (if defined).
-    """
-    return [Var(_js_expr=f"{e0}?.event")]
-
-
-def _event_points_data_signature(e0: Var) -> List[Any]:
+def _event_points_data_signature(e0: Var) -> Tuple[Var[List[Point]]]:
     """For plotly events with event data containing a point array.
 
     Args:
@@ -42,51 +31,63 @@ def _event_points_data_signature(e0: Var) -> List[Any]:
     Returns:
         The event data and the extracted points.
     """
-    return [
-        Var(_js_expr=f"{e0}?.event"),
-        Var(_js_expr=f"extractPoints({e0}?.points)"),
+    return (Var(_js_expr=f"extractPoints({e0}?.points)"),)
+
+
+T = TypeVar("T")
+
+ItemOrList = Union[T, List[T]]
+
+
+class BBox(TypedDict):
+    """Bounding box for a point in a plotly graph."""
+
+    x0: Union[float, int, None]
+    x1: Union[float, int, None]
+    y0: Union[float, int, None]
+    y1: Union[float, int, None]
+    z0: Union[float, int, None]
+    z1: Union[float, int, None]
+
+
+class Point(TypedDict):
+    """A point in a plotly graph."""
+
+    x: Union[float, int, None]
+    y: Union[float, int, None]
+    z: Union[float, int, None]
+    lat: Union[float, int, None]
+    lon: Union[float, int, None]
+    curveNumber: Union[int, None]
+    pointNumber: Union[int, None]
+    pointNumbers: Union[List[int], None]
+    pointIndex: Union[int, None]
+    markerColor: Union[
+        ItemOrList[
+            ItemOrList[
+                Union[
+                    float,
+                    int,
+                    str,
+                    None,
+                ]
+            ]
+        ],
+        None,
     ]
-
-
-class _ButtonClickData(Base):
-    """Event data structure for plotly UI buttons."""
-
-    menu: Any
-    button: Any
-    active: Any
-
-
-def _button_click_signature(e0: _ButtonClickData) -> List[Any]:
-    """For plotly button click events.
-
-    Args:
-        e0: The button click data.
-
-    Returns:
-        The menu, button, and active state.
-    """
-    return [e0.menu, e0.button, e0.active]
-
-
-def _passthrough_signature(e0: Var) -> List[Any]:
-    """For plotly events with arbitrary serializable data, passed through directly.
-
-    Args:
-        e0: The event data.
-
-    Returns:
-        The event data.
-    """
-    return [e0]
-
-
-def _null_signature() -> List[Any]:
-    """For plotly events with no data or non-serializable data. Nothing passed through.
-
-    Returns:
-        An empty list (nothing passed through).
-    """
-    return []
+    markerSize: Union[
+        ItemOrList[
+            ItemOrList[
+                Union[
+                    float,
+                    int,
+                    None,
+                ]
+            ]
+        ],
+        None,
+    ]
+    bbox: Union[BBox, None]
 
 
 class Plotly(NoSSRComponent):
@@ -116,49 +117,49 @@ class Plotly(NoSSRComponent):
     use_resize_handler: Var[bool] = LiteralVar.create(True)
 
     # Fired after the plot is redrawn.
-    on_after_plot: EventHandler[_passthrough_signature]
+    on_after_plot: EventHandler[no_args_event_spec]
 
     # Fired after the plot was animated.
-    on_animated: EventHandler[_null_signature]
+    on_animated: EventHandler[no_args_event_spec]
 
     # Fired while animating a single frame (does not currently pass data through).
-    on_animating_frame: EventHandler[_null_signature]
+    on_animating_frame: EventHandler[no_args_event_spec]
 
     # Fired when an animation is interrupted (to start a new animation for example).
-    on_animation_interrupted: EventHandler[_null_signature]
+    on_animation_interrupted: EventHandler[no_args_event_spec]
 
     # Fired when the plot is responsively sized.
-    on_autosize: EventHandler[_event_data_signature]
+    on_autosize: EventHandler[no_args_event_spec]
 
     # Fired whenever mouse moves over a plot.
-    on_before_hover: EventHandler[_event_data_signature]
+    on_before_hover: EventHandler[no_args_event_spec]
 
     # Fired when a plotly UI button is clicked.
-    on_button_clicked: EventHandler[_button_click_signature]
+    on_button_clicked: EventHandler[no_args_event_spec]
 
     # Fired when the plot is clicked.
     on_click: EventHandler[_event_points_data_signature]
 
     # Fired when a selection is cleared (via double click).
-    on_deselect: EventHandler[_null_signature]
+    on_deselect: EventHandler[no_args_event_spec]
 
     # Fired when the plot is double clicked.
-    on_double_click: EventHandler[_passthrough_signature]
+    on_double_click: EventHandler[no_args_event_spec]
 
     # Fired when a plot element is hovered over.
     on_hover: EventHandler[_event_points_data_signature]
 
     # Fired after the plot is layed out (zoom, pan, etc).
-    on_relayout: EventHandler[_passthrough_signature]
+    on_relayout: EventHandler[no_args_event_spec]
 
     # Fired while the plot is being layed out.
-    on_relayouting: EventHandler[_passthrough_signature]
+    on_relayouting: EventHandler[no_args_event_spec]
 
     # Fired after the plot style is changed.
-    on_restyle: EventHandler[_passthrough_signature]
+    on_restyle: EventHandler[no_args_event_spec]
 
     # Fired after the plot is redrawn.
-    on_redraw: EventHandler[_event_data_signature]
+    on_redraw: EventHandler[no_args_event_spec]
 
     # Fired after selecting plot elements.
     on_selected: EventHandler[_event_points_data_signature]
@@ -167,10 +168,10 @@ class Plotly(NoSSRComponent):
     on_selecting: EventHandler[_event_points_data_signature]
 
     # Fired while an animation is occuring.
-    on_transitioning: EventHandler[_event_data_signature]
+    on_transitioning: EventHandler[no_args_event_spec]
 
     # Fired when a transition is stopped early.
-    on_transition_interrupted: EventHandler[_event_data_signature]
+    on_transition_interrupted: EventHandler[no_args_event_spec]
 
     # Fired when a hovered element is no longer hovered.
     on_unhover: EventHandler[_event_points_data_signature]
@@ -216,8 +217,8 @@ const extractPoints = (points) => {
             pointNumber: point.pointNumber,
             pointNumbers: point.pointNumbers,
             pointIndex: point.pointIndex,
-            'marker.color': point['marker.color'],
-            'marker.size': point['marker.size'],
+            markerColor: point['marker.color'],
+            markerSize: point['marker.size'],
             bbox: bbox,
         })
     })

+ 46 - 26
reflex/components/plotly/plotly.pyi

@@ -3,9 +3,10 @@
 # ------------------- DO NOT EDIT ----------------------
 # This file was generated by `reflex/utils/pyi_generator.py`!
 # ------------------------------------------------------
-from typing import Any, Dict, Optional, Union, overload
+from typing import Any, Dict, List, Optional, Union, overload
+
+from typing_extensions import TypedDict, TypeVar
 
-from reflex.base import Base
 from reflex.components.component import NoSSRComponent
 from reflex.event import BASE_STATE, EventType
 from reflex.style import Style
@@ -20,11 +21,30 @@ except ImportError:
     console.warn("Plotly is not installed. Please run `pip install plotly`.")
     Figure = Any
     Template = Any
+T = TypeVar("T")
+ItemOrList = Union[T, List[T]]
+
+class BBox(TypedDict):
+    x0: Union[float, int, None]
+    x1: Union[float, int, None]
+    y0: Union[float, int, None]
+    y1: Union[float, int, None]
+    z0: Union[float, int, None]
+    z1: Union[float, int, None]
 
-class _ButtonClickData(Base):
-    menu: Any
-    button: Any
-    active: Any
+class Point(TypedDict):
+    x: Union[float, int, None]
+    y: Union[float, int, None]
+    z: Union[float, int, None]
+    lat: Union[float, int, None]
+    lon: Union[float, int, None]
+    curveNumber: Union[int, None]
+    pointNumber: Union[int, None]
+    pointNumbers: Union[List[int], None]
+    pointIndex: Union[int, None]
+    markerColor: Union[ItemOrList[ItemOrList[Union[float, int, str, None]]], None]
+    markerSize: Union[ItemOrList[ItemOrList[Union[float, int, None]]], None]
+    bbox: Union[BBox, None]
 
 class Plotly(NoSSRComponent):
     def add_imports(self) -> dict[str, str]: ...
@@ -45,20 +65,20 @@ class Plotly(NoSSRComponent):
         class_name: Optional[Any] = None,
         autofocus: Optional[bool] = None,
         custom_attrs: Optional[Dict[str, Union[Var, str]]] = None,
-        on_after_plot: Optional[EventType[..., BASE_STATE]] = None,
-        on_animated: Optional[EventType[..., BASE_STATE]] = None,
-        on_animating_frame: Optional[EventType[..., BASE_STATE]] = None,
-        on_animation_interrupted: Optional[EventType[..., BASE_STATE]] = None,
-        on_autosize: Optional[EventType[..., BASE_STATE]] = None,
-        on_before_hover: Optional[EventType[..., BASE_STATE]] = None,
+        on_after_plot: Optional[EventType[[], BASE_STATE]] = None,
+        on_animated: Optional[EventType[[], BASE_STATE]] = None,
+        on_animating_frame: Optional[EventType[[], BASE_STATE]] = None,
+        on_animation_interrupted: Optional[EventType[[], BASE_STATE]] = None,
+        on_autosize: Optional[EventType[[], BASE_STATE]] = None,
+        on_before_hover: Optional[EventType[[], BASE_STATE]] = None,
         on_blur: Optional[EventType[[], BASE_STATE]] = None,
-        on_button_clicked: Optional[EventType[..., BASE_STATE]] = None,
-        on_click: Optional[EventType[..., BASE_STATE]] = None,
+        on_button_clicked: Optional[EventType[[], BASE_STATE]] = None,
+        on_click: Optional[EventType[[List[Point]], BASE_STATE]] = None,
         on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
-        on_deselect: Optional[EventType[..., BASE_STATE]] = None,
-        on_double_click: Optional[EventType[..., BASE_STATE]] = None,
+        on_deselect: Optional[EventType[[], BASE_STATE]] = None,
+        on_double_click: Optional[EventType[[], BASE_STATE]] = None,
         on_focus: Optional[EventType[[], BASE_STATE]] = None,
-        on_hover: Optional[EventType[..., BASE_STATE]] = None,
+        on_hover: Optional[EventType[[List[Point]], BASE_STATE]] = None,
         on_mount: Optional[EventType[[], BASE_STATE]] = None,
         on_mouse_down: Optional[EventType[[], BASE_STATE]] = None,
         on_mouse_enter: Optional[EventType[[], BASE_STATE]] = None,
@@ -67,16 +87,16 @@ class Plotly(NoSSRComponent):
         on_mouse_out: Optional[EventType[[], BASE_STATE]] = None,
         on_mouse_over: Optional[EventType[[], BASE_STATE]] = None,
         on_mouse_up: Optional[EventType[[], BASE_STATE]] = None,
-        on_redraw: Optional[EventType[..., BASE_STATE]] = None,
-        on_relayout: Optional[EventType[..., BASE_STATE]] = None,
-        on_relayouting: Optional[EventType[..., BASE_STATE]] = None,
-        on_restyle: Optional[EventType[..., BASE_STATE]] = None,
+        on_redraw: Optional[EventType[[], BASE_STATE]] = None,
+        on_relayout: Optional[EventType[[], BASE_STATE]] = None,
+        on_relayouting: Optional[EventType[[], BASE_STATE]] = None,
+        on_restyle: Optional[EventType[[], BASE_STATE]] = None,
         on_scroll: Optional[EventType[[], BASE_STATE]] = None,
-        on_selected: Optional[EventType[..., BASE_STATE]] = None,
-        on_selecting: Optional[EventType[..., BASE_STATE]] = None,
-        on_transition_interrupted: Optional[EventType[..., BASE_STATE]] = None,
-        on_transitioning: Optional[EventType[..., BASE_STATE]] = None,
-        on_unhover: Optional[EventType[..., BASE_STATE]] = None,
+        on_selected: Optional[EventType[[List[Point]], BASE_STATE]] = None,
+        on_selecting: Optional[EventType[[List[Point]], BASE_STATE]] = None,
+        on_transition_interrupted: Optional[EventType[[], BASE_STATE]] = None,
+        on_transitioning: Optional[EventType[[], BASE_STATE]] = None,
+        on_unhover: Optional[EventType[[List[Point]], BASE_STATE]] = None,
         on_unmount: Optional[EventType[[], BASE_STATE]] = None,
         **props,
     ) -> "Plotly":