dara-components 1.8.5__py3-none-any.whl → 1.22.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (92) hide show
  1. dara/components/__init__.py +18 -0
  2. dara/components/_assets/__init__.py +30 -0
  3. dara/components/_assets/auto_js/.gitkeep +0 -0
  4. dara/components/_assets/auto_js/dara.components.css +1494 -0
  5. dara/components/_assets/auto_js/dara.components.umd.js +182837 -0
  6. dara/components/_assets/common/bokeh-3.1.1.min.js +690 -0
  7. dara/components/_assets/common/bokeh-api-3.1.1.min.js +60 -0
  8. dara/components/_assets/common/bokeh-gl-3.1.1.min.js +67 -0
  9. dara/components/_assets/common/bokeh-mathjax-3.1.1.min.js +329 -0
  10. dara/components/_assets/common/bokeh-tables-3.1.1.min.js +132 -0
  11. dara/components/_assets/common/bokeh-widgets-3.1.1.min.js +129 -0
  12. dara/components/_assets/common/pixi-filters.min.js +17 -0
  13. dara/components/_assets/common/pixi.min.js +2214 -0
  14. dara/components/_assets/common/pixi_viewport.js +1 -0
  15. dara/components/_assets/common/plotly.min.js +8 -0
  16. dara/components/common/__init__.py +11 -2
  17. dara/components/common/accordion.py +20 -26
  18. dara/components/common/anchor.py +9 -10
  19. dara/components/common/base_component.py +23 -36
  20. dara/components/common/bullet_list.py +1 -3
  21. dara/components/common/button.py +35 -26
  22. dara/components/common/button_bar.py +25 -20
  23. dara/components/common/card.py +4 -5
  24. dara/components/common/carousel.py +9 -9
  25. dara/components/common/checkbox_group.py +26 -19
  26. dara/components/common/code.py +8 -5
  27. dara/components/common/component_select_list.py +9 -13
  28. dara/components/common/datepicker.py +16 -16
  29. dara/components/common/dropdown_menu.py +161 -0
  30. dara/components/common/dropzone.py +42 -33
  31. dara/components/common/form.py +5 -7
  32. dara/components/common/form_page.py +4 -6
  33. dara/components/common/grid.py +21 -18
  34. dara/components/common/heading.py +5 -4
  35. dara/components/common/icon.py +1 -3
  36. dara/components/common/if_cmp.py +23 -17
  37. dara/components/common/image.py +2 -2
  38. dara/components/common/input.py +9 -11
  39. dara/components/common/label.py +13 -14
  40. dara/components/common/markdown.py +3 -5
  41. dara/components/common/modal.py +2 -2
  42. dara/components/common/overlay.py +8 -14
  43. dara/components/common/paragraph.py +2 -2
  44. dara/components/common/progress_bar.py +6 -8
  45. dara/components/common/radio_group.py +38 -21
  46. dara/components/common/select.py +33 -30
  47. dara/components/common/slider.py +74 -29
  48. dara/components/common/spacer.py +4 -6
  49. dara/components/common/stack.py +7 -4
  50. dara/components/common/switch.py +6 -8
  51. dara/components/common/tabbed_card.py +8 -11
  52. dara/components/common/table.py +224 -73
  53. dara/components/common/text.py +7 -9
  54. dara/components/common/textarea.py +7 -7
  55. dara/components/common/time_utils.py +2 -5
  56. dara/components/common/tooltip.py +4 -6
  57. dara/components/common/utils.py +29 -35
  58. dara/components/graphs/__init__.py +1 -0
  59. dara/components/graphs/components/base_graph_component.py +34 -22
  60. dara/components/graphs/components/causal_graph_viewer.py +13 -15
  61. dara/components/graphs/components/edge_encoder.py +49 -26
  62. dara/components/graphs/components/node_hierarchy_builder.py +17 -16
  63. dara/components/graphs/definitions.py +27 -20
  64. dara/components/graphs/graph_layout.py +90 -53
  65. dara/components/plotting/__init__.py +2 -1
  66. dara/components/plotting/bokeh/bokeh.py +7 -10
  67. dara/components/plotting/bokeh/utils.py +5 -3
  68. dara/components/plotting/plotly/plotly.py +24 -19
  69. dara/components/plotting/plotly/themes.py +7 -5
  70. dara/components/smart/__init__.py +7 -1
  71. dara/components/smart/chat/chat.py +7 -8
  72. dara/components/smart/chat/config.py +1 -1
  73. dara/components/smart/chat/types.py +4 -6
  74. dara/components/smart/code_editor/code_editor.py +18 -4
  75. dara/components/smart/code_editor/util.py +11 -11
  76. dara/components/smart/data_slicer/__init__.py +4 -0
  77. dara/components/smart/data_slicer/data_slicer.py +14 -18
  78. dara/components/smart/data_slicer/data_slicer_modal.py +4 -6
  79. dara/components/smart/data_slicer/extension/data_slicer_filter.py +3 -4
  80. dara/components/smart/data_slicer/extension/filter_status_button.py +1 -3
  81. dara/components/smart/data_slicer/utils/core.py +23 -23
  82. dara/components/smart/data_slicer/utils/data_preview.py +1 -3
  83. dara/components/smart/data_slicer/utils/plotting.py +8 -6
  84. dara/components/smart/hierarchy.py +9 -10
  85. {dara_components-1.8.5.dist-info → dara_components-1.22.1.dist-info}/METADATA +7 -7
  86. dara_components-1.22.1.dist-info/RECORD +100 -0
  87. {dara_components-1.8.5.dist-info → dara_components-1.22.1.dist-info}/WHEEL +1 -1
  88. dara_components-1.22.1.dist-info/entry_points.txt +3 -0
  89. dara/components/umd/dara.components.umd.js +0 -396288
  90. dara/components/umd/style.css +0 -745
  91. dara_components-1.8.5.dist-info/RECORD +0 -86
  92. {dara_components-1.8.5.dist-info → dara_components-1.22.1.dist-info}/LICENSE +0 -0
@@ -16,7 +16,7 @@ limitations under the License.
16
16
  """
17
17
 
18
18
  import ast
19
- from typing import Any, List, Optional
19
+ from typing import Any
20
20
 
21
21
  DEFAULT_WHITELIST = [
22
22
  # Inbuilts
@@ -41,7 +41,7 @@ class ScriptVisitor(ast.NodeVisitor):
41
41
 
42
42
  _function_blacklist = ['read_pickle', 'read_csv', 'read_fwf']
43
43
 
44
- def __init__(self, undeclared_whitelist: List[str]):
44
+ def __init__(self, undeclared_whitelist: list[str]):
45
45
  self.undeclared_whitelist = undeclared_whitelist
46
46
  self.declared_vars: list = []
47
47
  super().__init__()
@@ -63,9 +63,9 @@ class ScriptVisitor(ast.NodeVisitor):
63
63
  self.declared_vars.append(target.id)
64
64
  self.generic_visit(node)
65
65
 
66
- def visit_Attribute(self, attr):
67
- self._check_dunder(attr, attr.attr)
68
- self.generic_visit(attr)
66
+ def visit_Attribute(self, node):
67
+ self._check_dunder(node, node.attr)
68
+ self.generic_visit(node)
69
69
 
70
70
  def visit_FunctionDef(self, node):
71
71
  self._check_dunder(node, node.name)
@@ -89,7 +89,7 @@ class ScriptVisitor(ast.NodeVisitor):
89
89
  self.generic_visit(node)
90
90
 
91
91
  def visit_Call(self, node):
92
- func_name: Optional[str] = None
92
+ func_name: str | None = None
93
93
  if isinstance(node.func, ast.Name):
94
94
  func_name = node.func.id
95
95
  elif isinstance(node.func, ast.Attribute):
@@ -106,7 +106,7 @@ class ScriptVisitor(ast.NodeVisitor):
106
106
  raise SyntaxError(f'Imports are not allowed: {node.names}')
107
107
 
108
108
 
109
- def run_script(script: str, injections: dict = {}, whitelist: List[str] = DEFAULT_WHITELIST) -> Any:
109
+ def run_script(script: str, injections: dict | None = None, whitelist: list[str] = DEFAULT_WHITELIST) -> Any:
110
110
  """
111
111
  Run a given script in a "sandbox".
112
112
  Disallows imports, most globals except whitelisted ones.
@@ -131,13 +131,13 @@ def run_script(script: str, injections: dict = {}, whitelist: List[str] = DEFAUL
131
131
 
132
132
  """
133
133
  # Validate that the script is safe
134
+ if injections is None:
135
+ injections = {}
134
136
  module: ast.Module = ast.parse(script)
135
137
  visitor = ScriptVisitor([*whitelist, *injections.keys()])
136
138
  visitor.visit(module)
137
139
 
138
140
  # Run the script
139
141
  loc: dict = {}
140
- exec(
141
- script, injections, loc
142
- ) # nosec B102 # this is unsafe but we make best effort with the above to make it as safe as possible
143
- return loc.get('return_val', None)
142
+ exec(script, injections, loc) # nosec B102 # this is unsafe but we make best effort with the above to make it as safe as possible
143
+ return loc.get('return_val')
@@ -17,8 +17,12 @@ limitations under the License.
17
17
 
18
18
  from dara.components.smart.data_slicer.data_slicer import DataSlicer
19
19
  from dara.components.smart.data_slicer.data_slicer_modal import DataSlicerModal
20
+ from dara.components.smart.data_slicer.extension.filter_status_button import (
21
+ FilterStatusButton,
22
+ )
20
23
 
21
24
  __all__ = [
22
25
  'DataSlicer',
23
26
  'DataSlicerModal',
27
+ 'FilterStatusButton',
24
28
  ]
@@ -15,8 +15,6 @@ See the License for the specific language governing permissions and
15
15
  limitations under the License.
16
16
  """
17
17
 
18
- from typing import List, Union
19
-
20
18
  from pandas import DataFrame
21
19
 
22
20
  from dara.components import (
@@ -51,29 +49,29 @@ from dara.components.smart.data_slicer.utils.plotting import render_input_plot
51
49
  from dara.core import DerivedVariable, Variable, py_component
52
50
  from dara.core.actions import UpdateVariable
53
51
  from dara.core.definitions import ComponentInstance, discover
54
- from dara.core.interactivity import AnyDataVariable, DataVariable, DerivedDataVariable
52
+ from dara.core.interactivity import AnyVariable, ServerVariable
55
53
 
56
54
  NO_RESULTS_FOUND = Stack(Text('No results found'))
57
55
  TABLE_ROWS = 5
58
56
 
59
57
 
60
- def increment(ctx: UpdateVariable.Ctx):
58
+ def increment(ctx: UpdateVariable.Ctx): # type: ignore
61
59
  return ctx.inputs.old + 1
62
60
 
63
61
 
64
62
  @discover
65
63
  class DataSlicer:
66
- def __init__(self, data: Union[DataFrame, AnyDataVariable], rows_to_show: int = 10):
64
+ def __init__(self, data: DataFrame | AnyVariable, rows_to_show: int = 10):
67
65
  """
68
66
  DataSlicer component allows the user to select a subset of a dataset by variable ranges or individual rows.
69
- Once instantiated, the `DerivedDataVariable` returned by `get_output()` will contain the filtered data.
67
+ Once instantiated, the `DerivedVariable` returned by `get_output()` will contain the filtered data.
70
68
 
71
69
  Displayed inline.
72
70
 
73
71
  :param data: input data
74
72
  :param rows_to_show: number of rows to show in the 'Head' and 'Tail' sections of filter preview
75
73
  """
76
- self.data_var = data if isinstance(data, AnyDataVariable) else DataVariable(data)
74
+ self.data_var = data if isinstance(data, AnyVariable) else ServerVariable(data)
77
75
  self.selected_column = Variable(None)
78
76
  self.rows_to_show = Variable(rows_to_show)
79
77
 
@@ -82,14 +80,12 @@ class DataSlicer:
82
80
  self.table_columns = DerivedVariable(get_columns, variables=[self.column_definitions])
83
81
 
84
82
  self.current_variable_filters = Variable([])
85
- self.preview_output = DerivedDataVariable(
86
- apply_filters, variables=[self.current_variable_filters, self.data_var]
87
- )
83
+ self.preview_output = DerivedVariable(apply_filters, variables=[self.current_variable_filters, self.data_var])
88
84
 
89
85
  # Table preview outputs
90
- self.describe_data = DerivedDataVariable(get_describe_data, variables=[self.preview_output])
91
- self.head_data = DerivedDataVariable(get_head_data, variables=[self.preview_output, self.rows_to_show])
92
- self.tail_data = DerivedDataVariable(get_tail_data, variables=[self.preview_output, self.rows_to_show])
86
+ self.describe_data = DerivedVariable(get_describe_data, variables=[self.preview_output])
87
+ self.head_data = DerivedVariable(get_head_data, variables=[self.preview_output, self.rows_to_show])
88
+ self.tail_data = DerivedVariable(get_tail_data, variables=[self.preview_output, self.rows_to_show])
93
89
 
94
90
  # This is a workaround for issues in DO-230
95
91
  self.manual_output_trigger = Variable(0)
@@ -99,20 +95,20 @@ class DataSlicer:
99
95
  variables=[self.current_variable_filters, self.manual_output_trigger],
100
96
  deps=[self.manual_output_trigger],
101
97
  )
102
- self.final_output = DerivedDataVariable(
98
+ self.final_output = DerivedVariable(
103
99
  lambda x, _y: x,
104
100
  variables=[self.preview_output, self.manual_output_trigger],
105
101
  deps=[self.manual_output_trigger],
106
102
  )
107
103
 
108
- def get_output(self) -> DerivedDataVariable:
104
+ def get_output(self) -> DerivedVariable:
109
105
  """
110
106
  Get the DerivedVariable containing filtered data
111
107
  """
112
108
  return self.final_output
113
109
 
114
110
  @py_component
115
- def describe_table(self, columns: List[Column]):
111
+ def describe_table(self, columns: list[Column]):
116
112
  """
117
113
  Display data.describe() as a Table
118
114
  """
@@ -122,14 +118,14 @@ class DataSlicer:
122
118
  return Table(data=self.describe_data, columns=cols, max_rows=TABLE_ROWS)
123
119
 
124
120
  @py_component
125
- def table_head(self, columns: List[Column]):
121
+ def table_head(self, columns: list[Column]):
126
122
  """
127
123
  Display data.head() as a Table
128
124
  """
129
125
  return Table(data=self.head_data, columns=columns, max_rows=TABLE_ROWS)
130
126
 
131
127
  @py_component
132
- def table_tail(self, columns: List[Column]):
128
+ def table_tail(self, columns: list[Column]):
133
129
  """
134
130
  Display data.tail() as a Table
135
131
  """
@@ -15,8 +15,6 @@ See the License for the specific language governing permissions and
15
15
  limitations under the License.
16
16
  """
17
17
 
18
- from typing import Union
19
-
20
18
  from pandas import DataFrame
21
19
 
22
20
  from dara.components.common import Button, Heading, Modal, Stack
@@ -30,11 +28,11 @@ from dara.core.definitions import ComponentInstance, discover
30
28
  from dara.core.interactivity import AnyDataVariable, DerivedVariable, Variable
31
29
 
32
30
 
33
- def toggle_variable(ctx: UpdateVariable.Ctx):
31
+ def toggle_variable(ctx: UpdateVariable.Ctx): # type: ignore
34
32
  return not ctx.inputs.old
35
33
 
36
34
 
37
- def increment(ctx: UpdateVariable.Ctx):
35
+ def increment(ctx: UpdateVariable.Ctx): # type: ignore
38
36
  return ctx.inputs.old + 1
39
37
 
40
38
 
@@ -42,14 +40,14 @@ def increment(ctx: UpdateVariable.Ctx):
42
40
  class DataSlicerModal(DataSlicer):
43
41
  def __init__(
44
42
  self,
45
- data: Union[DataFrame, AnyDataVariable],
43
+ data: DataFrame | AnyDataVariable,
46
44
  rows_to_show: int = 10,
47
45
  button_top_position: str = '5%',
48
46
  ):
49
47
  """
50
48
  DataSlicerModal component is a modal version of the DataSlicer component.
51
49
 
52
- Once instantiated, the `DerivedDataVariable` returned by `get_output()` will contain the filtered data.
50
+ Once instantiated, the `DerivedVariable` returned by `get_output()` will contain the filtered data.
53
51
 
54
52
  When included in a page, it adds a Filter button to the top-right corner of the screen which
55
53
  displays current filter status when hovered. The button opens up a modal with the DataSlicer when clicked.
@@ -16,11 +16,10 @@ limitations under the License.
16
16
  """
17
17
 
18
18
  from enum import Enum
19
- from typing import List, Optional
20
19
 
21
- from pydantic import BaseModel
22
20
  from typing_extensions import TypedDict
23
21
 
22
+ from dara.core.base_definitions import DaraBaseModel as BaseModel
24
23
  from dara.core.definitions import ComponentInstance
25
24
  from dara.core.interactivity import AnyVariable, Variable
26
25
 
@@ -61,6 +60,6 @@ class DataSlicerFilter(ComponentInstance):
61
60
 
62
61
  js_module = '@darajs/components'
63
62
 
64
- filters: Variable[List[FilterInstance]]
63
+ filters: Variable[list[FilterInstance]]
65
64
  columns: AnyVariable
66
- height: Optional[str] = None
65
+ height: str | None = None
@@ -15,8 +15,6 @@ See the License for the specific language governing permissions and
15
15
  limitations under the License.
16
16
  """
17
17
 
18
- from typing import Optional
19
-
20
18
  from typing_extensions import TypedDict
21
19
 
22
20
  from dara.core.base_definitions import Action
@@ -45,4 +43,4 @@ class FilterStatusButton(ComponentInstance):
45
43
 
46
44
  filter_stats: AnyVariable
47
45
  on_click: Action
48
- top_position: Optional[str] = '5%'
46
+ top_position: str | None = '5%'
@@ -17,7 +17,7 @@ limitations under the License.
17
17
 
18
18
  import re
19
19
  from datetime import datetime, timezone
20
- from typing import Any, List, Optional, Union
20
+ from typing import Any, Optional, cast
21
21
 
22
22
  import numpy
23
23
  from pandas import DataFrame, Series
@@ -60,17 +60,17 @@ def infer_column_type(data: DataFrame, col: str) -> ColumnType:
60
60
  return ColumnType.CATEGORICAL
61
61
 
62
62
 
63
- def get_column_definitions(data: DataFrame) -> List[ColumnDefinition]:
64
- symbols: List[str] = data.columns.values.tolist()
63
+ def get_column_definitions(data: DataFrame) -> list[ColumnDefinition]:
64
+ symbols: list[str] = data.columns.values.tolist()
65
65
 
66
66
  return [ColumnDefinition(name=s, type=infer_column_type(data, s)) for s in symbols if s != '__index__']
67
67
 
68
68
 
69
- def get_column_items(column_defs: List[ColumnDefinition]) -> list:
69
+ def get_column_items(column_defs: list[ColumnDefinition]) -> list:
70
70
  return [{'label': c['name'], 'value': c['name']} for c in column_defs]
71
71
 
72
72
 
73
- def isnumber(*values: Union[str, float]):
73
+ def isnumber(*values: str | float):
74
74
  """
75
75
  Check if all values are numeric strings (ints, floats etc)
76
76
  """
@@ -83,7 +83,7 @@ def isnumber(*values: Union[str, float]):
83
83
  return True
84
84
 
85
85
 
86
- def apply_range_filter(range_filter: str, column: Series) -> Optional['Series[bool]']:
86
+ def apply_range_filter(range_filter: str, column: Series) -> Optional['Series']:
87
87
  """
88
88
  Apply a 'range' filter on a column
89
89
 
@@ -93,7 +93,7 @@ def apply_range_filter(range_filter: str, column: Series) -> Optional['Series[bo
93
93
  final_range_filter = None
94
94
 
95
95
  # Look for groups of [<something>]
96
- ranges: List[str] = re.findall(r'\[[^\[\]]+\]', range_filter)
96
+ ranges: list[str] = re.findall(r'\[[^\[\]]+\]', range_filter)
97
97
 
98
98
  for rang in ranges:
99
99
  if ',' not in rang:
@@ -107,8 +107,8 @@ def apply_range_filter(range_filter: str, column: Series) -> Optional['Series[bo
107
107
  upper_raw = upper_raw.strip()
108
108
 
109
109
  # Replace ':' symbols with (-)infinity
110
- lower: Union[str, float] = float('-inf') if lower_raw == ':' else lower_raw
111
- upper: Union[str, float] = float('inf') if upper_raw == ':' else upper_raw
110
+ lower: str | float = float('-inf') if lower_raw == ':' else lower_raw
111
+ upper: str | float = float('inf') if upper_raw == ':' else upper_raw
112
112
 
113
113
  # Only consider the range valid if the limits are numbers and lower < upper
114
114
  if lower != '' and upper != '' and isnumber(lower, upper):
@@ -126,7 +126,7 @@ def apply_range_filter(range_filter: str, column: Series) -> Optional['Series[bo
126
126
  return final_range_filter
127
127
 
128
128
 
129
- def apply_values_filter(values_filter: str, column: Series, col_type: ColumnType) -> Optional['Series[bool]']:
129
+ def apply_values_filter(values_filter: str, column: Series, col_type: ColumnType) -> Optional['Series']:
130
130
  """
131
131
  Apply a 'values' filter on a column
132
132
 
@@ -135,7 +135,7 @@ def apply_values_filter(values_filter: str, column: Series, col_type: ColumnType
135
135
  """
136
136
  final_values_filter = None
137
137
 
138
- values: List[Any] = (
138
+ values: list[Any] = (
139
139
  [v.strip() for v in values_filter.split(',') if v != ''] if ',' in values_filter else [values_filter.strip()]
140
140
  )
141
141
 
@@ -177,7 +177,7 @@ def parseISO(date: str) -> numpy.datetime64:
177
177
  return numpy.datetime64(d)
178
178
 
179
179
 
180
- def apply_date_filter(from_date: str, to_date: str, column: 'Series[numpy.datetime64]') -> Optional['Series[bool]']:
180
+ def apply_date_filter(from_date: str, to_date: str, column: 'Series') -> Optional['Series']:
181
181
  """
182
182
  Apply a 'from_date' and 'to_date' filters to a column
183
183
 
@@ -189,18 +189,18 @@ def apply_date_filter(from_date: str, to_date: str, column: 'Series[numpy.dateti
189
189
 
190
190
  if from_date != '':
191
191
  from_timestamp = parseISO(from_date)
192
- from_date_filter = column.gt(from_timestamp) # type: ignore
192
+ from_date_filter = column.gt(from_timestamp) # type: ignore
193
193
  final_date_filter = from_date_filter
194
194
 
195
195
  if to_date != '':
196
196
  to_timestamp = parseISO(to_date)
197
- to_date_filter = column.lt(to_timestamp) # type: ignore
197
+ to_date_filter = column.lt(to_timestamp) # type: ignore
198
198
  final_date_filter = final_date_filter & to_date_filter if final_date_filter is not None else to_date_filter
199
199
 
200
200
  return final_date_filter
201
201
 
202
202
 
203
- def apply_filters(variable_filters: List[FilterInstance], data: DataFrame) -> DataFrame:
203
+ def apply_filters(variable_filters: list[FilterInstance], data: DataFrame) -> DataFrame:
204
204
  """
205
205
  Apply filters on data
206
206
 
@@ -212,9 +212,9 @@ def apply_filters(variable_filters: List[FilterInstance], data: DataFrame) -> Da
212
212
  for fil in variable_filters:
213
213
  var = fil['column']
214
214
 
215
- values_filter: Optional['Series[bool]'] = None
216
- range_filter: Optional['Series[bool]'] = None
217
- date_filter: Optional['Series[bool]'] = None
215
+ values_filter: Series | None = None
216
+ range_filter: Series | None = None
217
+ date_filter: Series | None = None
218
218
 
219
219
  if var is None or var.strip() == '':
220
220
  continue
@@ -223,14 +223,14 @@ def apply_filters(variable_filters: List[FilterInstance], data: DataFrame) -> Da
223
223
 
224
224
  # Range filter
225
225
  if fil['range'] != '' and 'range' in ALLOWED_FILTERS[column_type]:
226
- range_filter = apply_range_filter(fil['range'], data[var])
226
+ range_filter = apply_range_filter(fil['range'], cast(Series, data[var]))
227
227
 
228
228
  # Values filter
229
229
  if fil['values'] != '' and 'values' in ALLOWED_FILTERS[column_type]:
230
- values_filter = apply_values_filter(fil['values'], data[var], column_type)
230
+ values_filter = apply_values_filter(fil['values'], cast(Series, data[var]), column_type)
231
231
 
232
232
  if (fil['from_date'] != '' or fil['to_date'] != '') and ('from_date' in ALLOWED_FILTERS[column_type]):
233
- date_filter = apply_date_filter(fil['from_date'], fil['to_date'], data[var])
233
+ date_filter = apply_date_filter(fil['from_date'], fil['to_date'], cast(Series, data[var]))
234
234
 
235
235
  # OR all of the defined filters together
236
236
  final_filter = None
@@ -242,10 +242,10 @@ def apply_filters(variable_filters: List[FilterInstance], data: DataFrame) -> Da
242
242
  if final_filter is not None:
243
243
  output = output[final_filter]
244
244
 
245
- return output
245
+ return cast(DataFrame, output)
246
246
 
247
247
 
248
- def get_filter_stats(input_data: DataFrame, output_data: DataFrame, filters: List[FilterInstance]) -> FilterStats:
248
+ def get_filter_stats(input_data: DataFrame, output_data: DataFrame, filters: list[FilterInstance]) -> FilterStats:
249
249
  """
250
250
  Get filter statistics
251
251
 
@@ -15,8 +15,6 @@ See the License for the specific language governing permissions and
15
15
  limitations under the License.
16
16
  """
17
17
 
18
- from typing import List
19
-
20
18
  from pandas import DataFrame
21
19
 
22
20
  from dara.components.common.table import Column, TableFormatterType
@@ -39,7 +37,7 @@ def get_tail_data(df: DataFrame, rows_to_show: int) -> DataFrame:
39
37
  return df.tail(rows_to_show).fillna('NaN')
40
38
 
41
39
 
42
- def get_columns(col_defs: List[ColumnDefinition]) -> List[Column]:
40
+ def get_columns(col_defs: list[ColumnDefinition]) -> list[Column]:
43
41
  cols = []
44
42
 
45
43
  for col_def in col_defs:
@@ -15,9 +15,11 @@ See the License for the specific language governing permissions and
15
15
  limitations under the License.
16
16
  """
17
17
 
18
+ from typing import cast
19
+
18
20
  import numpy
19
21
  from bokeh.plotting import figure
20
- from pandas import DataFrame
22
+ from pandas import DataFrame, Series
21
23
  from scipy.stats import gaussian_kde
22
24
 
23
25
  from dara.components.common import Stack, Text
@@ -43,9 +45,9 @@ def _plot_x_numerical(dataset: DataFrame, x: str, **kwargs):
43
45
  sizing_mode='stretch_both',
44
46
  **kwargs,
45
47
  )
46
- p.toolbar.logo = None # type: ignore
48
+ p.toolbar.logo = None # type: ignore
47
49
 
48
- pdf = gaussian_kde(df[x].dropna())
50
+ pdf = gaussian_kde(cast(DataFrame, df[x]).dropna())
49
51
  y = pdf(lin)
50
52
  p.line(
51
53
  lin,
@@ -63,10 +65,10 @@ def _plot_x_categorical(dataset: DataFrame, x: str, **kwargs):
63
65
  df = dataset.copy()
64
66
  df = df[[x]].dropna().astype(str)
65
67
 
66
- values_counts = df[x].value_counts()
68
+ values_counts = cast(Series, df[x]).value_counts()
67
69
 
68
70
  p = figure(
69
- x_range=sorted(list(df[x].unique())),
71
+ x_range=sorted(list(cast(Series, df[x]).unique())),
70
72
  title=f'Histogram - {x}',
71
73
  toolbar_location=None,
72
74
  tools='',
@@ -76,7 +78,7 @@ def _plot_x_categorical(dataset: DataFrame, x: str, **kwargs):
76
78
 
77
79
  p.vbar(x=values_counts.index, top=values_counts.values, width=0.5, color=BLUE)
78
80
 
79
- p.toolbar.logo = None # type: ignore
81
+ p.toolbar.logo = None # type: ignore
80
82
 
81
83
  p.xgrid.grid_line_color = None
82
84
 
@@ -15,13 +15,12 @@ See the License for the specific language governing permissions and
15
15
  limitations under the License.
16
16
  """
17
17
 
18
- from typing import List, Optional, Union
19
-
20
- from pydantic import BaseModel
18
+ from typing import Optional
21
19
 
22
20
  from dara.core.base_definitions import Action
21
+ from dara.core.base_definitions import DaraBaseModel as BaseModel
23
22
  from dara.core.definitions import StyledComponentInstance
24
- from dara.core.interactivity import NonDataVariable
23
+ from dara.core.interactivity import ClientVariable
25
24
 
26
25
 
27
26
  class Node(BaseModel):
@@ -30,13 +29,13 @@ class Node(BaseModel):
30
29
  are represented by stacking further Node components as children of a Node.
31
30
  """
32
31
 
33
- children: Optional[List['Node']]
32
+ children: list['Node'] | None
34
33
  id: str
35
34
  label: str
36
35
  weight: float
37
36
 
38
37
  @staticmethod
39
- def from_string(name: str, weight: Optional[float] = None, children: Optional[List['Node']] = None):
38
+ def from_string(name: str, weight: float | None = None, children: list['Node'] | None = None):
40
39
  return Node(id=name, label=name, children=children, weight=weight if weight is not None else 0.0)
41
40
 
42
41
  def find_node(self, target: str) -> Optional['Node']:
@@ -59,7 +58,7 @@ class Node(BaseModel):
59
58
  return None
60
59
 
61
60
 
62
- Node.update_forward_refs()
61
+ Node.model_rebuild()
63
62
 
64
63
 
65
64
  class HierarchySelector(StyledComponentInstance):
@@ -74,7 +73,7 @@ class HierarchySelector(StyledComponentInstance):
74
73
  allow_leaf_select: bool = True
75
74
  hierarchy: Node
76
75
  open_all: bool = True
77
- value: NonDataVariable
76
+ value: ClientVariable
78
77
 
79
78
 
80
79
  class HierarchyViewer(StyledComponentInstance):
@@ -87,5 +86,5 @@ class HierarchyViewer(StyledComponentInstance):
87
86
 
88
87
  allow_leaf_click: bool = True
89
88
  allow_parent_click: bool = True
90
- hierarchy: Union[Node, NonDataVariable]
91
- on_click_node: Optional[Action] = None
89
+ hierarchy: Node | ClientVariable
90
+ on_click_node: Action | None = None
@@ -1,21 +1,21 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dara-components
3
- Version: 1.8.5
3
+ Version: 1.22.1
4
4
  Summary: Components for the Dara Framework
5
5
  Home-page: https://dara.causalens.com/
6
6
  License: Apache-2.0
7
7
  Author: Patricia Jacob
8
8
  Author-email: patricia@causalens.com
9
- Requires-Python: >=3.8.0,<3.12.0
9
+ Requires-Python: >=3.10.0,<3.13.0
10
10
  Classifier: License :: OSI Approved :: Apache Software License
11
11
  Classifier: Programming Language :: Python :: 3
12
- Classifier: Programming Language :: Python :: 3.8
13
- Classifier: Programming Language :: Python :: 3.9
14
12
  Classifier: Programming Language :: Python :: 3.10
15
13
  Classifier: Programming Language :: Python :: 3.11
16
- Requires-Dist: bokeh (>=3.1.0,<3.2.0)
14
+ Classifier: Programming Language :: Python :: 3.12
15
+ Requires-Dist: bokeh (==3.1.1)
17
16
  Requires-Dist: cai-causal-graph (>=0.3.6)
18
- Requires-Dist: dara-core (==1.8.5)
17
+ Requires-Dist: certifi (>=2024.7.4)
18
+ Requires-Dist: dara-core (==1.22.1)
19
19
  Requires-Dist: dill (>=0.3.0,<0.4.0)
20
20
  Requires-Dist: matplotlib (>=2.0.0)
21
21
  Requires-Dist: pandas (>=1.1.0,<3.0.0)
@@ -27,7 +27,7 @@ Description-Content-Type: text/markdown
27
27
 
28
28
  # Dara Components
29
29
 
30
- <img src="https://github.com/causalens/dara/blob/VERSION-1.8.5/img/dara_light.svg?raw=true">
30
+ <img src="https://github.com/causalens/dara/blob/v1.22.1/img/dara_light.svg?raw=true">
31
31
 
32
32
  ![Master tests](https://github.com/causalens/dara/actions/workflows/tests.yml/badge.svg?branch=master)
33
33
  [![License](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](https://www.apache.org/licenses/LICENSE-2.0)